mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 05:00:26 +00:00
Change the SplitEditor interface to a single instance can be shared for multiple splits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126912 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8701768ae2
commit
bece06f0c6
@ -111,6 +111,7 @@ class RAGreedy : public MachineFunctionPass, public RegAllocBase {
|
|||||||
|
|
||||||
// splitting state.
|
// splitting state.
|
||||||
std::auto_ptr<SplitAnalysis> SA;
|
std::auto_ptr<SplitAnalysis> SA;
|
||||||
|
std::auto_ptr<SplitEditor> SE;
|
||||||
|
|
||||||
/// All basic blocks where the current register is live.
|
/// All basic blocks where the current register is live.
|
||||||
SmallVector<SpillPlacement::BlockConstraint, 8> SpillConstraints;
|
SmallVector<SpillPlacement::BlockConstraint, 8> SpillConstraints;
|
||||||
@ -699,10 +700,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
|
|
||||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
||||||
SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit);
|
SE->reset(LREdit);
|
||||||
|
|
||||||
// Create the main cross-block interval.
|
// Create the main cross-block interval.
|
||||||
SE.openIntv();
|
SE->openIntv();
|
||||||
|
|
||||||
// First add all defs that are live out of a block.
|
// First add all defs that are live out of a block.
|
||||||
for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) {
|
for (unsigned i = 0, e = SA->LiveBlocks.size(); i != e; ++i) {
|
||||||
@ -736,19 +737,19 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
DEBUG(dbgs() << ", no uses"
|
DEBUG(dbgs() << ", no uses"
|
||||||
<< (RegIn ? ", live-through.\n" : ", stack in.\n"));
|
<< (RegIn ? ", live-through.\n" : ", stack in.\n"));
|
||||||
if (!RegIn)
|
if (!RegIn)
|
||||||
SE.enterIntvAtEnd(*BI.MBB);
|
SE->enterIntvAtEnd(*BI.MBB);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!BI.LiveThrough) {
|
if (!BI.LiveThrough) {
|
||||||
DEBUG(dbgs() << ", not live-through.\n");
|
DEBUG(dbgs() << ", not live-through.\n");
|
||||||
SE.useIntv(SE.enterIntvBefore(BI.Def), Stop);
|
SE->useIntv(SE->enterIntvBefore(BI.Def), Stop);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!RegIn) {
|
if (!RegIn) {
|
||||||
// Block is live-through, but entry bundle is on the stack.
|
// Block is live-through, but entry bundle is on the stack.
|
||||||
// Reload just before the first use.
|
// Reload just before the first use.
|
||||||
DEBUG(dbgs() << ", not live-in, enter before first use.\n");
|
DEBUG(dbgs() << ", not live-in, enter before first use.\n");
|
||||||
SE.useIntv(SE.enterIntvBefore(BI.FirstUse), Stop);
|
SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DEBUG(dbgs() << ", live-through.\n");
|
DEBUG(dbgs() << ", live-through.\n");
|
||||||
@ -761,7 +762,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
if (!BI.LiveThrough && IP.second <= BI.Def) {
|
if (!BI.LiveThrough && IP.second <= BI.Def) {
|
||||||
// The interference doesn't reach the outgoing segment.
|
// The interference doesn't reach the outgoing segment.
|
||||||
DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n');
|
DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n');
|
||||||
SE.useIntv(BI.Def, Stop);
|
SE->useIntv(BI.Def, Stop);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +770,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
if (!BI.Uses) {
|
if (!BI.Uses) {
|
||||||
// No uses in block, avoid interference by reloading as late as possible.
|
// No uses in block, avoid interference by reloading as late as possible.
|
||||||
DEBUG(dbgs() << ", no uses.\n");
|
DEBUG(dbgs() << ", no uses.\n");
|
||||||
SlotIndex SegStart = SE.enterIntvAtEnd(*BI.MBB);
|
SlotIndex SegStart = SE->enterIntvAtEnd(*BI.MBB);
|
||||||
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -786,17 +787,17 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
// Only attempt a split befroe the last split point.
|
// Only attempt a split befroe the last split point.
|
||||||
if (Use.getBaseIndex() <= BI.LastSplitPoint) {
|
if (Use.getBaseIndex() <= BI.LastSplitPoint) {
|
||||||
DEBUG(dbgs() << ", free use at " << Use << ".\n");
|
DEBUG(dbgs() << ", free use at " << Use << ".\n");
|
||||||
SlotIndex SegStart = SE.enterIntvBefore(Use);
|
SlotIndex SegStart = SE->enterIntvBefore(Use);
|
||||||
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
||||||
assert(SegStart < BI.LastSplitPoint && "Impossible split point");
|
assert(SegStart < BI.LastSplitPoint && "Impossible split point");
|
||||||
SE.useIntv(SegStart, Stop);
|
SE->useIntv(SegStart, Stop);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interference is after the last use.
|
// Interference is after the last use.
|
||||||
DEBUG(dbgs() << " after last use.\n");
|
DEBUG(dbgs() << " after last use.\n");
|
||||||
SlotIndex SegStart = SE.enterIntvAtEnd(*BI.MBB);
|
SlotIndex SegStart = SE->enterIntvAtEnd(*BI.MBB);
|
||||||
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
assert(SegStart >= IP.second && "Couldn't avoid interference");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,16 +828,16 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
// Block is live-through without interference.
|
// Block is live-through without interference.
|
||||||
if (RegOut) {
|
if (RegOut) {
|
||||||
DEBUG(dbgs() << ", no uses, live-through.\n");
|
DEBUG(dbgs() << ", no uses, live-through.\n");
|
||||||
SE.useIntv(Start, Stop);
|
SE->useIntv(Start, Stop);
|
||||||
} else {
|
} else {
|
||||||
DEBUG(dbgs() << ", no uses, stack-out.\n");
|
DEBUG(dbgs() << ", no uses, stack-out.\n");
|
||||||
SE.leaveIntvAtTop(*BI.MBB);
|
SE->leaveIntvAtTop(*BI.MBB);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!BI.LiveThrough) {
|
if (!BI.LiveThrough) {
|
||||||
DEBUG(dbgs() << ", killed in block.\n");
|
DEBUG(dbgs() << ", killed in block.\n");
|
||||||
SE.useIntv(Start, SE.leaveIntvAfter(BI.Kill));
|
SE->useIntv(Start, SE->leaveIntvAfter(BI.Kill));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!RegOut) {
|
if (!RegOut) {
|
||||||
@ -844,24 +845,24 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
// Spill immediately after the last use.
|
// Spill immediately after the last use.
|
||||||
if (BI.LastUse < BI.LastSplitPoint) {
|
if (BI.LastUse < BI.LastSplitPoint) {
|
||||||
DEBUG(dbgs() << ", uses, stack-out.\n");
|
DEBUG(dbgs() << ", uses, stack-out.\n");
|
||||||
SE.useIntv(Start, SE.leaveIntvAfter(BI.LastUse));
|
SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// The last use is after the last split point, it is probably an
|
// The last use is after the last split point, it is probably an
|
||||||
// indirect jump.
|
// indirect jump.
|
||||||
DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point "
|
DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point "
|
||||||
<< BI.LastSplitPoint << ", stack-out.\n");
|
<< BI.LastSplitPoint << ", stack-out.\n");
|
||||||
SlotIndex SegEnd = SE.leaveIntvBefore(BI.LastSplitPoint);
|
SlotIndex SegEnd = SE->leaveIntvBefore(BI.LastSplitPoint);
|
||||||
SE.useIntv(Start, SegEnd);
|
SE->useIntv(Start, SegEnd);
|
||||||
// Run a double interval from the split to the last use.
|
// Run a double interval from the split to the last use.
|
||||||
// This makes it possible to spill the complement without affecting the
|
// This makes it possible to spill the complement without affecting the
|
||||||
// indirect branch.
|
// indirect branch.
|
||||||
SE.overlapIntv(SegEnd, BI.LastUse);
|
SE->overlapIntv(SegEnd, BI.LastUse);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Register is live-through.
|
// Register is live-through.
|
||||||
DEBUG(dbgs() << ", uses, live-through.\n");
|
DEBUG(dbgs() << ", uses, live-through.\n");
|
||||||
SE.useIntv(Start, Stop);
|
SE->useIntv(Start, Stop);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,14 +872,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
if (!BI.LiveThrough && IP.first >= BI.Kill) {
|
if (!BI.LiveThrough && IP.first >= BI.Kill) {
|
||||||
// The interference doesn't reach the outgoing segment.
|
// The interference doesn't reach the outgoing segment.
|
||||||
DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n');
|
DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n');
|
||||||
SE.useIntv(Start, BI.Kill);
|
SE->useIntv(Start, BI.Kill);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BI.Uses) {
|
if (!BI.Uses) {
|
||||||
// No uses in block, avoid interference by spilling as soon as possible.
|
// No uses in block, avoid interference by spilling as soon as possible.
|
||||||
DEBUG(dbgs() << ", no uses.\n");
|
DEBUG(dbgs() << ", no uses.\n");
|
||||||
SlotIndex SegEnd = SE.leaveIntvAtTop(*BI.MBB);
|
SlotIndex SegEnd = SE->leaveIntvAtTop(*BI.MBB);
|
||||||
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -891,24 +892,24 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg,
|
|||||||
assert(UI != SA->UseSlots.begin() && "Couldn't find first use");
|
assert(UI != SA->UseSlots.begin() && "Couldn't find first use");
|
||||||
SlotIndex Use = (--UI)->getBoundaryIndex();
|
SlotIndex Use = (--UI)->getBoundaryIndex();
|
||||||
DEBUG(dbgs() << ", free use at " << *UI << ".\n");
|
DEBUG(dbgs() << ", free use at " << *UI << ".\n");
|
||||||
SlotIndex SegEnd = SE.leaveIntvAfter(Use);
|
SlotIndex SegEnd = SE->leaveIntvAfter(Use);
|
||||||
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
||||||
SE.useIntv(Start, SegEnd);
|
SE->useIntv(Start, SegEnd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interference is before the first use.
|
// Interference is before the first use.
|
||||||
DEBUG(dbgs() << " before first use.\n");
|
DEBUG(dbgs() << " before first use.\n");
|
||||||
SlotIndex SegEnd = SE.leaveIntvAtTop(*BI.MBB);
|
SlotIndex SegEnd = SE->leaveIntvAtTop(*BI.MBB);
|
||||||
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
assert(SegEnd <= IP.first && "Couldn't avoid interference");
|
||||||
}
|
}
|
||||||
|
|
||||||
SE.closeIntv();
|
SE->closeIntv();
|
||||||
|
|
||||||
// FIXME: Should we be more aggressive about splitting the stack region into
|
// FIXME: Should we be more aggressive about splitting the stack region into
|
||||||
// per-block segments? The current approach allows the stack region to
|
// per-block segments? The current approach allows the stack region to
|
||||||
// separate into connected components. Some components may be allocatable.
|
// separate into connected components. Some components may be allocatable.
|
||||||
SE.finish();
|
SE->finish();
|
||||||
++NumGlobalSplits;
|
++NumGlobalSplits;
|
||||||
|
|
||||||
if (VerifyEnabled) {
|
if (VerifyEnabled) {
|
||||||
@ -1215,14 +1216,14 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||||||
|
|
||||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
||||||
SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit);
|
SE->reset(LREdit);
|
||||||
|
|
||||||
SE.openIntv();
|
SE->openIntv();
|
||||||
SlotIndex SegStart = SE.enterIntvBefore(Uses[BestBefore]);
|
SlotIndex SegStart = SE->enterIntvBefore(Uses[BestBefore]);
|
||||||
SlotIndex SegStop = SE.leaveIntvAfter(Uses[BestAfter]);
|
SlotIndex SegStop = SE->leaveIntvAfter(Uses[BestAfter]);
|
||||||
SE.useIntv(SegStart, SegStop);
|
SE->useIntv(SegStart, SegStop);
|
||||||
SE.closeIntv();
|
SE->closeIntv();
|
||||||
SE.finish();
|
SE->finish();
|
||||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Local);
|
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Local);
|
||||||
++NumLocalSplits;
|
++NumLocalSplits;
|
||||||
|
|
||||||
@ -1268,7 +1269,8 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order,
|
|||||||
if (SA->getMultiUseBlocks(Blocks)) {
|
if (SA->getMultiUseBlocks(Blocks)) {
|
||||||
SmallVector<LiveInterval*, 4> SpillRegs;
|
SmallVector<LiveInterval*, 4> SpillRegs;
|
||||||
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs);
|
||||||
SplitEditor(*SA, *LIS, *VRM, *DomTree, LREdit).splitSingleBlocks(Blocks);
|
SE->reset(LREdit);
|
||||||
|
SE->splitSingleBlocks(Blocks);
|
||||||
setStage(NewVRegs.begin(), NewVRegs.end(), RS_Block);
|
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");
|
||||||
@ -1350,6 +1352,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
SpillPlacer = &getAnalysis<SpillPlacement>();
|
SpillPlacer = &getAnalysis<SpillPlacement>();
|
||||||
|
|
||||||
SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops));
|
SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops));
|
||||||
|
SE.reset(new SplitEditor(*SA, *LIS, *VRM, *DomTree));
|
||||||
LRStage.clear();
|
LRStage.clear();
|
||||||
LRStage.resize(MRI->getNumVirtRegs());
|
LRStage.resize(MRI->getNumVirtRegs());
|
||||||
|
|
||||||
|
@ -209,17 +209,24 @@ void SplitAnalysis::analyze(const LiveInterval *li) {
|
|||||||
SplitEditor::SplitEditor(SplitAnalysis &sa,
|
SplitEditor::SplitEditor(SplitAnalysis &sa,
|
||||||
LiveIntervals &lis,
|
LiveIntervals &lis,
|
||||||
VirtRegMap &vrm,
|
VirtRegMap &vrm,
|
||||||
MachineDominatorTree &mdt,
|
MachineDominatorTree &mdt)
|
||||||
LiveRangeEdit &edit)
|
|
||||||
: SA(sa), LIS(lis), VRM(vrm),
|
: SA(sa), LIS(lis), VRM(vrm),
|
||||||
MRI(vrm.getMachineFunction().getRegInfo()),
|
MRI(vrm.getMachineFunction().getRegInfo()),
|
||||||
MDT(mdt),
|
MDT(mdt),
|
||||||
TII(*vrm.getMachineFunction().getTarget().getInstrInfo()),
|
TII(*vrm.getMachineFunction().getTarget().getInstrInfo()),
|
||||||
TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()),
|
TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()),
|
||||||
Edit(&edit),
|
Edit(0),
|
||||||
OpenIdx(0),
|
OpenIdx(0),
|
||||||
RegAssign(Allocator)
|
RegAssign(Allocator)
|
||||||
{
|
{}
|
||||||
|
|
||||||
|
void SplitEditor::reset(LiveRangeEdit &lre) {
|
||||||
|
Edit = &lre;
|
||||||
|
OpenIdx = 0;
|
||||||
|
RegAssign.clear();
|
||||||
|
Values.clear();
|
||||||
|
LiveOutCache.clear();
|
||||||
|
|
||||||
// We don't need an AliasAnalysis since we will only be performing
|
// We don't need an AliasAnalysis since we will only be performing
|
||||||
// cheap-as-a-copy remats anyway.
|
// cheap-as-a-copy remats anyway.
|
||||||
Edit->anyRematerializable(LIS, TII, 0);
|
Edit->anyRematerializable(LIS, TII, 0);
|
||||||
|
@ -268,10 +268,10 @@ public:
|
|||||||
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
|
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
|
||||||
/// Newly created intervals will be appended to newIntervals.
|
/// Newly created intervals will be appended to newIntervals.
|
||||||
SplitEditor(SplitAnalysis &SA, LiveIntervals&, VirtRegMap&,
|
SplitEditor(SplitAnalysis &SA, LiveIntervals&, VirtRegMap&,
|
||||||
MachineDominatorTree&, LiveRangeEdit&);
|
MachineDominatorTree&);
|
||||||
|
|
||||||
/// getAnalysis - Get the corresponding analysis.
|
/// reset - Prepare for a new split.
|
||||||
SplitAnalysis &getAnalysis() { return SA; }
|
void reset(LiveRangeEdit&);
|
||||||
|
|
||||||
/// Create a new virtual register and live interval.
|
/// Create a new virtual register and live interval.
|
||||||
void openIntv();
|
void openIntv();
|
||||||
|
Loading…
Reference in New Issue
Block a user