aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-13 01:23:11 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-03-13 01:23:11 +0000
commit7792e980c43536814ea42448db9799b4da32fef6 (patch)
tree588136e9c9fab1ac2531f5ce6b1c8ad1fa9738c1
parentb56130f96b6ca98b0c78caf9f12f3936a4d240a8 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127560 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/InlineSpiller.cpp3
-rw-r--r--lib/CodeGen/LiveRangeEdit.cpp5
-rw-r--r--lib/CodeGen/LiveRangeEdit.h9
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp10
4 files changed, 26 insertions, 1 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp
index 8964853e9f..1b1cd68e22 100644
--- a/lib/CodeGen/InlineSpiller.cpp
+++ b/lib/CodeGen/InlineSpiller.cpp
@@ -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_);
}
diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp
index 75aeac4639..c9985cd9d2 100644
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -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) {
diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h
index 363f4d7572..a784826e95 100644
--- a/lib/CodeGen/LiveRangeEdit.h
+++ b/lib/CodeGen/LiveRangeEdit.h
@@ -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.
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 86fd108167..57119aacd2 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -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);