Index: llvm/trunk/include/llvm/CodeGen/LiveRangeEdit.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveRangeEdit.h +++ llvm/trunk/include/llvm/CodeGen/LiveRangeEdit.h @@ -241,11 +241,8 @@ /// RegsBeingSpilled lists registers currently being spilled by the register /// allocator. These registers should not be split into new intervals /// as currently those new intervals are not guaranteed to spill. - /// NoSplit indicates this func is used after the iterations of selectOrSplit - /// where registers should not be split into new intervals. void eliminateDeadDefs(SmallVectorImpl &Dead, - ArrayRef RegsBeingSpilled = None, - bool NoSplit = false); + ArrayRef RegsBeingSpilled = None); /// calculateRegClassAndHint - Recompute register class and hint for each new /// register. Index: llvm/trunk/lib/CodeGen/InlineSpiller.cpp =================================================================== --- llvm/trunk/lib/CodeGen/InlineSpiller.cpp +++ llvm/trunk/lib/CodeGen/InlineSpiller.cpp @@ -55,7 +55,8 @@ cl::desc("Disable inline spill hoisting")); namespace { -class HoistSpillHelper { +class HoistSpillHelper : private LiveRangeEdit::Delegate { + MachineFunction &MF; LiveIntervals &LIS; LiveStacks &LSS; AliasAnalysis *AA; @@ -105,7 +106,7 @@ public: HoistSpillHelper(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm) - : LIS(pass.getAnalysis()), + : MF(mf), LIS(pass.getAnalysis()), LSS(pass.getAnalysis()), AA(&pass.getAnalysis().getAAResults()), MDT(pass.getAnalysis()), @@ -118,7 +119,8 @@ void addToMergeableSpills(MachineInstr *Spill, int StackSlot, unsigned Original); bool rmFromMergeableSpills(MachineInstr *Spill, int StackSlot); - void hoistAllSpills(LiveRangeEdit &Edit); + void hoistAllSpills(); + void LRE_DidCloneVirtReg(unsigned, unsigned) override; }; class InlineSpiller : public Spiller { @@ -1040,13 +1042,7 @@ /// Optimizations after all the reg selections and spills are done. /// -void InlineSpiller::postOptimization() { - SmallVector NewVRegs; - LiveRangeEdit LRE(nullptr, NewVRegs, MF, LIS, &VRM, nullptr); - HSpiller.hoistAllSpills(LRE); - assert(NewVRegs.size() == 0 && - "No new vregs should be generated in hoistAllSpills"); -} +void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); } /// When a spill is inserted, add the spill to MergeableSpills map. /// @@ -1360,7 +1356,10 @@ /// its subtree to that node. In this way, we can get benefit locally even if /// hoisting all the equal spills to one cold place is impossible. /// -void HoistSpillHelper::hoistAllSpills(LiveRangeEdit &Edit) { +void HoistSpillHelper::hoistAllSpills() { + SmallVector NewVRegs; + LiveRangeEdit Edit(nullptr, NewVRegs, MF, LIS, &VRM, this); + // Save the mapping between stackslot and its original reg. DenseMap SlotToOrigReg; for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) { @@ -1436,6 +1435,17 @@ RMEnt->RemoveOperand(i - 1); } } - Edit.eliminateDeadDefs(SpillsToRm, None, true); + Edit.eliminateDeadDefs(SpillsToRm, None); } } + +/// For VirtReg clone, the \p New register should have the same physreg or +/// stackslot as the \p old register. +void HoistSpillHelper::LRE_DidCloneVirtReg(unsigned New, unsigned Old) { + if (VRM.hasPhys(Old)) + VRM.assignVirt2Phys(New, VRM.getPhys(Old)); + else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT) + VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old)); + else + llvm_unreachable("VReg should be assigned either physreg or stackslot"); +} Index: llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp +++ llvm/trunk/lib/CodeGen/LiveRangeEdit.cpp @@ -356,8 +356,7 @@ } void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl &Dead, - ArrayRef RegsBeingSpilled, - bool NoSplit) { + ArrayRef RegsBeingSpilled) { ToShrinkSet ToShrink; for (;;) { @@ -379,9 +378,6 @@ if (!LIS.shrinkToUses(LI, &Dead)) continue; - if (NoSplit) - continue; - // Don't create new intervals for a register being spilled. // The new intervals would have to be spilled anyway so its not worth it. // Also they currently aren't spilled so creating them and not spilling Index: llvm/trunk/test/CodeGen/X86/interval-update-remat.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/interval-update-remat.ll +++ llvm/trunk/test/CodeGen/X86/interval-update-remat.ll @@ -1,4 +1,4 @@ -; RUN: llc -verify-regalloc < %s +; RUN: llc -verify-regalloc -verify-machineinstrs < %s ; PR27275: When enabling remat for vreg defined by PHIs, make sure the update ; of the live range removes dead phi. Otherwise, we may end up with PHIs with ; incorrect operands and that will trigger assertions or verifier failures