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;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the given machine instruction from the mapping.
|
/// Removes machine instruction (bundle) \p MI from the mapping.
|
||||||
void removeMachineInstrFromMaps(MachineInstr &MI) {
|
/// This should be called before MachineInstr::eraseFromParent() is used to
|
||||||
// remove index -> MachineInstr and
|
/// remove a whole bundle or an unbundled instruction.
|
||||||
// MachineInstr -> index mappings
|
void removeMachineInstrFromMaps(MachineInstr &MI);
|
||||||
Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
|
|
||||||
if (mi2iItr != mi2iMap.end()) {
|
/// Removes a single machine instruction \p MI from the mapping.
|
||||||
IndexListEntry *miEntry(mi2iItr->second.listEntry());
|
/// This should be called before MachineInstr::eraseFromBundle() is used to
|
||||||
assert(miEntry->getInstr() == &MI && "Instruction indexes broken.");
|
/// remove a single instruction (out of a bundle).
|
||||||
// FIXME: Eventually we want to actually delete these indexes.
|
void removeSingleMachineInstrFromMaps(MachineInstr &MI);
|
||||||
miEntry->setInstr(nullptr);
|
|
||||||
mi2iMap.erase(mi2iItr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
|
/// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
|
||||||
/// maps used by register allocator. \returns the index where the new
|
/// maps used by register allocator. \returns the index where the new
|
||||||
|
@ -103,6 +103,48 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
return false;
|
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() {
|
void SlotIndexes::renumberIndexes() {
|
||||||
// Renumber updates the index of every element of the index list.
|
// Renumber updates the index of every element of the index list.
|
||||||
DEBUG(dbgs() << "\n*** Renumbering SlotIndexes ***\n");
|
DEBUG(dbgs() << "\n*** Renumbering SlotIndexes ***\n");
|
||||||
|
@ -367,8 +367,8 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Indexes)
|
if (Indexes)
|
||||||
Indexes->removeMachineInstrFromMaps(MI);
|
Indexes->removeSingleMachineInstrFromMaps(MI);
|
||||||
MI.eraseFromParent();
|
MI.eraseFromBundle();
|
||||||
DEBUG(dbgs() << " deleted.\n");
|
DEBUG(dbgs() << " deleted.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,12 +431,14 @@ void VirtRegRewriter::rewrite() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The <def,undef> flag only makes sense for sub-register defs, and
|
// The <def,undef> and <def,internal> flags only make sense for
|
||||||
// we are substituting a full physreg. An <imp-use,kill> operand
|
// sub-register defs, and we are substituting a full physreg. An
|
||||||
// from the SuperKills list will represent the partial read of the
|
// <imp-use,kill> operand from the SuperKills list will represent the
|
||||||
// super-register.
|
// partial read of the super-register.
|
||||||
if (MO.isDef())
|
if (MO.isDef()) {
|
||||||
MO.setIsUndef(false);
|
MO.setIsUndef(false);
|
||||||
|
MO.setIsInternalRead(false);
|
||||||
|
}
|
||||||
|
|
||||||
// PhysReg operands cannot have subregister indexes.
|
// PhysReg operands cannot have subregister indexes.
|
||||||
PhysReg = TRI->getSubReg(PhysReg, SubReg);
|
PhysReg = TRI->getSubReg(PhysReg, SubReg);
|
||||||
|
Loading…
Reference in New Issue
Block a user