summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/RegAllocGreedy.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-21 18:38:15 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-21 18:38:15 +0000
commit6a663b8dc8ed475c5d441c87887478e709a781ff (patch)
treec5fdbc7770beeb4cb6a822216328e195e3443d6e /llvm/lib/CodeGen/RegAllocGreedy.cpp
parentd861e8b7bebcb7a36a158955a795b36128033c66 (diff)
downloadbcm5719-llvm-6a663b8dc8ed475c5d441c87887478e709a781ff.tar.gz
bcm5719-llvm-6a663b8dc8ed475c5d441c87887478e709a781ff.zip
Allow allocatable ranges from global live range splitting to be split again.
These intervals are allocatable immediately after splitting, but they may be evicted because of later splitting. This is rare, but when it happens they should be split again. The remainder intervals that cannot be allocated after splitting still move directly to spilling. SplitEditor::finish can optionally provide a mapping from new live intervals back to the original interval indexes returned by openIntv(). Each original interval index can map to multiple new intervals after connected components have been separated. Dead code elimination may also add existing intervals to the list. The reverse mapping allows the SplitEditor client to treat the new intervals differently depending on the split region they came from. llvm-svn: 129925
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocGreedy.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocGreedy.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 9e58ef6d0a4..ef391434289 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -883,12 +883,36 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg,
SE->enterIntvAtEnd(*MBB);
}
- // 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();
++NumGlobalSplits;
+ SmallVector<unsigned, 8> IntvMap;
+ SE->finish(&IntvMap);
+ LRStage.resize(MRI->getNumVirtRegs());
+
+ // Sort out the new intervals created by splitting. We get four kinds:
+ // - Remainder intervals should not be split again.
+ // - Candidate intervals can be assigned to Cand.PhysReg.
+ // - Block-local splits are candidates for local splitting.
+ // - DCE leftovers should go back on the queue.
+ for (unsigned i = 0, e = LREdit.size(); i != e; ++i) {
+ unsigned Reg = LREdit.get(i)->reg;
+
+ // Ignore old intervals from DCE.
+ if (LRStage[Reg] != RS_New)
+ continue;
+
+ // Remainder interval. Don't try splitting again, spill if it doesn't
+ // allocate.
+ if (IntvMap[i] == 0) {
+ LRStage[Reg] = RS_Global;
+ continue;
+ }
+
+ // Other intervals are treated as new. This includes the main interval,
+ // local intervals created for blocks with multiple uses, and anything
+ // created by DCE.
+ }
+
if (VerifyEnabled)
MF->verify(this, "After splitting live range around region");
}
@@ -946,7 +970,6 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
return 0;
splitAroundRegion(VirtReg, GlobalCand[BestCand], NewVRegs);
- setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global);
return 0;
}
OpenPOWER on IntegriCloud