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

Alkis Evlogimenos alkis at cs.uiuc.edu
Sun May 30 02:28:02 PDT 2004


Changes in directory llvm/lib/CodeGen:

RegAllocLinearScan.cpp updated: 1.72 -> 1.73
LiveIntervals.h updated: 1.24 -> 1.25
LiveIntervals.cpp updated: 1.74 -> 1.75

---
Log message:

When spilling an register, introduce a new temporary for each of its
spills. This allows for more flexibility when allocating registers for
spill code.


---
Diffs of the changes:  (+83 -56)

Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.72 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.73
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.72	Fri May  7 22:50:03 2004
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Sun May 30 02:24:39 2004
@@ -27,6 +27,7 @@
 #include <algorithm>
 #include <cmath>
 #include <iostream>
+#include <set>
 
 using namespace llvm;
 
@@ -366,24 +367,26 @@
     DEBUG(std::cerr << "\t\tregister with min weight: "
           << mri_->getName(minReg) << " (" << minWeight << ")\n");
 
-    // if the current has the minimum weight, we need to modify it,
-    // push it back in unhandled and let the linear scan algorithm run
-    // again
+    // if the current has the minimum weight, we need to spill it and
+    // add any added intervals back to unhandled, and restart
+    // linearscan.
     if (cur->weight <= minWeight) {
         DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
         int slot = vrm_->assignVirt2StackSlot(cur->reg);
-        li_->updateSpilledInterval(*cur, *vrm_, slot);
+        std::vector<LiveIntervals::Interval*> added =
+            li_->addIntervalsForSpills(*cur, *vrm_, slot);
 
-        // if we didn't eliminate the interval find where to add it
-        // back to unhandled. We need to scan since unhandled are
-        // sorted on earliest start point and we may have changed our
-        // start point.
-        if (!cur->empty()) {
-            IntervalPtrs::iterator it = unhandled_.begin();
-            while (it != unhandled_.end() && (*it)->start() < cur->start())
-                ++it;
-            unhandled_.insert(it, cur);
+        // merge added with unhandled
+        std::vector<LiveIntervals::Interval*>::iterator addedIt = added.begin();
+        std::vector<LiveIntervals::Interval*>::iterator addedItEnd = added.end();
+        for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end();
+             i != e && addedIt != addedItEnd; ++i) {
+            if ((*i)->start() > (*addedIt)->start())
+                i = unhandled_.insert(i, *(addedIt++));
         }
+        while (addedIt != addedItEnd)
+            unhandled_.push_back(*(addedIt++));
+
         return;
     }
 
@@ -395,6 +398,7 @@
     // otherwise we spill all intervals aliasing the register with
     // minimum weight, rollback to the interval with the earliest
     // start point and let the linear scan algorithm run again
+    std::vector<LiveIntervals::Interval*> added;
     assert(MRegisterInfo::isPhysicalRegister(minReg) &&
            "did not choose a register to spill?");
     std::vector<bool> toSpill(mri_->getNumRegs(), false);
@@ -403,6 +407,8 @@
         toSpill[*as] = true;
     unsigned earliestStart = cur->start();
 
+    std::set<unsigned> spilled;
+
     for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
         unsigned reg = (*i)->reg;
         if (MRegisterInfo::isVirtualRegister(reg) &&
@@ -411,7 +417,10 @@
             DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
             earliestStart = std::min(earliestStart, (*i)->start());
             int slot = vrm_->assignVirt2StackSlot((*i)->reg);
-            li_->updateSpilledInterval(**i, *vrm_, slot);
+            std::vector<LiveIntervals::Interval*> newIs =
+                li_->addIntervalsForSpills(**i, *vrm_, slot);
+            std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+            spilled.insert(reg);
         }
     }
     for (IntervalPtrs::iterator i = inactive_.begin();
@@ -423,7 +432,10 @@
             DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
             earliestStart = std::min(earliestStart, (*i)->start());
             int slot = vrm_->assignVirt2StackSlot((*i)->reg);
-            li_->updateSpilledInterval(**i, *vrm_, slot);
+            std::vector<LiveIntervals::Interval*> newIs =
+                li_->addIntervalsForSpills(**i, *vrm_, slot);
+            std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+            spilled.insert(reg);
         }
     }
 
@@ -433,7 +445,7 @@
     while (!handled_.empty()) {
         IntervalPtrs::value_type i = handled_.back();
         // if this interval starts before t we are done
-        if (!i->empty() && i->start() < earliestStart)
+        if (i->start() < earliestStart)
             break;
         DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
         handled_.pop_back();
@@ -445,20 +457,10 @@
                 unhandled_.push_front(i);
             }
             else {
+                if (!spilled.count(i->reg))
+                    unhandled_.push_front(i);
                 prt_->delRegUse(vrm_->getPhys(i->reg));
                 vrm_->clearVirt(i->reg);
-                if (i->spilled()) {
-                    if (!i->empty()) {
-                        IntervalPtrs::iterator it = unhandled_.begin();
-                        while (it != unhandled_.end() &&
-                               (*it)->start() < i->start())
-                            ++it;
-                        unhandled_.insert(it, i);
-                    }
-                }
-                else
-                    unhandled_.push_front(i);
-
             }
         }
         else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
@@ -466,18 +468,9 @@
             if (MRegisterInfo::isPhysicalRegister(i->reg))
                 unhandled_.push_front(i);
             else {
-                vrm_->clearVirt(i->reg);
-                if (i->spilled()) {
-                    if (!i->empty()) {
-                        IntervalPtrs::iterator it = unhandled_.begin();
-                        while (it != unhandled_.end() &&
-                               (*it)->start() < i->start())
-                            ++it;
-                        unhandled_.insert(it, i);
-                    }
-                }
-                else
+                if (!spilled.count(i->reg))
                     unhandled_.push_front(i);
+                vrm_->clearVirt(i->reg);
             }
         }
         else {
@@ -501,6 +494,19 @@
                 prt_->addRegUse(vrm_->getPhys((*i)->reg));
         }
     }
+
+    std::sort(added.begin(), added.end(), LiveIntervals::StartPointPtrComp());
+    // merge added with unhandled
+    std::vector<LiveIntervals::Interval*>::iterator addedIt = added.begin();
+    std::vector<LiveIntervals::Interval*>::iterator addedItEnd = added.end();
+    for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end();
+         i != e && addedIt != addedItEnd; ++i) {
+        if ((*i)->start() > (*addedIt)->start())
+            i = unhandled_.insert(i, *(addedIt++));
+    }
+    while (addedIt != addedItEnd)
+        unhandled_.push_back(*(addedIt++));
+
 }
 
 unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)


Index: llvm/lib/CodeGen/LiveIntervals.h
diff -u llvm/lib/CodeGen/LiveIntervals.h:1.24 llvm/lib/CodeGen/LiveIntervals.h:1.25
--- llvm/lib/CodeGen/LiveIntervals.h:1.24	Sat May 29 11:18:57 2004
+++ llvm/lib/CodeGen/LiveIntervals.h	Sun May 30 02:24:39 2004
@@ -80,9 +80,9 @@
             }
         };
 
-        struct EndPointComp {
-            bool operator()(const Interval& lhs, const Interval& rhs) {
-                return lhs.ranges.back().second < rhs.ranges.back().second;
+        struct StartPointPtrComp {
+            bool operator()(const Interval* lhs, const Interval* rhs) {
+                return lhs->ranges.front().first < rhs->ranges.front().first;
             }
         };
 
@@ -164,7 +164,9 @@
 
         Intervals& getIntervals() { return intervals_; }
 
-        void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
+        std::vector<Interval*> addIntervalsForSpills(const Interval& i,
+                                                     VirtRegMap& vrm,
+                                                     int slot);
 
     private:
         /// computeIntervals - compute live intervals


Index: llvm/lib/CodeGen/LiveIntervals.cpp
diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.74 llvm/lib/CodeGen/LiveIntervals.cpp:1.75
--- llvm/lib/CodeGen/LiveIntervals.cpp:1.74	Sat May 29 11:18:57 2004
+++ llvm/lib/CodeGen/LiveIntervals.cpp	Sun May 30 02:24:39 2004
@@ -186,19 +186,23 @@
     return true;
 }
 
-void LiveIntervals::updateSpilledInterval(Interval& li,
-                                          VirtRegMap& vrm,
-                                          int slot)
+std::vector<LiveIntervals::Interval*>
+LiveIntervals::addIntervalsForSpills(const Interval& li,
+                                     VirtRegMap& vrm,
+                                     int slot)
 {
+    std::vector<Interval*> added;
+
     assert(li.weight != HUGE_VAL &&
            "attempt to spill already spilled interval!");
-    Interval::Ranges oldRanges;
-    swap(oldRanges, li.ranges);
 
-    DEBUG(std::cerr << "\t\t\t\tupdating interval: " << li);
+    DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: "
+          << li << '\n');
+
+    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
 
-    for (Interval::Ranges::iterator i = oldRanges.begin(), e = oldRanges.end();
-         i != e; ++i) {
+    for (Interval::Ranges::const_iterator
+             i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
         unsigned index = getBaseIndex(i->first);
         unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
         for (; index < end; index += InstrSlots::NUM) {
@@ -240,16 +244,31 @@
                         unsigned end = 1 + (mop.isDef() ?
                                             getUseIndex(index+InstrSlots::NUM) :
                                             getUseIndex(index));
-                        li.addRange(start, end);
+
+                        // create a new register for this spill
+                        unsigned nReg =
+                            mf_->getSSARegMap()->createVirtualRegister(rc);
+                        mi->SetMachineOperandReg(i, nReg);
+                        vrm.grow();
+                        vrm.assignVirt2StackSlot(nReg, slot);
+                        Interval& nI = getOrCreateInterval(nReg);
+                        assert(nI.empty());
+                        // the spill weight is now infinity as it
+                        // cannot be spilled again
+                        nI.weight = HUGE_VAL;
+                        nI.addRange(start, end);
+                        added.push_back(&nI);
+                        // update live variables
+                        lv_->addVirtualRegisterKilled(nReg, mi->getParent(),mi);
+                        DEBUG(std::cerr << "\t\t\t\tadded new interval: "
+                              << nI << '\n');
                     }
                 }
             }
         }
     }
-    // the new spill weight is now infinity as it cannot be spilled again
-    li.weight = HUGE_VAL;
-    DEBUG(std::cerr << '\n');
-    DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n');
+
+    return added;
 }
 
 void LiveIntervals::printRegName(unsigned reg) const





More information about the llvm-commits mailing list