Index: llvm/include/llvm/CodeGen/LiveRangeEdit.h =================================================================== --- llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -210,12 +210,14 @@ /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an /// instruction into MBB before MI. The new instruction is mapped, but - /// liveness is not updated. + /// liveness is not updated. If ReplaceIndexMI is not null it will be replaced + /// by new MI in the index map. /// Return the SlotIndex of the new instruction. SlotIndex rematerializeAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const Remat &RM, const TargetRegisterInfo &, - bool Late = false); + bool Late = false, unsigned SubIdx = 0, + MachineInstr *ReplaceIndexMI = nullptr); /// markRematerialized - explicitly mark a value as rematerialized after doing /// it manually. Index: llvm/lib/CodeGen/LiveRangeEdit.cpp =================================================================== --- llvm/lib/CodeGen/LiveRangeEdit.cpp +++ llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -183,14 +183,18 @@ unsigned DestReg, const Remat &RM, const TargetRegisterInfo &tri, - bool Late) { + bool Late, + unsigned SubIdx, + MachineInstr *ReplaceIndexMI) { assert(RM.OrigMI && "Invalid remat"); - TII.reMaterialize(MBB, MI, DestReg, 0, *RM.OrigMI, tri); + TII.reMaterialize(MBB, MI, DestReg, SubIdx, *RM.OrigMI, tri); // DestReg of the cloned instruction cannot be Dead. Set isDead of DestReg // to false anyway in case the isDead flag of RM.OrigMI's dest register // is true. (*--MI).getOperand(0).setIsDead(false); Rematted.insert(RM.ParentVNI); + if (ReplaceIndexMI) + return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI); return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot(); } Index: llvm/lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- llvm/lib/CodeGen/RegisterCoalescer.cpp +++ llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -199,12 +199,7 @@ DenseMap LargeLIVisitCounter; /// Recursively eliminate dead defs in DeadDefs. - void eliminateDeadDefs(); - - /// allUsesAvailableAt - Return true if all registers used by OrigMI at - /// OrigIdx are also available with the same value at UseIdx. - bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, - SlotIndex UseIdx); + void eliminateDeadDefs(LiveRangeEdit *Edit = nullptr); /// LiveRangeEdit callback for eliminateDeadDefs(). void LRE_WillEraseInstruction(MachineInstr *MI) override; @@ -603,20 +598,16 @@ MachineFunctionPass::getAnalysisUsage(AU); } -void RegisterCoalescer::eliminateDeadDefs() { +void RegisterCoalescer::eliminateDeadDefs(LiveRangeEdit *Edit) { + if (Edit) { + Edit->eliminateDeadDefs(DeadDefs); + return; + } SmallVector NewRegs; LiveRangeEdit(nullptr, NewRegs, *MF, *LIS, nullptr, this).eliminateDeadDefs(DeadDefs); } -bool RegisterCoalescer::allUsesAvailableAt(const MachineInstr *OrigMI, - SlotIndex OrigIdx, - SlotIndex UseIdx) { - SmallVector NewRegs; - return LiveRangeEdit(nullptr, NewRegs, *MF, *LIS, nullptr, this) - .allUsesAvailableAt(OrigMI, OrigIdx, UseIdx); -} - void RegisterCoalescer::LRE_WillEraseInstruction(MachineInstr *MI) { // MI may be in WorkList. Make sure we don't visit it. ErasedInstrs.insert(MI); @@ -1306,8 +1297,12 @@ } if (!TII->isAsCheapAsAMove(*DefMI)) return false; - if (!TII->isTriviallyReMaterializable(*DefMI)) + + SmallVector NewRegs; + LiveRangeEdit Edit(&SrcInt, NewRegs, *MF, *LIS, nullptr, this); + if (!Edit.checkRematerializable(ValNo, DefMI)) return false; + if (!definesFullReg(*DefMI, SrcReg)) return false; bool SawStore = false; @@ -1352,14 +1347,16 @@ } } - if (!allUsesAvailableAt(DefMI, ValNo->def, CopyIdx)) + LiveRangeEdit::Remat RM(ValNo); + RM.OrigMI = DefMI; + if (!Edit.canRematerializeAt(RM, ValNo, CopyIdx, true)) return false; DebugLoc DL = CopyMI->getDebugLoc(); MachineBasicBlock *MBB = CopyMI->getParent(); MachineBasicBlock::iterator MII = std::next(MachineBasicBlock::iterator(CopyMI)); - TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, *DefMI, *TRI); + Edit.rematerializeAt(*MBB, MII, DstReg, RM, *TRI, false, SrcIdx, CopyMI); MachineInstr &NewMI = *std::prev(MII); NewMI.setDebugLoc(DL); @@ -1403,7 +1400,6 @@ } } - LIS->ReplaceMachineInstrInMaps(*CopyMI, NewMI); CopyMI->eraseFromParent(); ErasedInstrs.insert(CopyMI); @@ -1597,7 +1593,7 @@ // The source interval can become smaller because we removed a use. shrinkToUses(&SrcInt, &DeadDefs); if (!DeadDefs.empty()) - eliminateDeadDefs(); + eliminateDeadDefs(&Edit); } else { ToBeUpdated.insert(SrcReg); }