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:
Cameron Zwarich
2013-02-17 00:10:44 +00:00
parent cc54889cd5
commit f0b2535344
3 changed files with 80 additions and 0 deletions

View File

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