From: Matthias Braun Date: Fri, 17 Mar 2017 00:41:33 +0000 (+0000) Subject: VirtRegMap: Correctly deal with bundles when deleting identity copies. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=852989f86cced6742a76e99d5f91bdccab562253;p=llvm VirtRegMap: Correctly deal with bundles when deleting identity copies. This fixes two problems when VirtRegMap encounters bundles: - When substituting a vreg subregister def with an actual register the internal read flag must be cleared. - Removing an identity COPY from a bundle needs to use removeFromBundle() and a newly introduced function to update SlotIndexes. No testcase here, because none of the in-tree targets trigger this, however an upcoming commit of mine will need this and the testcase there will trigger this. Differential Revision: https://reviews.llvm.org/D30925 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298024 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 2ac3b3d86cb..14fc3a499a0 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -602,19 +602,15 @@ namespace llvm { 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 diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp index dba103e9bfb..bc2a1d09056 100644 --- a/lib/CodeGen/SlotIndexes.cpp +++ b/lib/CodeGen/SlotIndexes.cpp @@ -103,6 +103,48 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { 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"); diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 0d506d64665..b561c6aba18 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -367,8 +367,8 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const { } if (Indexes) - Indexes->removeMachineInstrFromMaps(MI); - MI.eraseFromParent(); + Indexes->removeSingleMachineInstrFromMaps(MI); + MI.eraseFromBundle(); DEBUG(dbgs() << " deleted.\n"); } @@ -431,12 +431,14 @@ void VirtRegRewriter::rewrite() { } } - // 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);