Tell the register allocator about new unused virtual registers.

This allows the allocator to free any resources used by the virtual register,
including physical register assignments.

llvm-svn: 127560
This commit is contained in:
Jakob Stoklund Olesen 2011-03-13 01:23:11 +00:00
parent e747eabef1
commit 2d87d5139b
4 changed files with 26 additions and 1 deletions

View File

@ -573,5 +573,6 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
MI->eraseFromParent();
}
// FIXME: Notify the register allocator that the snippets are now dead.
for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i)
edit.eraseVirtReg(RegsToSpill[i], lis_);
}

View File

@ -131,6 +131,11 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
return lis.InsertMachineInstrInMaps(--MI).getDefIndex();
}
void LiveRangeEdit::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
if (delegate_ && delegate_->LRE_CanEraseVirtReg(Reg))
LIS.removeInterval(Reg);
}
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
LiveIntervals &LIS,
const TargetInstrInfo &TII) {

View File

@ -34,6 +34,11 @@ public:
struct Delegate {
/// Called immediately before erasing a dead machine instruction.
virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
/// Called when a virtual register is no longer used. Return false to defer
/// its deletion from LiveIntervals.
virtual bool LRE_CanEraseVirtReg(unsigned) { return true; }
virtual ~Delegate() {}
};
@ -150,6 +155,10 @@ public:
return rematted_.count(ParentVNI);
}
/// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
/// to erase it from LIS.
void eraseVirtReg(unsigned Reg, LiveIntervals &LIS);
/// eliminateDeadDefs - Try to delete machine instructions that are now dead
/// (allDefsAreDead returns true). This may cause live intervals to be trimmed
/// and further dead efs to be eliminated.

View File

@ -161,6 +161,7 @@ public:
private:
void LRE_WillEraseInstruction(MachineInstr*);
bool LRE_CanEraseVirtReg(unsigned);
bool checkUncachedInterference(LiveInterval&, unsigned);
LiveInterval *getSingleInterference(LiveInterval&, unsigned);
@ -249,6 +250,15 @@ void RAGreedy::LRE_WillEraseInstruction(MachineInstr *MI) {
VRM->RemoveMachineInstrFromMaps(MI);
}
bool RAGreedy::LRE_CanEraseVirtReg(unsigned VirtReg) {
if (unsigned PhysReg = VRM->getPhys(VirtReg)) {
unassign(LIS->getInterval(VirtReg), PhysReg);
return true;
}
// Unassigned virtreg is probably in the priority queue.
// RegAllocBase will erase it after dequeueing.
return false;
}
void RAGreedy::releaseMemory() {
SpillerInstance.reset(0);