aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocGreedy.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-06 21:32:38 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-06 21:32:38 +0000
commit1b400e840f58489c7950f815780cf08917cecaa8 (patch)
tree58fed93ac6c86f86f13b55f3807ece18c7891cfc /lib/CodeGen/RegAllocGreedy.cpp
parentb0923771c90070d91d685a20f2e774754365a27c (diff)
Abort the constraint calculation early when all positive bias is lost.
Without any positive bias, there is nothing for the spill placer to to. It will spill everywhere. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129029 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocGreedy.cpp')
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp96
1 files changed, 63 insertions, 33 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 31729ec441..66ef62b1e9 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -169,7 +169,7 @@ private:
void LRE_WillShrinkVirtReg(unsigned);
void LRE_DidCloneVirtReg(unsigned, unsigned);
- float calcSplitConstraints(unsigned);
+ bool addSplitConstraints(unsigned, float&);
float calcGlobalSplitCost(const BitVector&);
void splitAroundRegion(LiveInterval&, unsigned, const BitVector&,
SmallVectorImpl<LiveInterval*>&);
@@ -409,10 +409,12 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
// Region Splitting
//===----------------------------------------------------------------------===//
-/// calcSplitConstraints - Fill out the SplitConstraints vector based on the
-/// interference pattern in Physreg and its aliases. Return the static cost of
-/// this split, assuming that all preferences in SplitConstraints are met.
-float RAGreedy::calcSplitConstraints(unsigned PhysReg) {
+/// addSplitConstraints - Fill out the SplitConstraints vector based on the
+/// interference pattern in Physreg and its aliases. Add the constraints to
+/// SpillPlacement and return the static cost of this split in Cost, assuming
+/// that all preferences in SplitConstraints are met.
+/// If it is evident that no bundles will be live, abort early and return false.
+bool RAGreedy::addSplitConstraints(unsigned PhysReg, float &Cost) {
InterferenceCache::Cursor Intf(IntfCache, PhysReg);
ArrayRef<SplitAnalysis::BlockInfo> UseBlocks = SA->getUseBlocks();
@@ -459,33 +461,58 @@ float RAGreedy::calcSplitConstraints(unsigned PhysReg) {
StaticCost += Ins * SpillPlacer->getBlockFrequency(BC.Number);
}
- // Now handle the live-through blocks without uses.
- ArrayRef<unsigned> ThroughBlocks = SA->getThroughBlocks();
- SplitConstraints.resize(UseBlocks.size() + ThroughBlocks.size());
- for (unsigned i = 0; i != ThroughBlocks.size(); ++i) {
- SpillPlacement::BlockConstraint &BC = SplitConstraints[UseBlocks.size()+i];
- BC.Number = ThroughBlocks[i];
- BC.Entry = SpillPlacement::DontCare;
- BC.Exit = SpillPlacement::DontCare;
+ // Add constraints for use-blocks. Note that these are the only constraints
+ // that may add a positive bias, it is downhill from here.
+ SpillPlacer->addConstraints(SplitConstraints);
+ if (SpillPlacer->getPositiveNodes() == 0)
+ return false;
- Intf.moveToBlock(BC.Number);
- if (!Intf.hasInterference())
- continue;
+ Cost = StaticCost;
- // Interference for the live-in value.
- if (Intf.first() <= Indexes->getMBBStartIdx(BC.Number))
- BC.Entry = SpillPlacement::MustSpill;
- else
- BC.Entry = SpillPlacement::PrefSpill;
+ // Now handle the live-through blocks without uses. These can only add
+ // negative bias, so we can abort whenever there are no more positive nodes.
+ // Compute constraints for a group of 8 blocks at a time.
+ const unsigned GroupSize = 8;
+ SpillPlacement::BlockConstraint BCS[GroupSize];
+ unsigned B = 0;
- // Interference for the live-out value.
- if (Intf.last() >= SA->getLastSplitPoint(BC.Number))
- BC.Exit = SpillPlacement::MustSpill;
- else
- BC.Exit = SpillPlacement::PrefSpill;
+ ArrayRef<unsigned> ThroughBlocks = SA->getThroughBlocks();
+ for (unsigned i = 0; i != ThroughBlocks.size(); ++i) {
+ unsigned Number = ThroughBlocks[i];
+ assert(B < GroupSize && "Array overflow");
+ BCS[B].Number = Number;
+ Intf.moveToBlock(Number);
+
+ if (Intf.hasInterference()) {
+ // Interference for the live-in value.
+ if (Intf.first() <= Indexes->getMBBStartIdx(Number))
+ BCS[B].Entry = SpillPlacement::MustSpill;
+ else
+ BCS[B].Entry = SpillPlacement::PrefSpill;
+
+ // Interference for the live-out value.
+ if (Intf.last() >= SA->getLastSplitPoint(Number))
+ BCS[B].Exit = SpillPlacement::MustSpill;
+ else
+ BCS[B].Exit = SpillPlacement::PrefSpill;
+ } else {
+ // No interference, transparent block.
+ BCS[B].Entry = BCS[B].Exit = SpillPlacement::DontCare;
+ }
+
+ if (++B == GroupSize) {
+ ArrayRef<SpillPlacement::BlockConstraint> Array(BCS, B);
+ SpillPlacer->addConstraints(Array);
+ B = 0;
+ // Abort early when all hope is lost.
+ if (SpillPlacer->getPositiveNodes() == 0)
+ return false;
+ }
}
- return StaticCost;
+ ArrayRef<SpillPlacement::BlockConstraint> Array(BCS, B);
+ SpillPlacer->addConstraints(Array);
+ return SpillPlacer->getPositiveNodes() != 0;
}
@@ -763,16 +790,19 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
GlobalCand.resize(Cand+1);
GlobalCand[Cand].PhysReg = PhysReg;
- float Cost = calcSplitConstraints(PhysReg);
- DEBUG(dbgs() << PrintReg(PhysReg, TRI) << "\tstatic = " << Cost);
+ SpillPlacer->prepare(LiveBundles);
+ float Cost;
+ if (!addSplitConstraints(PhysReg, Cost)) {
+ DEBUG(dbgs() << PrintReg(PhysReg, TRI) << "\tno positive bias\n");
+ continue;
+ }
+ DEBUG(dbgs() << PrintReg(PhysReg, TRI) << "\tbiased = "
+ << SpillPlacer->getPositiveNodes() << ", static = " << Cost);
if (BestReg && Cost >= BestCost) {
- DEBUG(dbgs() << " higher.\n");
+ DEBUG(dbgs() << " worse than " << PrintReg(BestReg, TRI) << '\n');
continue;
}
- SpillPlacer->prepare(LiveBundles);
- SpillPlacer->addConstraints(SplitConstraints);
- DEBUG(dbgs() << ", " << SpillPlacer->getPositiveNodes() << " biased nodes");
SpillPlacer->finish();
// No live bundles, defer to splitSingleBlocks().