diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-01-12 00:57:44 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-01-12 00:57:44 +0000 |
commit | 6d6132986d2ef14bbf9d76f5acbf2a0bace32d69 (patch) | |
tree | bca3e27f209a1c4b6baefaa64f71a679ab5a703d /lib/CodeGen | |
parent | c7a275245f501e2f68a55af05c75bc9b6b50ec84 (diff) | |
download | external_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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AllocationOrder.h | 15 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 19 |
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. |