summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-07 07:39:50 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-07 07:39:50 +0000
commit434fb37bb4a1025eca9f0179d71cd3a711829c40 (patch)
tree3d6b16f6c6d8d6fb2a839223c72f08479ae05130 /llvm/lib
parenta8879087b5d5de48a8c07f8cc6742b4f2509bbab (diff)
downloadbcm5719-llvm-434fb37bb4a1025eca9f0179d71cd3a711829c40.tar.gz
bcm5719-llvm-434fb37bb4a1025eca9f0179d71cd3a711829c40.zip
Optimize reserved register coalescing.
Reserved registers don't have proper live ranges, their LiveInterval simply has a snippet of liveness for each def. Virtual registers with a single value that is a copy of a reserved register (typically %esp) can be coalesced with the reserved register if the live range doesn't overlap any reserved register defs. When coalescing with a reserved register, don't modify the reserved register live range. Just leave it as a bunch of dead defs. This eliminates quadratic coalescer behavior in i386 functions with many function calls. PR11699 llvm-svn: 147726
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 7dd070ca1d3..bb5e65e8aa5 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -1431,6 +1431,31 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) {
// than the full interfeence check below. We allow overlapping live ranges
// only when one is a copy of the other.
if (CP.isPhys()) {
+ // Optimization for reserved registers like ESP.
+ // We can only merge with a reserved physreg if RHS has a single value that
+ // is a copy of CP.DstReg(). The live range of the reserved register will
+ // look like a set of dead defs - we don't properly track the live range of
+ // reserved registers.
+ if (RegClassInfo.isReserved(CP.getDstReg())) {
+ assert(CP.isFlipped() && RHS.containsOneValue() &&
+ "Invalid join with reserved register");
+ // Deny any overlapping intervals. This depends on all the reserved
+ // register live ranges to look like dead defs.
+ for (const unsigned *AS = TRI->getOverlaps(CP.getDstReg()); *AS; ++AS) {
+ if (!LIS->hasInterval(*AS))
+ continue;
+ if (RHS.overlaps(LIS->getInterval(*AS))) {
+ DEBUG(dbgs() << "\t\tInterference: " << PrintReg(*AS, TRI) << '\n');
+ return false;
+ }
+ }
+ // Skip any value computations, we are not adding new values to the
+ // reserved register. Also skip merging the live ranges, the reserved
+ // register live range doesn't need to be accurate as long as all the
+ // defs are there.
+ return true;
+ }
+
for (const unsigned *AS = TRI->getAliasSet(CP.getDstReg()); *AS; ++AS){
if (!LIS->hasInterval(*AS))
continue;
OpenPOWER on IntegriCloud