mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
Implement RAGreedy::splitAroundRegion and remove loop splitting.
Region splitting includes loop splitting as a subset, and it is more generic. The splitting heuristics for variables that are live in more than one block are now: 1. Try to create a region that covers multiple basic blocks. 2. Try to create a new live range for each block with multiple uses. 3. Spill. Steps 2 and 3 are similar to what the standard spiller is doing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123853 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5c6fc1cab7
commit
ccdb3fcef9
@ -650,7 +650,9 @@ void LiveRange::dump() const {
|
||||
}
|
||||
|
||||
void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
|
||||
OS << PrintReg(reg, TRI) << ',' << weight;
|
||||
OS << PrintReg(reg, TRI);
|
||||
if (weight != 0)
|
||||
OS << ',' << weight;
|
||||
|
||||
if (empty())
|
||||
OS << " EMPTY";
|
||||
|
@ -83,7 +83,7 @@ class RAGreedy : public MachineFunctionPass, public RegAllocBase {
|
||||
/// 6. |-----------| Live-through without uses. Transparent.
|
||||
///
|
||||
struct BlockInfo {
|
||||
const MachineBasicBlock *MBB;
|
||||
MachineBasicBlock *MBB;
|
||||
SlotIndex FirstUse; ///< First instr using current reg.
|
||||
SlotIndex LastUse; ///< Last instr using current reg.
|
||||
SlotIndex Kill; ///< Interval end point inside block.
|
||||
@ -119,8 +119,8 @@ public:
|
||||
|
||||
virtual float getPriority(LiveInterval *LI);
|
||||
|
||||
virtual unsigned selectOrSplit(LiveInterval &VirtReg,
|
||||
SmallVectorImpl<LiveInterval*> &SplitVRegs);
|
||||
virtual unsigned selectOrSplit(LiveInterval&,
|
||||
SmallVectorImpl<LiveInterval*>&);
|
||||
|
||||
/// Perform register allocation.
|
||||
virtual bool runOnMachineFunction(MachineFunction &mf);
|
||||
@ -132,12 +132,12 @@ private:
|
||||
LiveInterval *getSingleInterference(LiveInterval&, unsigned);
|
||||
bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg);
|
||||
bool reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg);
|
||||
unsigned findInterferenceFreeReg(MachineLoopRange*,
|
||||
LiveInterval&, AllocationOrder&);
|
||||
float calcInterferenceWeight(LiveInterval&, unsigned);
|
||||
void calcLiveBlockInfo(LiveInterval&);
|
||||
float calcInterferenceInfo(LiveInterval&, unsigned);
|
||||
float calcGlobalSplitCost(const BitVector&);
|
||||
void splitAroundRegion(LiveInterval&, unsigned, const BitVector&,
|
||||
SmallVectorImpl<LiveInterval*>&);
|
||||
|
||||
unsigned tryReassign(LiveInterval&, AllocationOrder&);
|
||||
unsigned tryRegionSplit(LiveInterval&, AllocationOrder&,
|
||||
@ -323,90 +323,6 @@ unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order) {
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Loop Splitting
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// findInterferenceFreeReg - Find a physical register in Order where Loop has
|
||||
/// no interferences with VirtReg.
|
||||
unsigned RAGreedy::findInterferenceFreeReg(MachineLoopRange *Loop,
|
||||
LiveInterval &VirtReg,
|
||||
AllocationOrder &Order) {
|
||||
Order.rewind();
|
||||
while (unsigned PhysReg = Order.next()) {
|
||||
bool interference = false;
|
||||
for (const unsigned *AI = TRI->getOverlaps(PhysReg); *AI; ++AI) {
|
||||
if (query(VirtReg, *AI).checkLoopInterference(Loop)) {
|
||||
interference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!interference)
|
||||
return PhysReg;
|
||||
}
|
||||
// No physreg found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// trySplit - Try to split VirtReg or one of its interferences, making it
|
||||
/// assignable.
|
||||
/// @return Physreg when VirtReg may be assigned and/or new SplitVRegs.
|
||||
unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
SmallVectorImpl<LiveInterval*>&SplitVRegs) {
|
||||
// Don't attempt splitting on local intervals for now.
|
||||
if (LIS->intervalIsInOneMBB(VirtReg))
|
||||
return 0;
|
||||
|
||||
NamedRegionTimer T("Splitter", TimerGroupName, TimePassesIsEnabled);
|
||||
SA->analyze(&VirtReg);
|
||||
|
||||
// Get the set of loops that have VirtReg uses and are splittable.
|
||||
SplitAnalysis::LoopPtrSet SplitLoopSet;
|
||||
SA->getSplitLoops(SplitLoopSet);
|
||||
|
||||
// Order loops by descending area.
|
||||
SmallVector<MachineLoopRange*, 8> SplitLoops;
|
||||
for (SplitAnalysis::LoopPtrSet::const_iterator I = SplitLoopSet.begin(),
|
||||
E = SplitLoopSet.end(); I != E; ++I)
|
||||
SplitLoops.push_back(LoopRanges->getLoopRange(*I));
|
||||
array_pod_sort(SplitLoops.begin(), SplitLoops.end(),
|
||||
MachineLoopRange::byAreaDesc);
|
||||
|
||||
// Find the first loop that is interference-free for some register in the
|
||||
// allocation order.
|
||||
MachineLoopRange *Loop = 0;
|
||||
for (unsigned i = 0, e = SplitLoops.size(); i != e; ++i) {
|
||||
DEBUG(dbgs() << " Checking " << *SplitLoops[i]);
|
||||
if (unsigned PhysReg = findInterferenceFreeReg(SplitLoops[i],
|
||||
VirtReg, Order)) {
|
||||
(void)PhysReg;
|
||||
Loop = SplitLoops[i];
|
||||
DEBUG(dbgs() << ": Use %" << TRI->getName(PhysReg) << '\n');
|
||||
break;
|
||||
} else {
|
||||
DEBUG(dbgs() << ": Interference.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!Loop) {
|
||||
DEBUG(dbgs() << " All candidate loops have interference.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute the split around Loop.
|
||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||
LiveRangeEdit LREdit(VirtReg, SplitVRegs, SpillRegs);
|
||||
SplitEditor(*SA, *LIS, *VRM, *DomTree, LREdit)
|
||||
.splitAroundLoop(Loop->getLoop());
|
||||
|
||||
if (VerifyEnabled)
|
||||
MF->verify(this, "After splitting live range around loop");
|
||||
|
||||
// We have new split regs, don't assign anything.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Region Splitting
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -427,7 +343,7 @@ void RAGreedy::calcLiveBlockInfo(LiveInterval &VirtReg) {
|
||||
UseE = SA->UseSlots.end();
|
||||
|
||||
// Loop over basic blocks where VirtReg is live.
|
||||
MachineFunction::const_iterator MFI = Indexes->getMBBFromIndex(LVI->start);
|
||||
MachineFunction::iterator MFI = Indexes->getMBBFromIndex(LVI->start);
|
||||
for (;;) {
|
||||
// Block constraints depend on the interference pattern.
|
||||
// Just allocate them here, don't compute anything.
|
||||
@ -665,6 +581,236 @@ float RAGreedy::calcGlobalSplitCost(const BitVector &LiveBundles) {
|
||||
return GlobalCost;
|
||||
}
|
||||
|
||||
/// splitAroundRegion - Split VirtReg around the region determined by
|
||||
/// LiveBundles. Make an effort to avoid interference from PhysReg.
|
||||
///
|
||||
/// The 'register' interval is going to contain as many uses as possible while
|
||||
/// avoiding interference. The 'stack' interval is the complement constructed by
|
||||
/// SplitEditor. It will contain the rest.
|
||||
///
|
||||
void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
||||
const BitVector &LiveBundles,
|
||||
SmallVectorImpl<LiveInterval*> &NewVRegs) {
|
||||
DEBUG({
|
||||
dbgs() << "Splitting around region for " << PrintReg(PhysReg, TRI)
|
||||
<< " with bundles";
|
||||
for (int i = LiveBundles.find_first(); i>=0; i = LiveBundles.find_next(i))
|
||||
dbgs() << " EB#" << i;
|
||||
dbgs() << ".\n";
|
||||
});
|
||||
|
||||
// First compute interference ranges in the live blocks.
|
||||
typedef std::pair<SlotIndex, SlotIndex> IndexPair;
|
||||
SmallVector<IndexPair, 8> InterferenceRanges;
|
||||
InterferenceRanges.resize(LiveBlocks.size());
|
||||
for (const unsigned *AI = TRI->getOverlaps(PhysReg); *AI; ++AI) {
|
||||
if (!query(VirtReg, *AI).checkInterference())
|
||||
continue;
|
||||
LiveIntervalUnion::SegmentIter IntI =
|
||||
PhysReg2LiveUnion[*AI].find(VirtReg.beginIndex());
|
||||
if (!IntI.valid())
|
||||
continue;
|
||||
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
|
||||
BlockInfo &BI = LiveBlocks[i];
|
||||
if (!BI.Uses)
|
||||
continue;
|
||||
IndexPair &IP = InterferenceRanges[i];
|
||||
SlotIndex Start, Stop;
|
||||
tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
|
||||
// Skip interference-free blocks.
|
||||
if (IntI.start() >= Stop)
|
||||
continue;
|
||||
|
||||
// First interference in block.
|
||||
if (BI.LiveIn) {
|
||||
IntI.advanceTo(Start);
|
||||
if (!IntI.valid())
|
||||
break;
|
||||
if (!IP.first.isValid() || IntI.start() < IP.first)
|
||||
IP.first = IntI.start();
|
||||
}
|
||||
|
||||
// Last interference in block.
|
||||
if (BI.LiveOut) {
|
||||
IntI.advanceTo(Stop);
|
||||
if (!IntI.valid() || IntI.start() >= Stop)
|
||||
--IntI;
|
||||
if (!IP.second.isValid() || IntI.stop() > IP.second)
|
||||
IP.second = IntI.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
||||
SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit);
|
||||
|
||||
// Create the main cross-block interval.
|
||||
SE.openIntv();
|
||||
|
||||
// First add all defs that are live out of a block.
|
||||
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
|
||||
BlockInfo &BI = LiveBlocks[i];
|
||||
bool RegIn = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
|
||||
bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
|
||||
|
||||
// Should the register be live out?
|
||||
if (!BI.LiveOut || !RegOut)
|
||||
continue;
|
||||
|
||||
IndexPair &IP = InterferenceRanges[i];
|
||||
SlotIndex Start, Stop;
|
||||
tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
|
||||
|
||||
DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " -> EB#"
|
||||
<< Bundles->getBundle(BI.MBB->getNumber(), 1));
|
||||
|
||||
// Check interference leaving the block.
|
||||
if (!IP.second.isValid() || IP.second < Start) {
|
||||
// Block is interference-free.
|
||||
DEBUG(dbgs() << ", no interference");
|
||||
if (!BI.Uses) {
|
||||
assert(BI.LiveThrough && "No uses, but not live through block?");
|
||||
// Block is live-through without interference.
|
||||
DEBUG(dbgs() << ", no uses"
|
||||
<< (RegIn ? ", live-through.\n" : ", stack in.\n"));
|
||||
if (!RegIn)
|
||||
SE.enterIntvAtEnd(*BI.MBB);
|
||||
continue;
|
||||
}
|
||||
if (!BI.LiveThrough) {
|
||||
DEBUG(dbgs() << ", not live-through.\n");
|
||||
SE.enterIntvBefore(BI.Def);
|
||||
SE.useIntv(BI.Def, Stop);
|
||||
continue;
|
||||
}
|
||||
if (!RegIn) {
|
||||
// Block is live-through, but entry bundle is on the stack.
|
||||
// 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);
|
||||
continue;
|
||||
}
|
||||
DEBUG(dbgs() << ", live-through.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Block has interference.
|
||||
DEBUG(dbgs() << ", interference to " << IP.second);
|
||||
if (!BI.Uses) {
|
||||
// No uses in block, avoid interference by reloading as late as possible.
|
||||
DEBUG(dbgs() << ", no uses.\n");
|
||||
SE.enterIntvAtEnd(*BI.MBB);
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
DEBUG(dbgs() << ", free use at " << Use << ".\n");
|
||||
assert(Use > IP.second && Use <= BI.LastUse);
|
||||
SE.enterIntvBefore(Use);
|
||||
SE.useIntv(Use, Stop);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Interference is after the last use.
|
||||
DEBUG(dbgs() << " after last use.\n");
|
||||
SE.enterIntvAtEnd(*BI.MBB);
|
||||
}
|
||||
|
||||
// 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];
|
||||
bool RegIn = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
|
||||
bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
|
||||
|
||||
// Is the register live-in?
|
||||
if (!BI.LiveIn || !RegIn)
|
||||
continue;
|
||||
|
||||
// We have an incoming register. Check for interference.
|
||||
IndexPair &IP = InterferenceRanges[i];
|
||||
SlotIndex Start, Stop;
|
||||
tie(Start, Stop) = Indexes->getMBBRange(BI.MBB);
|
||||
|
||||
DEBUG(dbgs() << "EB#" << Bundles->getBundle(BI.MBB->getNumber(), 0)
|
||||
<< " -> BB#" << BI.MBB->getNumber());
|
||||
|
||||
// Check interference entering the block.
|
||||
if (!IP.first.isValid() || IP.first > Stop) {
|
||||
// Block is interference-free.
|
||||
DEBUG(dbgs() << ", no interference");
|
||||
if (!BI.Uses) {
|
||||
assert(BI.LiveThrough && "No uses, but not live through block?");
|
||||
// Block is live-through without interference.
|
||||
if (RegOut) {
|
||||
DEBUG(dbgs() << ", no uses, live-through.\n");
|
||||
SE.useIntv(Start, Stop);
|
||||
} else {
|
||||
DEBUG(dbgs() << ", no uses, stack-out.\n");
|
||||
SE.leaveIntvAtTop(*BI.MBB);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!BI.LiveThrough) {
|
||||
DEBUG(dbgs() << ", killed in block.\n");
|
||||
SE.useIntv(Start, BI.Kill);
|
||||
SE.leaveIntvAfter(BI.Kill);
|
||||
continue;
|
||||
}
|
||||
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, BI.LastUse);
|
||||
SE.leaveIntvAfter(BI.LastUse);
|
||||
continue;
|
||||
}
|
||||
// Register is live-through.
|
||||
DEBUG(dbgs() << ", uses, live-through.\n");
|
||||
SE.useIntv(Start, Stop);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Block has interference.
|
||||
DEBUG(dbgs() << ", interference from " << IP.first);
|
||||
if (!BI.Uses) {
|
||||
// No uses in block, avoid interference by spilling as soon as possible.
|
||||
DEBUG(dbgs() << ", no uses.\n");
|
||||
SE.leaveIntvAtTop(*BI.MBB);
|
||||
continue;
|
||||
}
|
||||
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");
|
||||
assert(Use >= BI.FirstUse && Use < IP.first);
|
||||
SE.useIntv(Start, Use);
|
||||
SE.leaveIntvAfter(Use);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Interference is before the first use.
|
||||
DEBUG(dbgs() << " before first use.\n");
|
||||
SE.leaveIntvAtTop(*BI.MBB);
|
||||
}
|
||||
|
||||
SE.closeIntv();
|
||||
|
||||
// FIXME: Should we be more aggressive about splitting the stack region into
|
||||
// per-block segments? The current approach allows the stack region to
|
||||
// separate into connected components. Some components may be allocatable.
|
||||
SE.finish();
|
||||
|
||||
if (VerifyEnabled)
|
||||
MF->verify(this, "After splitting live range around region");
|
||||
}
|
||||
|
||||
unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
SmallVectorImpl<LiveInterval*> &NewVRegs) {
|
||||
calcLiveBlockInfo(VirtReg);
|
||||
@ -676,18 +822,62 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
float Cost = calcInterferenceInfo(VirtReg, PhysReg);
|
||||
if (BestReg && Cost >= BestCost)
|
||||
continue;
|
||||
if (!SpillPlacer->placeSpills(SpillConstraints, LiveBundles))
|
||||
Cost += calcGlobalSplitCost(LiveBundles);
|
||||
|
||||
SpillPlacer->placeSpills(SpillConstraints, LiveBundles);
|
||||
// No live bundles, defer to splitSingleBlocks().
|
||||
if (!LiveBundles.any())
|
||||
continue;
|
||||
|
||||
Cost += calcGlobalSplitCost(LiveBundles);
|
||||
if (!BestReg || Cost < BestCost) {
|
||||
BestReg = PhysReg;
|
||||
BestCost = Cost;
|
||||
BestBundles.swap(LiveBundles);
|
||||
}
|
||||
}
|
||||
// FIXME: Actually execute the split.
|
||||
|
||||
if (!BestReg)
|
||||
return 0;
|
||||
|
||||
splitAroundRegion(VirtReg, BestReg, BestBundles, NewVRegs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Live Range Splitting
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// trySplit - Try to split VirtReg or one of its interferences, making it
|
||||
/// assignable.
|
||||
/// @return Physreg when VirtReg may be assigned and/or new NewVRegs.
|
||||
unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
SmallVectorImpl<LiveInterval*>&NewVRegs) {
|
||||
NamedRegionTimer T("Splitter", TimerGroupName, TimePassesIsEnabled);
|
||||
SA->analyze(&VirtReg);
|
||||
|
||||
// Don't attempt splitting on local intervals for now. TBD.
|
||||
if (LIS->intervalIsInOneMBB(VirtReg))
|
||||
return 0;
|
||||
|
||||
// First try to split around a region spanning multiple blocks.
|
||||
unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
|
||||
if (PhysReg || !NewVRegs.empty())
|
||||
return PhysReg;
|
||||
|
||||
// Then isolate blocks with multiple uses.
|
||||
SplitAnalysis::BlockPtrSet Blocks;
|
||||
if (SA->getMultiUseBlocks(Blocks)) {
|
||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
||||
SplitEditor(*SA, *LIS, *VRM, *DomTree, LREdit).splitSingleBlocks(Blocks);
|
||||
}
|
||||
|
||||
// Don't assign any physregs.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Spilling
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -756,7 +946,7 @@ unsigned RAGreedy::trySpillInterferences(LiveInterval &VirtReg,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
|
||||
SmallVectorImpl<LiveInterval*> &SplitVRegs) {
|
||||
SmallVectorImpl<LiveInterval*> &NewVRegs) {
|
||||
// First try assigning a free register.
|
||||
AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs);
|
||||
while (unsigned PhysReg = Order.next()) {
|
||||
@ -768,20 +958,22 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg,
|
||||
if (unsigned PhysReg = tryReassign(VirtReg, Order))
|
||||
return PhysReg;
|
||||
|
||||
assert(NewVRegs.empty() && "Cannot append to existing NewVRegs");
|
||||
|
||||
// Try splitting VirtReg or interferences.
|
||||
unsigned PhysReg = trySplit(VirtReg, Order, SplitVRegs);
|
||||
if (PhysReg || !SplitVRegs.empty())
|
||||
unsigned PhysReg = trySplit(VirtReg, Order, NewVRegs);
|
||||
if (PhysReg || !NewVRegs.empty())
|
||||
return PhysReg;
|
||||
|
||||
// Try to spill another interfering reg with less spill weight.
|
||||
PhysReg = trySpillInterferences(VirtReg, Order, SplitVRegs);
|
||||
PhysReg = trySpillInterferences(VirtReg, Order, NewVRegs);
|
||||
if (PhysReg)
|
||||
return PhysReg;
|
||||
|
||||
// Finally spill VirtReg itself.
|
||||
NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled);
|
||||
SmallVector<LiveInterval*, 1> pendingSpills;
|
||||
spiller().spill(&VirtReg, SplitVRegs, pendingSpills);
|
||||
spiller().spill(&VirtReg, NewVRegs, pendingSpills);
|
||||
|
||||
// The live virtual register requesting allocation was spilled, so tell
|
||||
// the caller not to allocate anything during this round.
|
||||
|
@ -867,9 +867,7 @@ void SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) {
|
||||
/// LiveInterval, and ranges can be trimmed.
|
||||
void SplitEditor::closeIntv() {
|
||||
assert(openli_.getLI() && "openIntv not called before closeIntv");
|
||||
|
||||
DEBUG(dbgs() << " closeIntv cleaning up\n");
|
||||
DEBUG(dbgs() << " open " << *openli_.getLI() << '\n');
|
||||
DEBUG(dbgs() << " closeIntv " << *openli_.getLI() << '\n');
|
||||
openli_.reset(0);
|
||||
}
|
||||
|
||||
@ -966,6 +964,8 @@ void SplitEditor::computeRemainder() {
|
||||
// FIXME: If a single value is redefined, just move the def and truncate.
|
||||
LiveInterval &parent = edit_.getParent();
|
||||
|
||||
DEBUG(dbgs() << "computeRemainder from " << parent << '\n');
|
||||
|
||||
// Values that are fully contained in the split intervals.
|
||||
SmallPtrSet<const VNInfo*, 8> deadValues;
|
||||
// Map all curli values that should have live defs in dupli.
|
||||
|
Loading…
Reference in New Issue
Block a user