Try to avoid scanning the fixed list. On architectures with a non-stupid
authorChris Lattner <sabre@nondot.org>
Mon, 22 Aug 2005 20:59:30 +0000 (20:59 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 22 Aug 2005 20:59:30 +0000 (20:59 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22972 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegAllocLinearScan.cpp

index ce58e59cb55c45524d4220b8a3f2b2ff746e970c..6289754f9ffb8a04cb76f30d15b8b7a031ea116d 100644 (file)
@@ -381,29 +381,64 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
       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;