1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

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

llvm-svn: 298024
This commit is contained in:
Matthias Braun 2017-03-17 00:41:33 +00:00
parent 8a6aec9eb4
commit daa65cd09a
3 changed files with 60 additions and 20 deletions

View File

@ -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

View File

@ -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");

View File

@ -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 <def,undef> flag only makes sense for sub-register defs, and
// we are substituting a full physreg. An <imp-use,kill> operand
// from the SuperKills list will represent the partial read of the
// super-register.
if (MO.isDef())
// The <def,undef> and <def,internal> flags only make sense for
// sub-register defs, and we are substituting a full physreg. An
// <imp-use,kill> 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);