Index: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h +++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h @@ -602,19 +602,15 @@ return newIndex; } - /// Remove the given machine instruction from the mapping. - void removeMachineInstrFromMaps(MachineInstr &MI) { - // remove index -> MachineInstr and - // MachineInstr -> index mappings - Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); - if (mi2iItr != mi2iMap.end()) { - IndexListEntry *miEntry(mi2iItr->second.listEntry()); - assert(miEntry->getInstr() == &MI && "Instruction indexes broken."); - // FIXME: Eventually we want to actually delete these indexes. - miEntry->setInstr(nullptr); - mi2iMap.erase(mi2iItr); - } - } + /// 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); + + /// Removes a single machine instruction \p MI from the mapping. + /// This should be called before MachineInstr::eraseFromBundle() is used to + /// remove a single instruction (out of a bundle). + void removeSingleMachineInstrFromMaps(MachineInstr &MI); /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in /// maps used by register allocator. \returns the index where the new Index: llvm/trunk/lib/CodeGen/SlotIndexes.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SlotIndexes.cpp +++ llvm/trunk/lib/CodeGen/SlotIndexes.cpp @@ -103,6 +103,48 @@ return false; } +void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI) { + assert(!MI.isBundledWithPred() && + "Use removeSingleMachineInstrFromMaps() instread"); + Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); + if (mi2iItr == mi2iMap.end()) + return; + + SlotIndex MIIndex = mi2iItr->second; + IndexListEntry &MIEntry = *MIIndex.listEntry(); + assert(MIEntry.getInstr() == &MI && "Instruction indexes broken."); + mi2iMap.erase(mi2iItr); + // FIXME: Eventually we want to actually delete these indexes. + MIEntry.setInstr(nullptr); +} + +void SlotIndexes::removeSingleMachineInstrFromMaps(MachineInstr &MI) { + Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); + if (mi2iItr == mi2iMap.end()) + return; + + SlotIndex MIIndex = mi2iItr->second; + IndexListEntry &MIEntry = *MIIndex.listEntry(); + assert(MIEntry.getInstr() == &MI && "Instruction indexes broken."); + mi2iMap.erase(mi2iItr); + + // When removing the first instruction of a bundle update mapping to next + // instruction. + if (MI.isBundledWithSucc()) { + // Only the first instruction of a bundle should have an index assigned. + assert(!MI.isBundledWithPred() && "Should have first bundle isntruction"); + + MachineBasicBlock::instr_iterator Next = std::next(MI.getIterator()); + MachineInstr &NextMI = *Next; + MIEntry.setInstr(&NextMI); + mi2iMap.insert(std::make_pair(&NextMI, MIIndex)); + return; + } else { + // FIXME: Eventually we want to actually delete these indexes. + MIEntry.setInstr(nullptr); + } +} + void SlotIndexes::renumberIndexes() { // Renumber updates the index of every element of the index list. DEBUG(dbgs() << "\n*** Renumbering SlotIndexes ***\n"); Index: llvm/trunk/lib/CodeGen/VirtRegMap.cpp =================================================================== --- llvm/trunk/lib/CodeGen/VirtRegMap.cpp +++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp @@ -367,8 +367,8 @@ } if (Indexes) - Indexes->removeMachineInstrFromMaps(MI); - MI.eraseFromParent(); + Indexes->removeSingleMachineInstrFromMaps(MI); + MI.eraseFromBundle(); DEBUG(dbgs() << " deleted.\n"); } @@ -431,12 +431,14 @@ } } - // The flag only makes sense for sub-register defs, and - // we are substituting a full physreg. An operand - // from the SuperKills list will represent the partial read of the - // super-register. - if (MO.isDef()) + // The and flags only make sense for + // sub-register defs, and we are substituting a full physreg. An + // operand from the SuperKills list will represent the + // partial read of the super-register. + if (MO.isDef()) { MO.setIsUndef(false); + MO.setIsInternalRead(false); + } // PhysReg operands cannot have subregister indexes. PhysReg = TRI->getSubReg(PhysReg, SubReg);