[llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Aug 22 13:59:42 PDT 2005



Changes in directory llvm/lib/CodeGen:

RegAllocLinearScan.cpp updated: 1.110 -> 1.111
---
Log message:

Try to avoid scanning the fixed list.  On architectures with a non-stupid
number of regs (e.g. most riscs), many functions won't need to use callee
clobbered registers.  Do a speculative check to see if we can get a free
register without processing the fixed list (which has all of these).  This
saves a lot of time on machines with lots of callee clobbered regs (e.g.
ppc and itanium, also x86).

This reduces ppc llc compile time from 184s -> 172s on kc++.  This is probably
worth FAR FAR more on itanium though.



---
Diffs of the changes:  (+55 -20)

 RegAllocLinearScan.cpp |   75 +++++++++++++++++++++++++++++++++++--------------
 1 files changed, 55 insertions(+), 20 deletions(-)


Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.110 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.111
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.110	Mon Aug 22 15:20:42 2005
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Mon Aug 22 15:59:30 2005
@@ -381,29 +381,64 @@
       SpillWeightsToAdd.push_back(std::make_pair(reg, i->first->weight));
     }
   }
-
-  // For every interval in fixed we overlap with, mark the register as not free
-  // and update spill weights.
-  for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
-    IntervalPtr &IP = fixed_[i];
-    LiveInterval *I = IP.first;
-    if (I->endNumber() > StartPosition) {
-      LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
-      IP.second = II;
-      if (II != I->begin() && II->start > StartPosition)
-        --II;
-      if (cur->overlapsFrom(*I, II)) {
-        unsigned reg = I->reg;
-        prt_->addRegUse(reg);
-        SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
+  
+  // Speculatively check to see if we can get a register right now.  If not,
+  // we know we won't be able to by adding more constraints.  If so, we can
+  // check to see if it is valid.  Doing an exhaustive search of the fixed_ list
+  // is very bad (it contains all callee clobbered registers for any functions
+  // with a call), so we want to avoid doing that if possible.
+  unsigned physReg = getFreePhysReg(cur);
+  if (physReg) {
+    // We got a register.  However, if it's in the fixed_ list, we might
+    // conflict with it.  Check to see if we conflict with it.
+    bool ConflictsWithFixed = false;
+    for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
+      if (physReg == fixed_[i].first->reg) {
+        // Okay, this reg is on the fixed list.  Check to see if we actually
+        // conflict.
+        IntervalPtr &IP = fixed_[i];
+        LiveInterval *I = IP.first;
+        if (I->endNumber() > StartPosition) {
+          LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
+          IP.second = II;
+          if (II != I->begin() && II->start > StartPosition)
+            --II;
+          if (cur->overlapsFrom(*I, II))
+            ConflictsWithFixed = true;
+        }
+  
+        break;
       }
     }
-  }
+    
+    // Okay, the register picked by our speculative getFreePhysReg call turned
+    // out to be in use.  Actually add all of the conflicting fixed registers to
+    // prt so we can do an accurate query.
+    if (ConflictsWithFixed) {
+      // For every interval in fixed we overlap with, mark the register as not free
+      // and update spill weights.
+      for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
+        IntervalPtr &IP = fixed_[i];
+        LiveInterval *I = IP.first;
+        if (I->endNumber() > StartPosition) {
+          LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
+          IP.second = II;
+          if (II != I->begin() && II->start > StartPosition)
+            --II;
+          if (cur->overlapsFrom(*I, II)) {
+            unsigned reg = I->reg;
+            prt_->addRegUse(reg);
+            SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
+          }
+        }
+      }
 
-  // Using the newly updated prt_ object, which includes conflicts in the
-  // future, see if there are any registers available.
-  unsigned physReg = getFreePhysReg(cur);
-  
+      // Using the newly updated prt_ object, which includes conflicts in the
+      // future, see if there are any registers available.
+      physReg = getFreePhysReg(cur);
+    }
+  }
+    
   // Restore the physical register tracker, removing information about the
   // future.
   *prt_ = backupPrt;






More information about the llvm-commits mailing list