mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01: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:
parent
8a6aec9eb4
commit
daa65cd09a
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user