diff --git a/llvm/include/llvm/CodeGen/LiveIntervals.h b/llvm/include/llvm/CodeGen/LiveIntervals.h --- a/llvm/include/llvm/CodeGen/LiveIntervals.h +++ b/llvm/include/llvm/CodeGen/LiveIntervals.h @@ -310,16 +310,16 @@ /// \param UpdateFlags Update live intervals for nonallocatable physregs. void handleMove(MachineInstr &MI, bool UpdateFlags = false); - /// Update intervals for operands of \p MI so that they begin/end on the - /// SlotIndex for \p BundleStart. + /// Update intervals of operands of all instructions in the newly + /// created bundle specified by \p BundleStart. /// /// \param UpdateFlags Update live intervals for nonallocatable physregs. /// - /// Requires MI and BundleStart to have SlotIndexes, and assumes - /// existing liveness is accurate. BundleStart should be the first - /// instruction in the Bundle. - void handleMoveIntoBundle(MachineInstr &MI, MachineInstr &BundleStart, - bool UpdateFlags = false); + /// Assumes existing livenewss is accurate. + /// BundleStart should be the first instruction in the Bundle. + /// BundleStart should not have a have SlotIndex as one will be assigned. + void handleMoveIntoNewBundle(MachineInstr &BundleStart, + bool UpdateFlags = false); /// Update live intervals for instructions in a range of iterators. It is /// intended for use after target hooks that may insert or remove diff --git a/llvm/include/llvm/CodeGen/SlotIndexes.h b/llvm/include/llvm/CodeGen/SlotIndexes.h --- a/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -382,13 +382,15 @@ } /// Returns the base index for the given instruction. - SlotIndex getInstructionIndex(const MachineInstr &MI) const { + SlotIndex getInstructionIndex(const MachineInstr &MI, + bool IgnoreBundle = false) const { // Instructions inside a bundle have the same number as the bundle itself. auto BundleStart = getBundleStart(MI.getIterator()); auto BundleEnd = getBundleEnd(MI.getIterator()); // Use the first non-debug instruction in the bundle to get SlotIndex. const MachineInstr &BundleNonDebug = - *skipDebugInstructionsForward(BundleStart, BundleEnd); + IgnoreBundle ? MI + : *skipDebugInstructionsForward(BundleStart, BundleEnd); assert(!BundleNonDebug.isDebugInstr() && "Could not use a debug instruction to query mi2iMap."); Mi2IndexMap::const_iterator itr = mi2iMap.find(&BundleNonDebug); @@ -573,7 +575,11 @@ /// Removes machine instruction (bundle) \p MI from the mapping. /// This should be called before MachineInstr::eraseFromParent() is used to /// remove a whole bundle or an unbundled instruction. - void removeMachineInstrFromMaps(MachineInstr &MI); + /// If \p AllowBundled is set then this can be used on a bundled + /// instruction; however, this exists to support handleMoveIntoBundle, + /// and in general removeSingleMachineInstrFromMaps should be used instead. + void removeMachineInstrFromMaps(MachineInstr &MI, + bool AllowBundled = false); /// Removes a single machine instruction \p MI from the mapping. /// This should be called before MachineInstr::eraseFromBundle() is used to diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -1478,13 +1478,26 @@ HME.updateAllRanges(&MI); } -void LiveIntervals::handleMoveIntoBundle(MachineInstr &MI, - MachineInstr &BundleStart, - bool UpdateFlags) { - SlotIndex OldIndex = Indexes->getInstructionIndex(MI); - SlotIndex NewIndex = Indexes->getInstructionIndex(BundleStart); - HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags); - HME.updateAllRanges(&MI); +void LiveIntervals::handleMoveIntoNewBundle(MachineInstr &BundleStart, + bool UpdateFlags) { + SmallVector ToProcess; + const SlotIndex NewIndex = Indexes->insertMachineInstrInMaps(BundleStart); + auto BundleEnd = getBundleEnd(BundleStart.getIterator()); + + auto I = BundleStart.getIterator(); + I++; + while (I != BundleEnd) { + if (!Indexes->hasIndex(*I)) + continue; + SlotIndex OldIndex = Indexes->getInstructionIndex(*I, true); + ToProcess.push_back(OldIndex); + Indexes->removeMachineInstrFromMaps(*I, true); + I++; + } + for (SlotIndex OldIndex : ToProcess) { + HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags); + HME.updateAllRanges(&BundleStart); + } } void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin, diff --git a/llvm/lib/CodeGen/SlotIndexes.cpp b/llvm/lib/CodeGen/SlotIndexes.cpp --- a/llvm/lib/CodeGen/SlotIndexes.cpp +++ b/llvm/lib/CodeGen/SlotIndexes.cpp @@ -112,9 +112,10 @@ return false; } -void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI) { - assert(!MI.isBundledWithPred() && - "Use removeSingleMachineInstrFromMaps() instread"); +void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI, + bool AllowBundled) { + assert((AllowBundled || !MI.isBundledWithPred()) && + "Use removeSingleMachineInstrFromMaps() instead"); Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); if (mi2iItr == mi2iMap.end()) return; @@ -141,7 +142,7 @@ // instruction. if (MI.isBundledWithSucc()) { // Only the first instruction of a bundle should have an index assigned. - assert(!MI.isBundledWithPred() && "Should have first bundle isntruction"); + assert(!MI.isBundledWithPred() && "Should be first bundle instruction"); MachineBasicBlock::instr_iterator Next = std::next(MI.getIterator()); MachineInstr &NextMI = *Next;