aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-01-12 00:57:44 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-01-12 00:57:44 +0000
commit6d6132986d2ef14bbf9d76f5acbf2a0bace32d69 (patch)
treebca3e27f209a1c4b6baefaa64f71a679ab5a703d
parentc7a275245f501e2f68a55af05c75bc9b6b50ec84 (diff)
downloadexternal_llvm-6d6132986d2ef14bbf9d76f5acbf2a0bace32d69.zip
external_llvm-6d6132986d2ef14bbf9d76f5acbf2a0bace32d69.tar.gz
external_llvm-6d6132986d2ef14bbf9d76f5acbf2a0bace32d69.tar.bz2
Limit the search space in RAGreedy::tryEvict().
When tryEvict() is looking for a cheaper register in the allocation order, skip the tail of too expensive registers when possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172281 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/AllocationOrder.h15
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp19
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/CodeGen/AllocationOrder.h b/lib/CodeGen/AllocationOrder.h
index a5293f6..aed461a 100644
--- a/lib/CodeGen/AllocationOrder.h
+++ b/lib/CodeGen/AllocationOrder.h
@@ -39,6 +39,9 @@ public:
const VirtRegMap &VRM,
const RegisterClassInfo &RegClassInfo);
+ /// Get the allocation order without reordered hints.
+ ArrayRef<MCPhysReg> getOrder() const { return Order; }
+
/// Return the next physical register in the allocation order, or 0.
/// It is safe to call next() again after it returned 0, it will keep
/// returning 0 until rewind() is called.
@@ -53,6 +56,18 @@ public:
return 0;
}
+ /// As next(), but allow duplicates to be returned, and stop before the
+ /// Limit'th register in the RegisterClassInfo allocation order.
+ ///
+ /// This can produce more than Limit registers if there are hints.
+ unsigned nextWithDups(unsigned Limit) {
+ if (Pos < 0)
+ return Hints.end()[Pos++];
+ if (Pos < int(Limit))
+ return Order[Pos++];
+ return 0;
+ }
+
/// Start over from the beginning.
void rewind() { Pos = -int(Hints.size()); }
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 1884452..6344a73 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -632,16 +632,33 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
// Keep track of the cheapest interference seen so far.
EvictionCost BestCost(~0u);
unsigned BestPhys = 0;
+ unsigned OrderLimit = Order.getOrder().size();
// When we are just looking for a reduced cost per use, don't break any
// hints, and only evict smaller spill weights.
if (CostPerUseLimit < ~0u) {
BestCost.BrokenHints = 0;
BestCost.MaxWeight = VirtReg.weight;
+
+ // Check of any registers in RC are below CostPerUseLimit.
+ const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg);
+ unsigned MinCost = RegClassInfo.getMinCost(RC);
+ if (MinCost >= CostPerUseLimit) {
+ DEBUG(dbgs() << RC->getName() << " minimum cost = " << MinCost
+ << ", no cheaper registers to be found.\n");
+ return 0;
+ }
+
+ // It is normal for register classes to have a long tail of registers with
+ // the same cost. We don't need to look at them if they're too expensive.
+ if (TRI->getCostPerUse(Order.getOrder().back()) >= CostPerUseLimit) {
+ OrderLimit = RegClassInfo.getLastCostChange(RC);
+ DEBUG(dbgs() << "Only trying the first " << OrderLimit << " regs.\n");
+ }
}
Order.rewind();
- while (unsigned PhysReg = Order.next()) {
+ while (unsigned PhysReg = Order.nextWithDups(OrderLimit)) {
if (TRI->getCostPerUse(PhysReg) >= CostPerUseLimit)
continue;
// The first use of a callee-saved register in a function has cost 1.