summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-07-25 18:35:19 +0000
committerAndrew Trick <atrick@apple.com>2013-07-25 18:35:19 +0000
commit8bb0a251fdab0111f5438d17de42270331c7ad55 (patch)
tree9141551f548209f0a8c0f9b73bd48dd797b4199a /llvm/lib
parent8485257d6d55db47a570914ada461a0ecbffb04a (diff)
downloadbcm5719-llvm-8bb0a251fdab0111f5438d17de42270331c7ad55.tar.gz
bcm5719-llvm-8bb0a251fdab0111f5438d17de42270331c7ad55.zip
Evict local live ranges if they can be reassigned.
The previous change to local live range allocation also suppressed eviction of local ranges. In rare cases, this could result in more expensive register choices. This commit actually revives a feature that I added long ago: check if live ranges can be reassigned before eviction. But now it only happens in rare cases of evicting a local live range because another local live range wants a cheaper register. The benefit is improved code size for some benchmarks on x86 and armv7. I measured no significant compile time increase and performance changes are noise. llvm-svn: 187140
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/RegAllocGreedy.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 55f2fc68a75..79253715c33 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -261,6 +261,7 @@ private:
bool calcCompactRegion(GlobalSplitCandidate&);
void splitAroundRegion(LiveRangeEdit&, ArrayRef<unsigned>);
void calcGapWeights(unsigned, SmallVectorImpl<float>&);
+ unsigned canReassign(LiveInterval &VirtReg, unsigned PhysReg);
bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool);
bool canEvictInterference(LiveInterval&, unsigned, bool, EvictionCost&);
void evictInterference(LiveInterval&, unsigned,
@@ -494,6 +495,31 @@ unsigned RAGreedy::tryAssign(LiveInterval &VirtReg,
// Interference eviction
//===----------------------------------------------------------------------===//
+unsigned RAGreedy::canReassign(LiveInterval &VirtReg, unsigned PrevReg) {
+ AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo);
+ unsigned PhysReg;
+ while ((PhysReg = Order.next())) {
+ if (PhysReg == PrevReg)
+ continue;
+
+ MCRegUnitIterator Units(PhysReg, TRI);
+ for (; Units.isValid(); ++Units) {
+ // Instantiate a "subquery", not to be confused with the Queries array.
+ LiveIntervalUnion::Query subQ(&VirtReg, &Matrix->getLiveUnions()[*Units]);
+ if (subQ.checkInterference())
+ break;
+ }
+ // If no units have interference, break out with the current PhysReg.
+ if (!Units.isValid())
+ break;
+ }
+ if (PhysReg)
+ DEBUG(dbgs() << "can reassign: " << VirtReg << " from "
+ << PrintReg(PrevReg, TRI) << " to " << PrintReg(PhysReg, TRI)
+ << '\n');
+ return PhysReg;
+}
+
/// shouldEvict - determine if A should evict the assigned live range B. The
/// eviction policy defined by this function together with the allocation order
/// defined by enqueue() decides which registers ultimately end up being split
@@ -594,8 +620,10 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, unsigned PhysReg,
// If !MaxCost.isMax(), then we're just looking for a cheap register.
// Evicting another local live range in this case could lead to suboptimal
// coloring.
- if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf))
+ if (!MaxCost.isMax() && IsLocal && LIS->intervalIsInOneMBB(*Intf) &&
+ !canReassign(*Intf, PhysReg)) {
return false;
+ }
// Finally, apply the eviction policy for non-urgent evictions.
if (!shouldEvict(VirtReg, IsHint, *Intf, BreaksHint))
return false;
OpenPOWER on IntegriCloud