[llvm-commits] [llvm] r147726 - /llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Fri Jan 6 23:39:50 PST 2012


Author: stoklund
Date: Sat Jan  7 01:39:50 2012
New Revision: 147726

URL: http://llvm.org/viewvc/llvm-project?rev=147726&view=rev
Log:
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

Modified:
    llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp

Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=147726&r1=147725&r2=147726&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Sat Jan  7 01:39:50 2012
@@ -1431,6 +1431,31 @@
   // 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;





More information about the llvm-commits mailing list