/// slot changes. This removes information about which register the previous
/// value for this slot lives in (as the previous value is dead now).
void ModifyStackSlotOrReMat(int SlotOrReMat);
+
+ void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB);
};
}
PhysRegsAvailable.erase(I);
}
+/// AddAvailableRegsToLiveIn - Availability information is being kept coming
+/// into the specified MBB. Add available physical registers as live-in's
+/// so register scavenger and post-allocation scheduler are happy.
+void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB) {
+ for (std::multimap<unsigned, int>::iterator
+ I = PhysRegsAvailable.begin(), E = PhysRegsAvailable.end();
+ I != E; ++I) {
+ unsigned Reg = (*I).first;
+ const TargetRegisterClass* RC = TRI->getPhysicalRegisterRegClass(Reg);
+ // FIXME: A temporary workaround. We can't reuse available value if it's
+ // not safe to move the def of the virtual register's class. e.g.
+ // X86::RFP* register classes. Do not add it as a live-in.
+ if (!TII->isSafeToMoveRegClassDefs(RC))
+ continue;
+ if (!MBB.isLiveIn(Reg))
+ MBB.addLiveIn(Reg);
+ }
+}
+
+/// findSinglePredSuccessor - Return via reference a vector of machine basic
+/// blocks each of which is a successor of the specified BB and has no other
+/// predecessor.
static void findSinglePredSuccessor(MachineBasicBlock *MBB,
SmallVectorImpl<MachineBasicBlock *> &Succs) {
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
}
namespace {
- class AvailableSpills;
-
/// LocalSpiller - This spiller does a simple pass over the machine basic
/// block to attempt to keep spills in registers as much as possible for
/// blocks that have low register pressure (the vreg may be spilled due to
// FIXME: More than one successors, each of which has MBB has
// the only predecessor.
MBB = SinglePredSuccs[0];
- if (!Visited.count(MBB) && EarlyVisited.insert(MBB))
+ if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
+ Spills.AddAvailableRegsToLiveIn(*MBB);
RewriteMBB(*MBB, VRM, Spills);
+ }
}
} while (MBB);
NewMIs.clear();
int Idx = NewMI->findRegisterUseOperandIdx(VirtReg, false);
assert(Idx != -1);
- SmallVector<unsigned, 2> Ops;
+ SmallVector<unsigned, 1> Ops;
Ops.push_back(Idx);
MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, NewMI, Ops, SS);
if (FoldedMI) {
MachineInstr *CommutedMI = TII->commuteInstruction(DefMI, true);
if (!CommutedMI)
return false;
- SmallVector<unsigned, 2> Ops;
+ SmallVector<unsigned, 1> Ops;
Ops.push_back(NewDstIdx);
MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, CommutedMI, Ops, SS);
// Not needed since foldMemoryOperand returns new MI.
bool DoReMat = VRM.isReMaterialized(VirtReg);
int SSorRMId = DoReMat
? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
- unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
- assert((!InReg || !RegKills[InReg]) &&
- "Restoring a value that's previously defined in the same BB?");
+ const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
+ // FIXME: A temporary workaround. Don't reuse available value if it's
+ // not safe to move the def of the virtual register's class. e.g.
+ // X86::RFP* register classes.
+ unsigned InReg = TII->isSafeToMoveRegClassDefs(RC) ?
+ Spills.getSpillSlotOrReMatPhysReg(SSorRMId) : 0;
if (InReg == Phys) {
// If the value is already available in the expected register, save
// a reload / remat.
// If the reloaded / remat value is available in another register,
// copy it to the desired register.
- const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
TII->copyRegToReg(MBB, &MI, Phys, InReg, RC, RC);
// This invalidates Phys.
PotentialDeadStoreSlots.push_back(ReuseSlot);
}
+
+ // Assumes this is the last use. IsKill will be unset if reg is reused
+ // unless it's a two-address operand.
+ if (ti == -1)
+ MI.getOperand(i).setIsKill();
+
continue;
} // CanReuse
DefMO = NextMII->findRegisterDefOperand(DestReg);
DefMO->setSubReg(SubIdx);
}
+
+ // Mark is killed.
+ MachineOperand *KillOpnd = NextMII->findRegisterUseOperand(InReg);
+ KillOpnd->setIsKill();
+
BackTracked = true;
} else {
DOUT << "Removing now-noop copy: " << MI;