From 63935420ef1c323b9d9276eadc0ab74ee86a25b5 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 4 Feb 2011 21:42:06 +0000 Subject: [PATCH] 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 --- lib/CodeGen/RegAllocGreedy.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index f478d76bf79..9220d429fc4 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::const_iterator UI = -- 2.34.1