From: Jakob Stoklund Olesen Date: Thu, 3 Mar 2011 01:29:13 +0000 (+0000) Subject: Change the SplitEditor interface to a single instance can be shared for multiple... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=bece06f0c6936527e2b1c72d09f7d3a949af9a47;p=oota-llvm.git 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 --- diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index f08041cd6e7..ea20ae08eaf 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -111,6 +111,7 @@ class RAGreedy : public MachineFunctionPass, public RegAllocBase { // splitting state. std::auto_ptr SA; + std::auto_ptr SE; /// All basic blocks where the current register is live. SmallVector SpillConstraints; @@ -699,10 +700,10 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, SmallVector SpillRegs; LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs); - SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit); + SE->reset(LREdit); // Create the main cross-block interval. - SE.openIntv(); + SE->openIntv(); // First add all defs that are live out of a block. 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" << (RegIn ? ", live-through.\n" : ", stack in.\n")); if (!RegIn) - SE.enterIntvAtEnd(*BI.MBB); + SE->enterIntvAtEnd(*BI.MBB); continue; } if (!BI.LiveThrough) { DEBUG(dbgs() << ", not live-through.\n"); - SE.useIntv(SE.enterIntvBefore(BI.Def), Stop); + SE->useIntv(SE->enterIntvBefore(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.useIntv(SE.enterIntvBefore(BI.FirstUse), Stop); + SE->useIntv(SE->enterIntvBefore(BI.FirstUse), Stop); continue; } DEBUG(dbgs() << ", live-through.\n"); @@ -761,7 +762,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.LiveThrough && IP.second <= BI.Def) { // The interference doesn't reach the outgoing segment. DEBUG(dbgs() << " doesn't affect def from " << BI.Def << '\n'); - SE.useIntv(BI.Def, Stop); + SE->useIntv(BI.Def, Stop); continue; } @@ -769,7 +770,7 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.Uses) { // No uses in block, avoid interference by reloading as late as possible. 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"); continue; } @@ -786,17 +787,17 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, // Only attempt a split befroe the last split point. if (Use.getBaseIndex() <= BI.LastSplitPoint) { 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 < BI.LastSplitPoint && "Impossible split point"); - SE.useIntv(SegStart, Stop); + SE->useIntv(SegStart, Stop); continue; } } // Interference is after the last use. 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"); } @@ -827,16 +828,16 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, // Block is live-through without interference. if (RegOut) { DEBUG(dbgs() << ", no uses, live-through.\n"); - SE.useIntv(Start, Stop); + SE->useIntv(Start, Stop); } else { DEBUG(dbgs() << ", no uses, stack-out.\n"); - SE.leaveIntvAtTop(*BI.MBB); + SE->leaveIntvAtTop(*BI.MBB); } continue; } if (!BI.LiveThrough) { DEBUG(dbgs() << ", killed in block.\n"); - SE.useIntv(Start, SE.leaveIntvAfter(BI.Kill)); + SE->useIntv(Start, SE->leaveIntvAfter(BI.Kill)); continue; } if (!RegOut) { @@ -844,24 +845,24 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, // Spill immediately after the last use. if (BI.LastUse < BI.LastSplitPoint) { DEBUG(dbgs() << ", uses, stack-out.\n"); - SE.useIntv(Start, SE.leaveIntvAfter(BI.LastUse)); + SE->useIntv(Start, SE->leaveIntvAfter(BI.LastUse)); continue; } // The last use is after the last split point, it is probably an // indirect jump. DEBUG(dbgs() << ", uses at " << BI.LastUse << " after split point " << BI.LastSplitPoint << ", stack-out.\n"); - SlotIndex SegEnd = SE.leaveIntvBefore(BI.LastSplitPoint); - SE.useIntv(Start, SegEnd); + SlotIndex SegEnd = SE->leaveIntvBefore(BI.LastSplitPoint); + SE->useIntv(Start, SegEnd); // Run a double interval from the split to the last use. // This makes it possible to spill the complement without affecting the // indirect branch. - SE.overlapIntv(SegEnd, BI.LastUse); + SE->overlapIntv(SegEnd, BI.LastUse); continue; } // Register is live-through. DEBUG(dbgs() << ", uses, live-through.\n"); - SE.useIntv(Start, Stop); + SE->useIntv(Start, Stop); continue; } @@ -871,14 +872,14 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, if (!BI.LiveThrough && IP.first >= BI.Kill) { // The interference doesn't reach the outgoing segment. DEBUG(dbgs() << " doesn't affect kill at " << BI.Kill << '\n'); - SE.useIntv(Start, BI.Kill); + SE->useIntv(Start, BI.Kill); continue; } if (!BI.Uses) { // No uses in block, avoid interference by spilling as soon as possible. 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"); continue; } @@ -891,24 +892,24 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned PhysReg, assert(UI != SA->UseSlots.begin() && "Couldn't find first use"); SlotIndex Use = (--UI)->getBoundaryIndex(); 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"); - SE.useIntv(Start, SegEnd); + SE->useIntv(Start, SegEnd); continue; } // Interference is before the first use. 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"); } - SE.closeIntv(); + 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(); + SE->finish(); ++NumGlobalSplits; if (VerifyEnabled) { @@ -1215,14 +1216,14 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, SmallVector SpillRegs; LiveRangeEdit LREdit(VirtReg, NewVRegs, SpillRegs); - SplitEditor SE(*SA, *LIS, *VRM, *DomTree, LREdit); - - SE.openIntv(); - SlotIndex SegStart = SE.enterIntvBefore(Uses[BestBefore]); - SlotIndex SegStop = SE.leaveIntvAfter(Uses[BestAfter]); - SE.useIntv(SegStart, SegStop); - SE.closeIntv(); - SE.finish(); + SE->reset(LREdit); + + SE->openIntv(); + SlotIndex SegStart = SE->enterIntvBefore(Uses[BestBefore]); + SlotIndex SegStop = SE->leaveIntvAfter(Uses[BestAfter]); + SE->useIntv(SegStart, SegStop); + SE->closeIntv(); + SE->finish(); setStage(NewVRegs.begin(), NewVRegs.end(), RS_Local); ++NumLocalSplits; @@ -1268,7 +1269,8 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, if (SA->getMultiUseBlocks(Blocks)) { SmallVector 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); if (VerifyEnabled) MF->verify(this, "After splitting live range around basic blocks"); @@ -1350,6 +1352,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { SpillPlacer = &getAnalysis(); SA.reset(new SplitAnalysis(*VRM, *LIS, *Loops)); + SE.reset(new SplitEditor(*SA, *LIS, *VRM, *DomTree)); LRStage.clear(); LRStage.resize(MRI->getNumVirtRegs()); diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index 9b007a4ac15..017511e20c4 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -209,17 +209,24 @@ void SplitAnalysis::analyze(const LiveInterval *li) { SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm, - MachineDominatorTree &mdt, - LiveRangeEdit &edit) + MachineDominatorTree &mdt) : SA(sa), LIS(lis), VRM(vrm), MRI(vrm.getMachineFunction().getRegInfo()), MDT(mdt), TII(*vrm.getMachineFunction().getTarget().getInstrInfo()), TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()), - Edit(&edit), + Edit(0), OpenIdx(0), 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 // cheap-as-a-copy remats anyway. Edit->anyRematerializable(LIS, TII, 0); diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index 7b303617225..28c5c602d7a 100644 --- a/lib/CodeGen/SplitKit.h +++ b/lib/CodeGen/SplitKit.h @@ -268,10 +268,10 @@ public: /// Create a new SplitEditor for editing the LiveInterval analyzed by SA. /// Newly created intervals will be appended to newIntervals. SplitEditor(SplitAnalysis &SA, LiveIntervals&, VirtRegMap&, - MachineDominatorTree&, LiveRangeEdit&); + MachineDominatorTree&); - /// getAnalysis - Get the corresponding analysis. - SplitAnalysis &getAnalysis() { return SA; } + /// reset - Prepare for a new split. + void reset(LiveRangeEdit&); /// Create a new virtual register and live interval. void openIntv();