mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-26 18:20:39 +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:
@@ -95,8 +95,7 @@ class RAGreedy : public MachineFunctionPass,
|
|||||||
RS_New, ///< Never seen before.
|
RS_New, ///< Never seen before.
|
||||||
RS_First, ///< First time in the queue.
|
RS_First, ///< First time in the queue.
|
||||||
RS_Second, ///< Second time in the queue.
|
RS_Second, ///< Second time in the queue.
|
||||||
RS_Region, ///< Produced by region splitting.
|
RS_Global, ///< Produced by global splitting.
|
||||||
RS_Block, ///< Produced by per-block splitting.
|
|
||||||
RS_Local, ///< Produced by local splitting.
|
RS_Local, ///< Produced by local splitting.
|
||||||
RS_Spill ///< Produced by spilling.
|
RS_Spill ///< Produced by spilling.
|
||||||
};
|
};
|
||||||
@@ -636,7 +635,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
SE->reset(LREdit);
|
SE->reset(LREdit);
|
||||||
|
|
||||||
// Create the main cross-block interval.
|
// Create the main cross-block interval.
|
||||||
SE->openIntv();
|
const unsigned MainIntv = SE->openIntv();
|
||||||
|
|
||||||
// First add all defs that are live out of a block.
|
// First add all defs that are live out of a block.
|
||||||
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
|
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 RegIn = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)];
|
||||||
bool RegOut = LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)];
|
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?
|
// Should the register be live out?
|
||||||
if (!BI.LiveOut || !RegOut)
|
if (!BI.LiveOut || !RegOut)
|
||||||
continue;
|
continue;
|
||||||
@@ -894,7 +901,7 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
splitAroundRegion(VirtReg, BestReg, BestBundles, NewVRegs);
|
splitAroundRegion(VirtReg, BestReg, BestBundles, NewVRegs);
|
||||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Region);
|
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,30 +1192,25 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||||||
|
|
||||||
// Don't iterate global splitting.
|
// Don't iterate global splitting.
|
||||||
// Move straight to spilling if this range was produced by a global split.
|
// Move straight to spilling if this range was produced by a global split.
|
||||||
LiveRangeStage Stage = getStage(VirtReg);
|
if (getStage(VirtReg) >= RS_Global)
|
||||||
if (Stage >= RS_Block)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SA->analyze(&VirtReg);
|
SA->analyze(&VirtReg);
|
||||||
|
|
||||||
// First try to split around a region spanning multiple blocks.
|
// First try to split around a region spanning multiple blocks.
|
||||||
if (Stage < RS_Region) {
|
unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
|
||||||
unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
|
if (PhysReg || !NewVRegs.empty())
|
||||||
if (PhysReg || !NewVRegs.empty())
|
return PhysReg;
|
||||||
return PhysReg;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then isolate blocks with multiple uses.
|
// Then isolate blocks with multiple uses.
|
||||||
if (Stage < RS_Block) {
|
SplitAnalysis::BlockPtrSet Blocks;
|
||||||
SplitAnalysis::BlockPtrSet Blocks;
|
if (SA->getMultiUseBlocks(Blocks)) {
|
||||||
if (SA->getMultiUseBlocks(Blocks)) {
|
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
|
||||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, this);
|
SE->reset(LREdit);
|
||||||
SE->reset(LREdit);
|
SE->splitSingleBlocks(Blocks);
|
||||||
SE->splitSingleBlocks(Blocks);
|
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global);
|
||||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Block);
|
if (VerifyEnabled)
|
||||||
if (VerifyEnabled)
|
MF->verify(this, "After splitting live range around basic blocks");
|
||||||
MF->verify(this, "After splitting live range around basic blocks");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't assign any physregs.
|
// Don't assign any physregs.
|
||||||
|
|||||||
@@ -935,6 +935,22 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
|||||||
return !Blocks.empty();
|
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
|
/// splitSingleBlocks - Split CurLI into a separate live interval inside each
|
||||||
/// basic block in Blocks.
|
/// basic block in Blocks.
|
||||||
void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &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();
|
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA.getUseBlocks();
|
||||||
for (unsigned i = 0; i != UseBlocks.size(); ++i) {
|
for (unsigned i = 0; i != UseBlocks.size(); ++i) {
|
||||||
const SplitAnalysis::BlockInfo &BI = UseBlocks[i];
|
const SplitAnalysis::BlockInfo &BI = UseBlocks[i];
|
||||||
if (!Blocks.count(BI.MBB))
|
if (Blocks.count(BI.MBB))
|
||||||
continue;
|
splitSingleBlock(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();
|
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -347,6 +347,11 @@ public:
|
|||||||
|
|
||||||
// ===--- High level methods ---===
|
// ===--- 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
|
/// splitSingleBlocks - Split CurLI into a separate live interval inside each
|
||||||
/// basic block in Blocks.
|
/// basic block in Blocks.
|
||||||
void splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks);
|
void splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks);
|
||||||
|
|||||||
Reference in New Issue
Block a user