Newer
Older
// Process all of the spilled defs.
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
if (MO.isRegister() && MO.getReg() && MO.isDef()) {
unsigned VirtReg = MO.getReg();
if (!MRegisterInfo::isVirtualRegister(VirtReg)) {
Chris Lattner
committed
// Check to see if this is a noop copy. If so, eliminate the
// instruction before considering the dest reg to be changed.
unsigned Src, Dst;
if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
++NumDCE;
DOUT << "Removing now-noop copy: " << MI;
Chris Lattner
committed
MBB.erase(&MI);
Evan Cheng
committed
Erased = true;
Chris Lattner
committed
VRM.RemoveFromFoldedVirtMap(&MI);
Chris Lattner
committed
goto ProcessNextInst;
}
// If it's not a no-op copy, it clobbers the value in the destreg.
Chris Lattner
committed
Spills.ClobberPhysReg(VirtReg);
ReusedOperands.markClobbered(VirtReg);
// Check to see if this instruction is a load from a stack slot into
// a register. If so, this provides the stack slot value in the reg.
int FrameIdx;
if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
assert(DestReg == VirtReg && "Unknown load situation!");
// Otherwise, if it wasn't available, remember that it is now!
Spills.addAvailable(FrameIdx, &MI, DestReg);
goto ProcessNextInst;
}
Chris Lattner
committed
continue;
// The only vregs left are stack slot definitions.
int StackSlot = VRM.getStackSlot(VirtReg);
const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(VirtReg);
Chris Lattner
committed
// If this def is part of a two-address operand, make sure to execute
// the store from the correct physical register.
unsigned PhysReg;
int TiedOp = MI.getInstrDescriptor()->findTiedToSrcOperand(i);
if (TiedOp != -1)
PhysReg = MI.getOperand(TiedOp).getReg();
else {
Chris Lattner
committed
PhysReg = VRM.getPhys(VirtReg);
if (ReusedOperands.isClobbered(PhysReg)) {
// Another def has taken the assigned physreg. It must have been a
// use&def which got it due to reuse. Undo the reuse!
PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI,
Evan Cheng
committed
Spills, MaybeDeadStores, RegKills, KillOps);
}
}
ReusedOperands.markClobbered(PhysReg);
MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
DOUT << "Store:\t" << *next(MII);
MI.getOperand(i).setReg(PhysReg);
// If there is a dead store to this stack slot, nuke it now.
MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
if (LastStore) {
DOUT << "Removed dead store:\t" << *LastStore;
Evan Cheng
committed
InvalidateKills(*LastStore, RegKills, KillOps);
VRM.RemoveFromFoldedVirtMap(LastStore);
LastStore = next(MII);
// If the stack slot value was previously available in some other
// register, change it now. Otherwise, make the register available,
// in PhysReg.
Chris Lattner
committed
Spills.ModifyStackSlot(StackSlot);
Spills.ClobberPhysReg(PhysReg);
Spills.addAvailable(StackSlot, LastStore, PhysReg);
// Check to see if this is a noop copy. If so, eliminate the
// instruction before considering the dest reg to be changed.
{
unsigned Src, Dst;
if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
++NumDCE;
DOUT << "Removing now-noop copy: " << MI;
MBB.erase(&MI);
Evan Cheng
committed
Erased = true;
VRM.RemoveFromFoldedVirtMap(&MI);
Evan Cheng
committed
UpdateKills(*LastStore, RegKills, KillOps);
goto ProcessNextInst;
}
}
}
}
Chris Lattner
committed
ProcessNextInst:
Evan Cheng
committed
if (!Erased && !BackTracked)
for (MachineBasicBlock::iterator II = MI; II != NextMII; ++II)
UpdateKills(*II, RegKills, KillOps);
MII = NextMII;
}
Chris Lattner
committed
llvm::Spiller* llvm::createSpiller() {
switch (SpillerOpt) {
default: assert(0 && "Unreachable!");
case local:
return new LocalSpiller();
case simple:
return new SimpleSpiller();
}