mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
Add support for updating the LiveIntervals of registers used by 'exotic'
terminators that actually have register uses when splitting critical edges. This commit also introduces a method repairIntervalsInRange() on LiveIntervals, which allows for repairing LiveIntervals in a small range after an arbitrary target hook modifies, inserts, and removes instructions. It's pretty limited right now, but I hope to extend it to support all of the things that are done by the convertToThreeAddress() target hooks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175382 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cc54889cd5
commit
f0b2535344
@ -281,6 +281,21 @@ namespace llvm {
|
||||
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
|
||||
bool UpdateFlags = false);
|
||||
|
||||
/// repairIntervalsInRange - Update live intervals for instructions in a
|
||||
/// small range of reverse iterators. It is intended for use after target
|
||||
/// hooks that may insert or remove instructions, and is only efficient for
|
||||
/// a small number of instructions.
|
||||
///
|
||||
/// OrigRegs is a vector of registers that were originally used by the
|
||||
/// instructions in the range between the two iterators.
|
||||
///
|
||||
/// Currently, the only only changes that are supported are simple removal
|
||||
/// and addition of uses.
|
||||
void repairIntervalsInRange(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::reverse_iterator RBegin,
|
||||
MachineBasicBlock::reverse_iterator REnd,
|
||||
SmallVectorImpl<unsigned> &OrigRegs);
|
||||
|
||||
// Register mask functions.
|
||||
//
|
||||
// Machine instructions may use a register mask operand to indicate that a
|
||||
|
@ -1032,3 +1032,39 @@ void LiveIntervals::handleMoveIntoBundle(MachineInstr* MI,
|
||||
HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags);
|
||||
HME.updateAllRanges(MI);
|
||||
}
|
||||
|
||||
void
|
||||
LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::reverse_iterator RBegin,
|
||||
MachineBasicBlock::reverse_iterator REnd,
|
||||
SmallVectorImpl<unsigned> &OrigRegs) {
|
||||
for (unsigned i = 0, e = OrigRegs.size(); i != e; ++i) {
|
||||
unsigned Reg = OrigRegs[i];
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
continue;
|
||||
|
||||
LiveInterval &LI = getInterval(Reg);
|
||||
SlotIndex startIdx = (REnd == MBB->rend()) ? getMBBStartIdx(MBB)
|
||||
: getInstructionIndex(&*REnd);
|
||||
for (MachineBasicBlock::reverse_iterator I = RBegin; I != REnd; ++I) {
|
||||
MachineInstr *MI = &*I;
|
||||
SlotIndex instrIdx = getInstructionIndex(MI);
|
||||
|
||||
for (MachineInstr::mop_iterator OI = MI->operands_begin(),
|
||||
OE = MI->operands_end(); OI != OE; ++OI) {
|
||||
const MachineOperand &MO = *OI;
|
||||
if (!MO.isReg() || MO.getReg() != Reg)
|
||||
continue;
|
||||
|
||||
assert(MO.isUse() && "Register defs are not yet supported.");
|
||||
|
||||
if (!LI.liveAt(instrIdx)) {
|
||||
LiveRange *LR = LI.getLiveRangeContaining(startIdx.getRegSlot());
|
||||
assert(LR && "Used registers must be live-in.");
|
||||
LR->end = instrIdx.getRegSlot();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -698,6 +698,24 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<unsigned, 4> UsedRegs;
|
||||
if (LIS) {
|
||||
for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
|
||||
I != E; ++I) {
|
||||
MachineInstr *MI = I;
|
||||
|
||||
for (MachineInstr::mop_iterator OI = MI->operands_begin(),
|
||||
OE = MI->operands_end(); OI != OE; ++OI) {
|
||||
if (!OI->isReg() || OI->getReg() == 0)
|
||||
continue;
|
||||
|
||||
unsigned Reg = OI->getReg();
|
||||
if (std::find(UsedRegs.begin(), UsedRegs.end(), Reg) == UsedRegs.end())
|
||||
UsedRegs.push_back(Reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReplaceUsesOfBlockWith(Succ, NMBB);
|
||||
|
||||
// If updateTerminator() removes instructions, we need to remove them from
|
||||
@ -830,6 +848,17 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
|
||||
LI.removeRange(StartIndex, EndIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Update all intervals for registers whose uses may have been modified by
|
||||
// updateTerminator().
|
||||
iterator FirstTerminator = getFirstTerminator();
|
||||
MachineInstr *FirstTerminatorMI = FirstTerminator;
|
||||
if (FirstTerminatorMI->isBundled())
|
||||
FirstTerminatorMI = getBundleStart(FirstTerminatorMI);
|
||||
reverse_iterator PreTerminators =
|
||||
(FirstTerminator == begin()) ? rend()
|
||||
: reverse_iterator(FirstTerminatorMI);
|
||||
LIS->repairIntervalsInRange(this, rbegin(), PreTerminators, UsedRegs);
|
||||
}
|
||||
|
||||
if (MachineDominatorTree *MDT =
|
||||
|
Loading…
Reference in New Issue
Block a user