Tell the register allocator about new unused virtual registers.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 13 Mar 2011 01:23:11 +0000 (01:23 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sun, 13 Mar 2011 01:23:11 +0000 (01:23 +0000)
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

lib/CodeGen/InlineSpiller.cpp
lib/CodeGen/LiveRangeEdit.cpp
lib/CodeGen/LiveRangeEdit.h
lib/CodeGen/RegAllocGreedy.cpp

index 8964853e9fde4bd87c2d2237d274ba4dba80ee48..1b1cd68e2266d70a614509a0e71deeefc3e330cd 100644 (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_);
 }
index 75aeac46390e7c563ea0dd39d760bb496a3a0154..c9985cd9d223cbbf4b612d1a0095e2d749177466 100644 (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) {
index 363f4d7572a05af0c1d963098804aa6e061d104d..a784826e95f8fcc06c2481775c28c37190cec3b4 100644 (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.
index 86fd1081678869eeaab3fcd0869f2db289d01afe..57119aacd2be1c8a49304c363b95c31dcc22f841 100644 (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);