mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:50:30 +00:00
Local spiller kills a store if the folded restore is turned into a copy.
But this is incorrect if the spilled value live range extends beyond the current BB. It is currently controlled by a temporary option -spiller-check-liveout. llvm-svn: 28024
This commit is contained in:
parent
1b3f7b8b48
commit
02e72f8f55
@ -271,14 +271,15 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
|
||||
// can do this, we don't need to insert spill code.
|
||||
if (lv_)
|
||||
lv_->instructionChanged(MI, fmi);
|
||||
vrm.virtFolded(li.reg, MI, i, fmi);
|
||||
MachineBasicBlock &MBB = *MI->getParent();
|
||||
bool LiveOut = li.liveAt(getInstructionIndex(&MBB.back()) +
|
||||
InstrSlots::NUM);
|
||||
vrm.virtFolded(li.reg, MI, i, fmi, LiveOut);
|
||||
mi2iMap_.erase(MI);
|
||||
i2miMap_[index/InstrSlots::NUM] = fmi;
|
||||
mi2iMap_[fmi] = index;
|
||||
MachineBasicBlock &MBB = *MI->getParent();
|
||||
MI = MBB.insert(MBB.erase(MI), fmi);
|
||||
++numFolded;
|
||||
|
||||
// Folding the load/store can completely change the instruction in
|
||||
// unpredictable ways, rescan it from the beginning.
|
||||
goto for_operand;
|
||||
|
@ -50,6 +50,10 @@ namespace {
|
||||
clEnumVal(local, " local spiller"),
|
||||
clEnumValEnd),
|
||||
cl::init(local));
|
||||
|
||||
// TEMPORARY option to test a fix.
|
||||
cl::opt<bool>
|
||||
SpillerCheckLiveOut("spiller-check-liveout", cl::Hidden);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -81,7 +85,8 @@ void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int frameIndex) {
|
||||
}
|
||||
|
||||
void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI,
|
||||
unsigned OpNo, MachineInstr *NewMI) {
|
||||
unsigned OpNo, MachineInstr *NewMI,
|
||||
bool LiveOut) {
|
||||
// Move previous memory references folded to new instruction.
|
||||
MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(NewMI);
|
||||
for (MI2VirtMapTy::iterator I = MI2VirtMap.lower_bound(OldMI),
|
||||
@ -96,6 +101,7 @@ void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI,
|
||||
MRInfo = isRef;
|
||||
} else {
|
||||
MRInfo = OldMI->getOperand(OpNo).isUse() ? isModRef : isMod;
|
||||
if (LiveOut) MRInfo = (ModRef)(MRInfo | isLiveOut);
|
||||
}
|
||||
|
||||
// add new memory reference
|
||||
@ -727,10 +733,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
|
||||
MaybeDeadStores.erase(MDSI);
|
||||
else {
|
||||
// If we get here, the store is dead, nuke it now.
|
||||
assert(MR == VirtRegMap::isMod && "Can't be modref!");
|
||||
MBB.erase(MDSI->second);
|
||||
MaybeDeadStores.erase(MDSI);
|
||||
++NumDSE;
|
||||
assert(!(MR & VirtRegMap::isRef) && "Can't be modref!");
|
||||
// Don't nuke it if the value is needed in another block.
|
||||
if (!SpillerCheckLiveOut || !(MR & VirtRegMap::isLiveOut)) {
|
||||
DEBUG(std::cerr << " Killed store:\t" << *MDSI->second);
|
||||
MBB.erase(MDSI->second);
|
||||
MaybeDeadStores.erase(MDSI);
|
||||
++NumDSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace llvm {
|
||||
|
||||
class VirtRegMap {
|
||||
public:
|
||||
enum ModRef { isRef = 1, isMod = 2, isModRef = 3 };
|
||||
enum ModRef { isRef = 1, isMod = 2, isModRef = 3, isLiveOut = 4 };
|
||||
typedef std::multimap<MachineInstr*,
|
||||
std::pair<unsigned, ModRef> > MI2VirtMapTy;
|
||||
|
||||
@ -128,7 +128,7 @@ namespace llvm {
|
||||
/// folded into newMI machine instruction. The OpNum argument indicates the
|
||||
/// operand number of OldMI that is folded.
|
||||
void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum,
|
||||
MachineInstr *NewMI);
|
||||
MachineInstr *NewMI, bool LiveOut);
|
||||
|
||||
/// @brief returns the virtual registers' values folded in memory
|
||||
/// operands of this instruction
|
||||
|
Loading…
Reference in New Issue
Block a user