TargetInstrInfo::hasOperandInterlock() is always true, because it is
[oota-llvm.git] / lib / CodeGen / RegAllocLinearScan.cpp
index f43dc4010d7668b4b7c855a7aa97643072ab2236..4c44d9201cb67841b4d21f76cc0334206f656e35 100644 (file)
@@ -23,7 +23,7 @@
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
 #include "Support/STLExtras.h"
-#include "LiveIntervals.h"
+#include "LiveIntervalAnalysis.h"
 #include "PhysRegTracker.h"
 #include "VirtRegMap.h"
 #include <algorithm>
@@ -82,7 +82,7 @@ namespace {
 
         /// initIntervalSets - initializa the four interval sets:
         /// unhandled, fixed, active and inactive
-        void initIntervalSets(LiveIntervals::Intervals& li);
+        void initIntervalSets();
 
         /// processActiveIntervals - expire old intervals and move
         /// non-overlapping ones to the incative list
@@ -146,7 +146,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
     vrm_.reset(new VirtRegMap(*mf_));
     if (!spiller_.get()) spiller_.reset(createSpiller());
 
-    initIntervalSets(li_->getIntervals());
+    initIntervalSets();
 
     linearScan();
 
@@ -193,7 +193,7 @@ void RA::linearScan()
         DEBUG(printIntervals("active", active_.begin(), active_.end()));
         DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
     }
-    numIntervals += li_->getIntervals().size();
+    numIntervals += li_->getNumIntervals();
     efficiency = double(numIterations) / double(numIntervals);
 
     // expire any remaining active intervals
@@ -217,17 +217,16 @@ void RA::linearScan()
     DEBUG(std::cerr << *vrm_);
 }
 
-void RA::initIntervalSets(LiveIntervals::Intervals& li)
+void RA::initIntervalSets()
 {
     assert(unhandled_.empty() && fixed_.empty() &&
            active_.empty() && inactive_.empty() &&
            "interval sets should be empty on initialization");
 
-    for (LiveIntervals::Intervals::iterator i = li.begin(), e = li.end();
-         i != e; ++i) {
-        unhandled_.push(&*i);
-        if (MRegisterInfo::isPhysicalRegister(i->reg))
-            fixed_.push_back(&*i);
+    for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
+        unhandled_.push(&i->second);
+        if (MRegisterInfo::isPhysicalRegister(i->second.reg))
+            fixed_.push_back(&i->second);
     }
 }
 
@@ -404,13 +403,24 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
     assert(MRegisterInfo::isPhysicalRegister(minReg) &&
            "did not choose a register to spill?");
     std::vector<bool> toSpill(mri_->getNumRegs(), false);
+    // we are going to spill minReg and all its aliases
     toSpill[minReg] = true;
     for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
         toSpill[*as] = true;
+
+    // the earliest start of a spilled interval indicates up to where
+    // in handled we need to roll back
     unsigned earliestStart = cur->start();
 
+    // set of spilled vregs (used later to rollback properly)
     std::set<unsigned> spilled;
 
+    // spill live intervals of virtual regs mapped to the physical
+    // register we want to clear (and its aliases). we only spill
+    // those that overlap with the current interval as the rest do not
+    // affect its allocation. we also keep track of the earliest start
+    // of all spilled live intervals since this will mark our rollback
+    // point
     for (IntervalPtrs::iterator
              i = active_.begin(); i != active_.end(); ++i) {
         unsigned reg = (*i)->reg;
@@ -443,8 +453,9 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
     }
 
     DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
-    // scan handled in reverse order and undo each one, restoring the
-    // state of unhandled
+    // scan handled in reverse order up to the earliaset start of a
+    // spilled live interval and undo each one, restoring the state of
+    // unhandled
     while (!handled_.empty()) {
         LiveInterval* i = handled_.back();
         // if this interval starts before t we are done
@@ -452,6 +463,9 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
             break;
         DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
         handled_.pop_back();
+        // when undoing a live interval allocation we must know if it
+        // is active or inactive to properly update the PhysRegTracker
+        // and the VirtRegMap
         IntervalPtrs::iterator it;
         if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) {
             active_.erase(it);