mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-02 00:35:27 +00:00
Create new intervals for isolated blocks during region splitting.
This merges the behavior of splitSingleBlocks into splitAroundRegion, so the RS_Region and RS_Block register stages can be coalesced. That means the leftover intervals after region splitting go directly to spilling instead of a second pass of per-block splitting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129379 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5d7dcd3335
commit
fd5c51342a
@ -95,8 +95,7 @@ class RAGreedy : public MachineFunctionPass,
|
||||
RS_New, ///< Never seen before.
|
||||
RS_First, ///< First time in the queue.
|
||||
RS_Second, ///< Second time in the queue.
|
||||
RS_Region, ///< Produced by region splitting.
|
||||
RS_Block, ///< Produced by per-block splitting.
|
||||
RS_Global, ///< Produced by global splitting.
|
||||
RS_Local, ///< Produced by local splitting.
|
||||
RS_Spill ///< Produced by spilling.
|
||||
};
|
||||
@ -636,7 +635,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
||||
SE->reset(LREdit);
|
||||
|
||||
// Create the main cross-block interval.
|
||||
SE->openIntv();
|
||||
const unsigned MainIntv = SE->openIntv();
|
||||
|
||||
// First add all defs that are live out of a block.
|
||||
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
|
||||
@ -645,6 +644,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
||||
bool RegIn = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
|
||||
bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
|
||||
|
||||
// Create separate intervals for isolated blocks with multiple uses.
|
||||
if (!RegIn && !RegOut && BI.FirstUse != BI.LastUse) {
|
||||
DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " isolated.\n");
|
||||
SE->splitSingleBlock(BI);
|
||||
SE->selectIntv(MainIntv);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Should the register be live out?
|
||||
if (!BI.LiveOut || !RegOut)
|
||||
continue;
|
||||
@ -894,7 +901,7 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
return 0;
|
||||
|
||||
splitAroundRegion(VirtReg, BestReg, BestBundles, NewVRegs);
|
||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Region);
|
||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1185,30 +1192,25 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
||||
|
||||
// Don't iterate global splitting.
|
||||
// Move straight to spilling if this range was produced by a global split.
|
||||
LiveRangeStage Stage = getStage(VirtReg);
|
||||
if (Stage >= RS_Block)
|
||||
if (getStage(VirtReg) >= RS_Global)
|
||||
return 0;
|
||||
|
||||
SA->analyze(&VirtReg);
|
||||
|
||||
// First try to split around a region spanning multiple blocks.
|
||||
if (Stage < RS_Region) {
|
||||
unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
|
||||
if (PhysReg || !NewVRegs.empty())
|
||||
return PhysReg;
|
||||
}
|
||||
unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
|
||||
if (PhysReg || !NewVRegs.empty())
|
||||
return PhysReg;
|
||||
|
||||
// Then isolate blocks with multiple uses.
|
||||
if (Stage < RS_Block) {
|
||||
SplitAnalysis::BlockPtrSet Blocks;
|
||||
if (SA->getMultiUseBlocks(Blocks)) {
|
||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
|
||||
SE->reset(LREdit);
|
||||
SE->splitSingleBlocks(Blocks);
|
||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Block);
|
||||
if (VerifyEnabled)
|
||||
MF->verify(this, "After splitting live range around basic blocks");
|
||||
}
|
||||
SplitAnalysis::BlockPtrSet Blocks;
|
||||
if (SA->getMultiUseBlocks(Blocks)) {
|
||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
|
||||
SE->reset(LREdit);
|
||||
SE->splitSingleBlocks(Blocks);
|
||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global);
|
||||
if (VerifyEnabled)
|
||||
MF->verify(this, "After splitting live range around basic blocks");
|
||||
}
|
||||
|
||||
// Don't assign any physregs.
|
||||
|
@ -935,6 +935,22 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
||||
return !Blocks.empty();
|
||||
}
|
||||
|
||||
void SplitEditor::splitSingleBlock(const SplitAnalysis::BlockInfo &BI) {
|
||||
openIntv();
|
||||
SlotIndex LastSplitPoint = SA.getLastSplitPoint(BI.MBB->getNumber());
|
||||
SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse,
|
||||
LastSplitPoint));
|
||||
if (!BI.LiveOut || BI.LastUse < LastSplitPoint) {
|
||||
useIntv(SegStart, leaveIntvAfter(BI.LastUse));
|
||||
} else {
|
||||
// The last use is after the last valid split point.
|
||||
SlotIndex SegStop = leaveIntvBefore(LastSplitPoint);
|
||||
useIntv(SegStart, SegStop);
|
||||
overlapIntv(SegStop, BI.LastUse);
|
||||
}
|
||||
closeIntv();
|
||||
}
|
||||
|
||||
/// splitSingleBlocks - Split CurLI into a separate live interval inside each
|
||||
/// basic block in Blocks.
|
||||
void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) {
|
||||
@ -942,22 +958,8 @@ void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) {
|
||||
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA.getUseBlocks();
|
||||
for (unsigned i = 0; i != UseBlocks.size(); ++i) {
|
||||
const SplitAnalysis::BlockInfo &BI = UseBlocks[i];
|
||||
if (!Blocks.count(BI.MBB))
|
||||
continue;
|
||||
|
||||
openIntv();
|
||||
SlotIndex LastSplitPoint = SA.getLastSplitPoint(BI.MBB->getNumber());
|
||||
SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse,
|
||||
LastSplitPoint));
|
||||
if (!BI.LiveOut || BI.LastUse < LastSplitPoint) {
|
||||
useIntv(SegStart, leaveIntvAfter(BI.LastUse));
|
||||
} else {
|
||||
// The last use is after the last valid split point.
|
||||
SlotIndex SegStop = leaveIntvBefore(LastSplitPoint);
|
||||
useIntv(SegStart, SegStop);
|
||||
overlapIntv(SegStop, BI.LastUse);
|
||||
}
|
||||
closeIntv();
|
||||
if (Blocks.count(BI.MBB))
|
||||
splitSingleBlock(BI);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
@ -347,6 +347,11 @@ public:
|
||||
|
||||
// ===--- High level methods ---===
|
||||
|
||||
/// splitSingleBlock - Split CurLI into a separate live interval around the
|
||||
/// uses in a single block. This is intended to be used as part of a larger
|
||||
/// split, and doesn't call finish().
|
||||
void splitSingleBlock(const SplitAnalysis::BlockInfo &BI);
|
||||
|
||||
/// splitSingleBlocks - Split CurLI into a separate live interval inside each
|
||||
/// basic block in Blocks.
|
||||
void splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks);
|
||||
|
Loading…
x
Reference in New Issue
Block a user