[llvm-commits] [regalloc_linearscan] CVS: llvm/include/llvm/CodeGen/LiveIntervals.h

Alkis Evlogimenos alkis at cs.uiuc.edu
Sun Oct 26 20:40:13 PST 2003


Changes in directory llvm/include/llvm/CodeGen:

LiveIntervals.h updated: 1.1.2.2 -> 1.1.2.3

---
Log message:

Reimplement LiveIntervals. Apparently the previous version was not
working properly due to some false assumptions. This version works as
expected and it also supports intervals with holes. One subtle
difference in this implementation is that a live range of [i, j] means
that the variable is live between i and j - 1 (that is it is already
dead in j). In the previous implementation a live range [i, j] meant
that the variable is live between i and j (it dies after the execution
of instruction j).


---
Diffs of the changes:  (+74 -23)

Index: llvm/include/llvm/CodeGen/LiveIntervals.h
diff -u llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.2 llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.3
--- llvm/include/llvm/CodeGen/LiveIntervals.h:1.1.2.2	Fri Oct 24 10:49:24 2003
+++ llvm/include/llvm/CodeGen/LiveIntervals.h	Sun Oct 26 20:37:59 2003
@@ -1,19 +1,21 @@
 //===-- llvm/CodeGen/LiveInterval.h - Live Interval Analysis ----*- C++ -*-===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
-// 
+//
 // This file implements the LiveInterval analysis pass.  Given some
 // numbering of each the machine instructions (in this implemention
 // depth-first order) an interval [i, j] is said to be a live interval
 // for register v if there is no instruction with number j' > j such
 // that v is live at j' abd there is no instruction with number i' < i
-// such that v is live at i'.
-//   
+// such that v is live at i'. In this implementation intervals can
+// have holes, i.e. an interval might look like [1,20], [50,65],
+// [1000,1001]
+//
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CODEGEN_LIVEINTERVALS_H
@@ -21,33 +23,76 @@
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
+#include <iostream>
 #include <map>
 
 class LiveVariables;
 class MRegisterInfo;
 
-class LiveIntervals : public MachineFunctionPass {
+class LiveIntervals : public MachineFunctionPass
+{
 public:
     struct Interval {
+        typedef std::pair<unsigned, unsigned> Range;
+        typedef std::vector<Range> Ranges;
         unsigned reg;   // the register of this interval
-        unsigned start; // the start instruction (def)
-        unsigned end;   // the end instruction (last use)
+        Ranges ranges; // the ranges this register is valid
+
+        Interval(unsigned r)
+            : reg(r) {
 
-        Interval(unsigned r, unsigned b, unsigned e)
-            : reg(r), start(b), end(e) {
+        }
+
+        void addRange(unsigned start, unsigned end) {
+            Range range = std::make_pair(start, end);
+            Ranges::iterator it =
+                std::lower_bound(ranges.begin(), ranges.end(), range);
+
+            if (it == ranges.end()) {
+                it = ranges.insert(it, range);
+                goto exit;
+            }
+
+            assert(range.first <= it->first && "got wrong iterator?");
+            // merge ranges if necesary
+            if (range.first < it->first) {
+                if (range.second >= it->first) {
+                    it->first = range.first;
+                }
+                else {
+                    it = ranges.insert(it, range);
+                    assert(it != ranges.end() && "wtf?");
+                    goto exit;
+                }
+            }
 
+        exit:
+            mergeRangesIfNecessary(it);
+        }
+
+    private:
+        void mergeRangesIfNecessary(Ranges::iterator it) {
+            while (it != ranges.begin()) {
+                Ranges::iterator prev = it - 1;
+                if (prev->second < it->first) {
+                    break;
+                }
+                prev->second = it->second;
+                ranges.erase(it);
+                it = prev;
+            }
         }
     };
 
     struct StartPointComp {
         bool operator()(const Interval& lhs, const Interval& rhs) {
-            return lhs.start < rhs.start;
+            return lhs.ranges.front().first < rhs.ranges.front().first;
         }
     };
 
     struct EndPointComp {
         bool operator()(const Interval& lhs, const Interval& rhs) {
-            return lhs.end < rhs.end;
+            return lhs.ranges.back().second < rhs.ranges.back().second;
         }
     };
 
@@ -58,17 +103,18 @@
     MachineBasicBlock* _currentMbb;
     MachineBasicBlock::iterator _currentInstr;
     LiveVariables* _lv;
-    
-    typedef std::vector<MachineBasicBlock*> MBBPtrs;
-    MBBPtrs _mbbOrder;
 
-    typedef std::map<MachineInstr*, unsigned> Instr2IndexMap;
-    Instr2IndexMap _i2iMap;
+    typedef std::map<unsigned, MachineBasicBlock*> Index2MbbMap;
+    Index2MbbMap _i2mbbMap;
+
+    typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
+    Mi2IndexMap _mi2iMap;
 
     typedef std::vector<Interval> Intervals;
     Intervals _intervals;
 
     typedef std::map<unsigned, unsigned> Reg2IntervalMap;
+    Reg2IntervalMap _r2iMap;
 
 public:
     virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -81,10 +127,11 @@
     void computeIntervals();
 
     /// handleRegisterDef - update intervals for a register def
-    void handleRegisterDef(Reg2IntervalMap& r2iMap, unsigned i, unsigned reg);
+    void handleRegisterDef(MachineBasicBlock* mbb,
+                           MachineInstr* instr,
+                           unsigned reg);
 
-    /// handleRegisterKill - update intervals for a register kill
-    void handleRegisterKill(Reg2IntervalMap& r2iMap, unsigned i, unsigned reg);
+    unsigned getInstructionIndex(MachineInstr* instr);
 };
 
 inline bool operator==(const LiveIntervals::Interval& lhs,
@@ -93,9 +140,13 @@
 }
 
 inline std::ostream& operator<<(std::ostream& os,
-                                const LiveIntervals::Interval& i) {
-    return os << "[ %reg" << i.reg << ", "
-              << i.start << ", " << i.end << "]";
+                                const LiveIntervals::Interval& li) {
+    os << "%reg" << li.reg << " = ";
+    for (LiveIntervals::Interval::Ranges::const_iterator
+             i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
+        os << "[" << i->first << ", " << i->second << "]";
+    }
+    return os;
 }
 
 





More information about the llvm-commits mailing list