diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-08 18:50:21 +0000 |
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-08 18:50:21 +0000 |
| commit | 5c716bdccce2fa504e1aa0b67226165d181d2459 (patch) | |
| tree | a3521d6a1e177037b2e620c3585ed3f0a462cd0a /lib/CodeGen/RegAllocGreedy.cpp | |
| parent | 01cb34b0111a1e8792f327b56c51bc3bbaf83aca (diff) | |
Add SplitEditor::overlapIntv() to create small ranges where both registers are live.
If a live range is used by a terminator instruction, and that live range needs
to leave the block on the stack or in a different register, it can be necessary
to have both sides of the split live at the terminator instruction.
Example:
%vreg2 = COPY %vreg1
JMP %vreg1
Becomes after spilling %vreg2:
SPILL %vreg1
JMP %vreg1
The spill doesn't kill the register as is normally the case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125102 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocGreedy.cpp')
| -rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index ff0c790f88..be01bdce44 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -746,6 +746,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, assert(Use <= BI.LastUse && "Couldn't find last use"); SlotIndex SegStart = SE.enterIntvBefore(Use); assert(SegStart >= IP.second && "Couldn't avoid interference"); + assert(SegStart < BI.LastSplitPoint && "Impossible split point"); SE.useIntv(SegStart, Stop); continue; } @@ -798,8 +799,30 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!RegOut) { // Block is live-through, but exit bundle is on the stack. // Spill immediately after the last use. - DEBUG(dbgs() << ", uses, stack-out.\n"); - SE.useIntv(Start, SE.leaveIntvAfter(BI.LastUse)); + if (BI.LastUse < BI.LastSplitPoint) { + DEBUG(dbgs() << ", uses, stack-out.\n"); + SE.useIntv(Start, SE.leaveIntvAfter(BI.LastUse)); + continue; + } + // The last use is after the last split point, it is probably an + // indirect jump. + DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point " + << BI.LastSplitPoint << ", stack-out.\n"); + SlotIndex SegEnd; + if (BI.LastSplitPoint == Start) + SegEnd = SE.leaveIntvAtTop(*BI.MBB); + else { + MachineBasicBlock::iterator I = + LIS->getInstructionFromIndex(BI.LastSplitPoint); + do assert(I != BI.MBB->begin() && "Expected instruction"); + while ((--I)->isDebugValue()); + SegEnd = SE.leaveIntvAfter(LIS->getInstructionIndex(I)); + } + SE.useIntv(Start, SegEnd); + // Run a double interval from the split to the last use. + // This makes it possible to spill the complement without affecting the + // indirect branch. + SE.overlapIntv(SegEnd, BI.LastUse); continue; } // Register is live-through. |
