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

Chris Lattner lattner at cs.uiuc.edu
Fri Jul 23 20:32:16 PDT 2004



Changes in directory llvm/lib/CodeGen:

LiveIntervalAnalysis.cpp updated: 1.108 -> 1.109
LiveIntervalAnalysis.h updated: 1.36 -> 1.37
RegAllocIterativeScan.cpp updated: 1.8 -> 1.9
RegAllocLinearScan.cpp updated: 1.83 -> 1.84

---
Log message:

Completely eliminate the intervals_ list.  instead, the r2iMap_ maintains
ownership of the intervals.


---
Diffs of the changes:  (+71 -79)

Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.108 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.109
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.108	Fri Jul 23 21:59:07 2004
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp	Fri Jul 23 22:32:06 2004
@@ -76,9 +76,12 @@
 {
     mi2iMap_.clear();
     i2miMap_.clear();
+    for (std::map<unsigned, LiveInterval*>::iterator I = r2iMap_.begin(),
+           E = r2iMap_.end(); I != E; ++I)
+      delete I->second;  // free all intervals.
     r2iMap_.clear();
+
     r2rMap_.clear();
-    intervals_.clear();
 }
 
 
@@ -104,18 +107,18 @@
 
     computeIntervals();
 
-    numIntervals += intervals_.size();
+    numIntervals += getNumIntervals();
 
 #if 1
     DEBUG(std::cerr << "********** INTERVALS **********\n");
-    DEBUG(std::copy(intervals_.begin(), intervals_.end(),
-                    std::ostream_iterator<LiveInterval>(std::cerr, "\n")));
+    DEBUG(for (iterator I = begin(), E = end(); I != E; ++I)
+            std::cerr << *I->second << "\n");
 #endif
 
     // join intervals if requested
     if (EnableJoining) joinIntervals();
 
-    numIntervalsAfter += intervals_.size();
+    numIntervalsAfter += getNumIntervals();
 
     // perform a final pass over the instructions and compute spill
     // weights, coalesce virtual registers and remove identity moves
@@ -130,11 +133,11 @@
         for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
              mii != mie; ) {
             // if the move will be an identity move delete it
-            unsigned srcReg, dstReg;
+            unsigned srcReg, dstReg, RegRep;
             if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
-                rep(srcReg) == rep(dstReg)) {
+                (RegRep = rep(srcReg)) == rep(dstReg)) {
                 // remove from def list
-                LiveInterval& interval = getOrCreateInterval(rep(dstReg));
+                LiveInterval &interval = getOrCreateInterval(RegRep);
                 // remove index -> MachineInstr and
                 // MachineInstr -> index mappings
                 Mi2IndexMap::iterator mi2i = mi2iMap_.find(mii);
@@ -154,9 +157,8 @@
                         unsigned reg = rep(mop.getReg());
                         mii->SetMachineOperandReg(i, reg);
 
-                        Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
-                        assert(r2iit != r2iMap_.end());
-                        r2iit->second->weight +=
+                        LiveInterval &RegInt = getInterval(reg);
+                        RegInt.weight +=
                             (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
                     }
                 }
@@ -166,8 +168,8 @@
     }
 
     DEBUG(std::cerr << "********** INTERVALS **********\n");
-    DEBUG(std::copy(intervals_.begin(), intervals_.end(),
-                    std::ostream_iterator<LiveInterval>(std::cerr, "\n")));
+    DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
+             std::cerr << *I->second << "\n");
     DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
     DEBUG(
         for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
@@ -548,6 +550,8 @@
       assert(IntA.reg == regA && IntB.reg == regB &&
              "Register mapping is horribly broken!");
             
+      // If two intervals contain a single value and are joined by a copy, it
+      // does not matter if the intervals overlap, they can always be joined.
       bool TriviallyJoinable =
         IntA.containsOneValue() && IntB.containsOneValue();
 
@@ -555,19 +559,18 @@
       if ((TriviallyJoinable || !IntB.joinable(IntA, MIDefIdx)) &&
           !overlapsAliases(&IntA, &IntB)) {
         IntB.join(IntA, MIDefIdx);
-
-        // FIXME: Turn 'intervals_' into an ilist so we don't need to do these
-        // map lookups!
-        intervals_.erase(r2iMap_[regA]);
-        r2iMap_[regA] = r2iMap_[regB];
+        delete r2iMap_[regA];   // Delete the dead interval
 
         if (!MRegisterInfo::isPhysicalRegister(regA)) {
+          r2iMap_.erase(regA);
           r2rMap_[regA] = regB;
         } else {
           // Otherwise merge the data structures the other way so we don't lose
           // the physreg information.
           r2rMap_[regB] = regA;
           IntB.reg = regA;
+          r2iMap_[regA] = r2iMap_[regB];
+          r2iMap_.erase(regB);
         }
         DEBUG(std::cerr << "Joined.  Result = " << IntB << "\n");
         ++numJoins;
@@ -649,25 +652,15 @@
          MRegisterInfo::isVirtualRegister(RHS->reg) &&
          "first interval must describe a physical register");
 
-    for (const unsigned *AS = mri_->getAliasSet(LHS->reg); *AS; ++AS) {
-        Reg2IntervalMap::const_iterator r2i = r2iMap_.find(*AS);
-        assert(r2i != r2iMap_.end() && "alias does not have interval?");
-        if (RHS->overlaps(*r2i->second))
-            return true;
-    }
+  for (const unsigned *AS = mri_->getAliasSet(LHS->reg); *AS; ++AS)
+    if (RHS->overlaps(getInterval(*AS)))
+      return true;
 
-    return false;
+  return false;
 }
 
-LiveInterval& LiveIntervals::getOrCreateInterval(unsigned reg)
-{
-    Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg);
-    if (r2iit == r2iMap_.end() || r2iit->first != reg) {
-        float Weight = MRegisterInfo::isPhysicalRegister(reg) ?  HUGE_VAL :0.0F;
-        intervals_.push_back(LiveInterval(reg, Weight));
-        r2iit = r2iMap_.insert(r2iit, std::make_pair(reg, --intervals_.end()));
-    }
-
-    return *r2iit->second;
+LiveInterval *LiveIntervals::createInterval(unsigned reg) const {
+  float Weight = MRegisterInfo::isPhysicalRegister(reg) ?  HUGE_VAL :0.0F;
+  return new LiveInterval(reg, Weight);
 }
 


Index: llvm/lib/CodeGen/LiveIntervalAnalysis.h
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.36 llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.37
--- llvm/lib/CodeGen/LiveIntervalAnalysis.h:1.36	Fri Jul 23 21:53:43 2004
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.h	Fri Jul 23 22:32:06 2004
@@ -22,7 +22,6 @@
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "LiveInterval.h"
-#include <list>
 
 namespace llvm {
 
@@ -30,17 +29,10 @@
     class MRegisterInfo;
     class VirtRegMap;
 
-    class LiveIntervals : public MachineFunctionPass
-    {
-    public:
-        typedef std::list<LiveInterval> Intervals;
-
-    private:
+    class LiveIntervals : public MachineFunctionPass {
         MachineFunction* mf_;
         const TargetMachine* tm_;
         const MRegisterInfo* mri_;
-        MachineBasicBlock* currentMbb_;
-        MachineBasicBlock::iterator currentInstr_;
         LiveVariables* lv_;
 
         typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
@@ -49,14 +41,14 @@
         typedef std::vector<MachineInstr*> Index2MiMap;
         Index2MiMap i2miMap_;
 
-        typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
-        Reg2IntervalMap r2iMap_;
+        /// r2iMap_ - This map OWNS the interval pointed to by the map.  When
+        /// this map is destroyed or when entries are modified, this intervals
+        /// should be destroyed or modified as well.
+        std::map<unsigned, LiveInterval*> r2iMap_;
 
         typedef std::map<unsigned, unsigned> Reg2RegMap;
         Reg2RegMap r2rMap_;
 
-        Intervals intervals_;
-
     public:
         struct InstrSlots
         {
@@ -88,15 +80,15 @@
             return getBaseIndex(index) + InstrSlots::STORE;
         }
 
-        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-        virtual void releaseMemory();
-
-        /// runOnMachineFunction - pass entry point
-        virtual bool runOnMachineFunction(MachineFunction&);
-
-        LiveInterval& getInterval(unsigned reg) {
-          Reg2IntervalMap::iterator I = r2iMap_.find(reg);
-          assert(I != r2iMap_.end()&& "Interval does not exist for register");
+        typedef std::map<unsigned, LiveInterval*>::const_iterator iterator;
+        iterator begin() const { return r2iMap_.begin(); }
+        iterator end() const { return r2iMap_.end(); }
+      unsigned getNumIntervals() const { return r2iMap_.size(); }
+
+        LiveInterval &getInterval(unsigned reg) const {
+          std::map<unsigned, LiveInterval*>::const_iterator I =
+              r2iMap_.find(reg);
+          assert(I != r2iMap_.end() && "Interval does not exist for register");
           return *I->second;
         }
 
@@ -116,12 +108,16 @@
           return i2miMap_[index];
         }
 
-        Intervals& getIntervals() { return intervals_; }
-
         std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
                                                          VirtRegMap& vrm,
                                                          int slot);
 
+        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+        virtual void releaseMemory();
+
+        /// runOnMachineFunction - pass entry point
+        virtual bool runOnMachineFunction(MachineFunction&);
+
     private:
         /// computeIntervals - compute live intervals
         void computeIntervals();
@@ -159,8 +155,14 @@
         bool overlapsAliases(const LiveInterval *lhs, 
                              const LiveInterval *rhs) const;
 
+        LiveInterval *createInterval(unsigned Reg) const;
 
-        LiveInterval& getOrCreateInterval(unsigned reg);
+        LiveInterval &getOrCreateInterval(unsigned reg) {
+          LiveInterval *&LI = r2iMap_[reg];
+          if (LI == 0) 
+            LI = createInterval(reg);
+          return *LI;
+        }
 
         /// rep - returns the representative of this register
         unsigned rep(unsigned reg) {


Index: llvm/lib/CodeGen/RegAllocIterativeScan.cpp
diff -u llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.8 llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.9
--- llvm/lib/CodeGen/RegAllocIterativeScan.cpp:1.8	Fri Jul 23 12:56:30 2004
+++ llvm/lib/CodeGen/RegAllocIterativeScan.cpp	Fri Jul 23 22:32:06 2004
@@ -85,7 +85,7 @@
 
         /// initIntervalSets - initializes 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
@@ -151,9 +151,9 @@
     vrm_.reset(new VirtRegMap(*mf_));
     if (!spiller_.get()) spiller_.reset(createSpiller());
 
-    initIntervalSets(li_->getIntervals());
+    initIntervalSets();
 
-    numIntervals += li_->getIntervals().size();
+    numIntervals += li_->getNumIntervals();
 
     while (linearScan()) {
         // we spilled some registers, so we need to add intervals for
@@ -251,17 +251,15 @@
     return !spilled_.empty();
 }
 
-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_back(&*i);
-        if (MRegisterInfo::isPhysicalRegister(i->reg))
-            fixed_.push_back(&*i);
+    for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
+      unhandled_.push_back(i->second);
+      if (MRegisterInfo::isPhysicalRegister(i->second->reg))
+        fixed_.push_back(i->second);
     }
 }
 


Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.83 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.84
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.83	Fri Jul 23 12:56:30 2004
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Fri Jul 23 22:32:06 2004
@@ -82,7 +82,7 @@
 
         /// 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 @@
     vrm_.reset(new VirtRegMap(*mf_));
     if (!spiller_.get()) spiller_.reset(createSpiller());
 
-    initIntervalSets(li_->getIntervals());
+    initIntervalSets();
 
     linearScan();
 
@@ -193,7 +193,7 @@
         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 @@
     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);
     }
 }
 





More information about the llvm-commits mailing list