aboutsummaryrefslogtreecommitdiffstats
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)
downloadexternal_llvm-7792e980c43536814ea42448db9799b4da32fef6.zip
external_llvm-7792e980c43536814ea42448db9799b4da32fef6.tar.gz
external_llvm-7792e980c43536814ea42448db9799b4da32fef6.tar.bz2
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 8964853..1b1cd68 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 75aeac4..c9985cd 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 363f4d7..a784826 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 86fd108..57119aa 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);