Add LiveIntervals::getLastSplitPoint().

A live range cannot be split everywhere in a basic block. A split must go before
the first terminator, and if the variable is live into a landing pad, the split
must happen before the call that can throw.

llvm-svn: 124894
This commit is contained in:
Jakob Stoklund Olesen 2011-02-04 19:33:11 +00:00
parent 0ceb8d032a
commit bf833680ec
5 changed files with 43 additions and 1 deletions

View File

@ -308,6 +308,12 @@ namespace llvm {
/// within a single basic block.
bool intervalIsInOneMBB(const LiveInterval &li) const;
/// getLastSplitPoint - Return the last possible insertion point in mbb for
/// spilling and splitting code. This is the first terminator, or the call
/// instruction if li is live into a landing pad successor.
MachineBasicBlock::iterator getLastSplitPoint(const LiveInterval &li,
MachineBasicBlock *mbb);
private:
/// computeIntervals - Compute live intervals.
void computeIntervals();

View File

@ -224,6 +224,10 @@ public:
/// this basic block is entered via an exception handler.
void setIsLandingPad() { IsLandingPad = true; }
/// getLandingPadSuccessor - If this block has a successor that is a landing
/// pad, return it. Otherwise return NULL.
const MachineBasicBlock *getLandingPadSuccessor() const;
// Code Layout methods.
/// moveBefore/moveAfter - move 'this' block before or after the specified

View File

@ -746,6 +746,28 @@ LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
// Register allocator hooks.
//
MachineBasicBlock::iterator
LiveIntervals::getLastSplitPoint(const LiveInterval &li,
MachineBasicBlock *mbb) {
const MachineBasicBlock *lpad = mbb->getLandingPadSuccessor();
// If li is not live into a landing pad, we can insert spill code before the
// first terminator.
if (!lpad || !isLiveInToMBB(li, lpad))
return mbb->getFirstTerminator();
// When there is a landing pad, spill code must go before the call instruction
// that can throw.
MachineBasicBlock::iterator I = mbb->end(), B = mbb->begin();
while (I != B) {
--I;
if (I->getDesc().isCall())
return I;
}
assert(0 && "Block with landing pad successor contains no call instruction");
return mbb->getFirstTerminator();
}
/// getReMatImplicitUse - If the remat definition MI has one (for now, we only
/// allow one) virtual register operand, then its uses are implicitly using
/// the register. Returns the virtual register.

View File

@ -175,6 +175,16 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
return end();
}
const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {
// A block with a landing pad successor only has one other successor.
if (succ_size() > 2)
return 0;
for (const_succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
if ((*I)->isLandingPad())
return *I;
return 0;
}
void MachineBasicBlock::dump() const {
print(dbgs());
}

View File

@ -826,7 +826,7 @@ SlotIndex SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
}
DEBUG(dbgs() << ": valno " << ParentVNI->id);
VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Last, MBB,
MBB.getFirstTerminator());
LIS.getLastSplitPoint(Edit.getParent(), &MBB));
RegAssign.insert(VNI->def, End, OpenIdx);
DEBUG(dump());
return VNI->def;