diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp index e994d8c32d49..489d88c1dfbd 100644 --- a/llvm/lib/CodeGen/LiveRangeEdit.cpp +++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -201,8 +201,11 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, break; // Shrink just one live interval. Then delete new dead defs. - LIS.shrinkToUses(ToShrink.back(), &Dead); + LiveInterval *LI = ToShrink.back(); ToShrink.pop_back(); + if (delegate_) + delegate_->LRE_WillShrinkVirtReg(LI->reg); + LIS.shrinkToUses(LI, &Dead); } } diff --git a/llvm/lib/CodeGen/LiveRangeEdit.h b/llvm/lib/CodeGen/LiveRangeEdit.h index a784826e95f8..2bd34611c24e 100644 --- a/llvm/lib/CodeGen/LiveRangeEdit.h +++ b/llvm/lib/CodeGen/LiveRangeEdit.h @@ -39,6 +39,9 @@ public: /// its deletion from LiveIntervals. virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } + /// Called before shrinking the live range of a virtual register. + virtual void LRE_WillShrinkVirtReg(unsigned) {} + virtual ~Delegate() {} }; diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 940ed814652e..6feae4790d0a 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -162,6 +162,7 @@ public: private: void LRE_WillEraseInstruction(MachineInstr*); bool LRE_CanEraseVirtReg(unsigned); + void LRE_WillShrinkVirtReg(unsigned); bool checkUncachedInterference(LiveInterval&, unsigned); LiveInterval *getSingleInterference(LiveInterval&, unsigned); @@ -260,6 +261,17 @@ bool RAGreedy::LRE_CanEraseVirtReg(unsigned VirtReg) { return false; } +void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) { + unsigned PhysReg = VRM->getPhys(VirtReg); + if (!PhysReg) + return; + + // Register is assigned, put it back on the queue for reassignment. + LiveInterval &LI = LIS->getInterval(VirtReg); + unassign(LI, PhysReg); + enqueue(&LI); +} + void RAGreedy::releaseMemory() { SpillerInstance.reset(0); LRStage.clear();