aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/RegAllocGreedy.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-02-04 21:42:06 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-02-04 21:42:06 +0000
commit63935420ef1c323b9d9276eadc0ab74ee86a25b5 (patch)
treee5b8cf1b0113923eab4f5222d14f625f8f55b9b9 /lib/CodeGen/RegAllocGreedy.cpp
parent2d7a53aec2c6426eba9e5dd6462cc9e86432b410 (diff)
downloadexternal_llvm-63935420ef1c323b9d9276eadc0ab74ee86a25b5.tar.gz
external_llvm-63935420ef1c323b9d9276eadc0ab74ee86a25b5.tar.bz2
external_llvm-63935420ef1c323b9d9276eadc0ab74ee86a25b5.zip
Be more accurate about live range splitting at the end of blocks.
If interference reaches the last split point, it is effectively live out and should be marked as 'MustSpill'. This can make a difference when the terminator uses a register. There is no way that register can be reused in the outgoing CFG bundle, even if it isn't live out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124900 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocGreedy.cpp')
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index f478d76bf7..9220d429fc 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -88,6 +88,8 @@ class RAGreedy : public MachineFunctionPass, public RegAllocBase {
SlotIndex LastUse; ///< Last instr using current reg.
SlotIndex Kill; ///< Interval end point inside block.
SlotIndex Def; ///< Interval start point inside block.
+ /// Last possible point for splitting live ranges.
+ SlotIndex LastSplitPoint;
bool Uses; ///< Current reg has uses or defs in block.
bool LiveThrough; ///< Live in whole block (Templ 5. or 6. above).
bool LiveIn; ///< Current reg is live in.
@@ -356,6 +358,16 @@ void RAGreedy::calcLiveBlockInfo(LiveInterval &VirtReg) {
SlotIndex Start, Stop;
tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
+ // The last split point is the latest possible insertion point that dominates
+ // all successor blocks. If interference reaches LastSplitPoint, it is not
+ // possible to insert a split or reload that makes VirtReg live in the
+ // outgoing bundle.
+ MachineBasicBlock::iterator LSP = LIS->getLastSplitPoint(VirtReg, BI.MBB);
+ if (LSP == BI.MBB->end())
+ BI.LastSplitPoint = Stop;
+ else
+ BI.LastSplitPoint = Indexes->getInstructionIndex(LSP);
+
// LVI is the first live segment overlapping MBB.
BI.LiveIn = LVI->start <= Start;
if (!BI.LiveIn)
@@ -462,7 +474,8 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
// Check if interference is live-out - force spill.
if (BC.Exit != SpillPlacement::MustSpill) {
BC.Exit = SpillPlacement::PrefSpill;
- IntI.advanceTo(Stop);
+ // Any interference overlapping [LastSplitPoint;Stop) forces a spill.
+ IntI.advanceTo(BI.LastSplitPoint.getPrevSlot());
if (IntI.valid() && IntI.start() < Stop)
BC.Exit = SpillPlacement::MustSpill;
}
@@ -522,8 +535,8 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
if (IntI.start() < Stop)
BC.Exit = SpillPlacement::PrefSpill;
}
- // Is the interference live-out?
- IntI.advanceTo(Stop);
+ // Is the interference overlapping the last split point?
+ IntI.advanceTo(BI.LastSplitPoint.getPrevSlot());
if (!IntI.valid())
break;
if (IntI.start() < Stop)
@@ -709,7 +722,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
SE.enterIntvAtEnd(*BI.MBB);
continue;
}
- if (IP.second < BI.LastUse) {
+ if (IP.second < BI.LastUse && IP.second <= BI.LastSplitPoint) {
// There are interference-free uses at the end of the block.
// Find the first use that can get the live-out register.
SmallVectorImpl<SlotIndex>::const_iterator UI =