diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 2083c4bdc41..2b30c316f15 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -645,6 +645,9 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs); SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit); + // Ranges to add to the register interval after all defs are in place. + SmallVector UseRanges; + // Create the main cross-block interval. SE.openIntv(); @@ -681,7 +684,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.LiveThrough) { DEBUG(dbgs() << ", not live-through.\n"); SE.enterIntvBefore(BI.Def); - SE.useIntv(BI.Def, Stop); + UseRanges.push_back(IndexPair(BI.Def, Stop)); continue; } if (!RegIn) { @@ -689,7 +692,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, // Reload just before the first use. DEBUG(dbgs() << ", not live-in, enter before first use.\n"); SE.enterIntvBefore(BI.FirstUse); - SE.useIntv(BI.FirstUse, Stop); + UseRanges.push_back(IndexPair(BI.FirstUse, Stop)); continue; } DEBUG(dbgs() << ", live-through.\n"); @@ -707,12 +710,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (IP.second < BI.LastUse) { // There are interference-free uses at the end of the block. // Find the first use that can get the live-out register. - SlotIndex Use = *std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), - IP.second); + SmallVectorImpl::const_iterator UI = + std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), IP.second); + assert(UI != SA->UseSlots.end() && "Couldn't find last use"); + SlotIndex Use = *UI; DEBUG(dbgs() << ", free use at " << Use << ".\n"); - assert(Use > IP.second && Use <= BI.LastUse); + assert(Use <= BI.LastUse && "Couldn't find last use"); SE.enterIntvBefore(Use); - SE.useIntv(Use, Stop); + UseRanges.push_back(IndexPair(Use, Stop)); continue; } @@ -721,6 +726,12 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, SE.enterIntvAtEnd(*BI.MBB); } + // Add the live-out ranges following the defs. + // We must wait until all defs have been inserted, otherwise SplitKit gets + // confused about the value mapping. + for (unsigned i = 0, e = UseRanges.size(); i != e; ++i) + SE.useIntv(UseRanges[i].first, UseRanges[i].second); + // Now all defs leading to live bundles are handled, do everything else. for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) { BlockInfo &BI = LiveBlocks[i]; @@ -786,10 +797,11 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (IP.first > BI.FirstUse) { // There are interference-free uses at the beginning of the block. // Find the last use that can get the register. - SlotIndex Use = std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), - IP.second)[-1]; - DEBUG(dbgs() << ", free use at " << Use << ".\n"); - Use = Use.getBoundaryIndex(); + SmallVectorImpl::const_iterator UI = + std::lower_bound(SA->UseSlots.begin(), SA->UseSlots.end(), IP.first); + assert(UI != SA->UseSlots.begin() && "Couldn't find first use"); + SlotIndex Use = (--UI)->getBoundaryIndex(); + DEBUG(dbgs() << ", free use at " << *UI << ".\n"); assert(Use >= BI.FirstUse && Use < IP.first); SE.useIntv(Start, Use); SE.leaveIntvAfter(Use);