rename DenseMap to IndexedMap.
[oota-llvm.git] / include / llvm / CodeGen / LiveInterval.h
index 33b2c75e6a2fd36f0e2082be68775cd54ce82379..367cefeb36c0601b1d247eea85c175b73b9534f8 100644 (file)
@@ -22,6 +22,7 @@
 #define LLVM_CODEGEN_LIVEINTERVAL_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Streams.h"
 #include <iosfwd>
 #include <vector>
 #include <cassert>
@@ -55,12 +56,16 @@ namespace llvm {
     }
 
     void dump() const;
+    void print(std::ostream &os) const;
+    void print(std::ostream *os) const { if (os) print(*os); }
 
   private:
     LiveRange(); // DO NOT IMPLEMENT
   };
+
   std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
 
+
   inline bool operator<(unsigned V, const LiveRange &LR) {
     return V < LR.start;
   }
@@ -78,10 +83,12 @@ namespace llvm {
     float weight;        // weight of this interval
     Ranges ranges;       // the ranges in which this register is live
   private:
-    /// InstDefiningValue - This tracks the def index of the instruction that
-    /// defines a particular value number in the interval.  This may be ~0,
-    /// which is treated as unknown, or ~1, which is a deleted value number.
-    SmallVector<unsigned, 4> InstDefiningValue;
+    /// ValueNumberInfo - If this value number is not defined by a copy, this
+    /// holds ~0,x.  If the value number is not in use, it contains ~1,x to
+    /// indicate that the value # is not used.  If the val# is defined by a
+    /// copy, the first entry is the instruction # of the copy, and the second
+    /// is the register number copied from.
+    SmallVector<std::pair<unsigned,unsigned>, 4> ValueNumberInfo;
   public:
 
     LiveInterval(unsigned Reg, float Weight)
@@ -113,31 +120,44 @@ namespace llvm {
       std::swap(reg, other.reg);
       std::swap(weight, other.weight);
       std::swap(ranges, other.ranges);
-      std::swap(InstDefiningValue, other.InstDefiningValue);
+      std::swap(ValueNumberInfo, other.ValueNumberInfo);
     }
 
-    bool containsOneValue() const { return InstDefiningValue.size() == 1; }
+    bool containsOneValue() const { return ValueNumberInfo.size() == 1; }
 
-    unsigned getNumValNums() const { return InstDefiningValue.size(); }
+    unsigned getNumValNums() const { return ValueNumberInfo.size(); }
     
     /// getNextValue - Create a new value number and return it.  MIIdx specifies
     /// the instruction that defines the value number.
-    unsigned getNextValue(unsigned MIIdx) {
-      InstDefiningValue.push_back(MIIdx);
-      return InstDefiningValue.size()-1;
+    unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) {
+      ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg));
+      return ValueNumberInfo.size()-1;
     }
     
     /// getInstForValNum - Return the machine instruction index that defines the
     /// specified value number.
     unsigned getInstForValNum(unsigned ValNo) const {
-      assert(ValNo < InstDefiningValue.size());
-      return InstDefiningValue[ValNo];
+      //assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo].first;
+    }
+    
+    unsigned getSrcRegForValNum(unsigned ValNo) const {
+      //assert(ValNo < ValueNumberInfo.size());
+      if (ValueNumberInfo[ValNo].first < ~2U)
+        return ValueNumberInfo[ValNo].second;
+      return 0;
+    }
+    
+    std::pair<unsigned, unsigned> getValNumInfo(unsigned ValNo) const {
+      //assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo];
     }
     
-    /// setInstDefiningValNum - Change the instruction defining the specified
-    /// value number to the specified instruction.
-    void setInstDefiningValNum(unsigned ValNo, unsigned MIIdx) {
-      InstDefiningValue[ValNo] = MIIdx;
+    /// setValueNumberInfo - Change the value number info for the specified
+    /// value number.
+    void setValueNumberInfo(unsigned ValNo,
+                            const std::pair<unsigned, unsigned> &I){
+      ValueNumberInfo[ValNo] = I;
     }
     
     /// MergeValueNumberInto - This method is called when two value nubmers
@@ -151,6 +171,13 @@ namespace llvm {
     /// used with an unknown definition value.
     void MergeInClobberRanges(const LiveInterval &Clobbers);
 
+    
+    /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live
+    /// interval as the specified value number.  The LiveRanges in RHS are
+    /// allowed to overlap with LiveRanges in the current interval, but only if
+    /// the overlapping LiveRanges have the specified value number.
+    void MergeRangesInAsValue(const LiveInterval &RHS, unsigned LHSValNo);
+    
     bool empty() const { return ranges.empty(); }
 
     /// beginNumber - Return the lowest numbered slot covered by interval.
@@ -216,18 +243,24 @@ namespace llvm {
     /// the intervals are not joinable, this aborts.
     void join(LiveInterval &Other, int *ValNoAssignments,
               int *RHSValNoAssignments,
-              SmallVector<unsigned, 16> &NewInstDefiningValue);
-
+              SmallVector<std::pair<unsigned,unsigned>,16> &NewValueNumberInfo);
 
     /// removeRange - Remove the specified range from this interval.  Note that
     /// the range must already be in this interval in its entirety.
     void removeRange(unsigned Start, unsigned End);
 
+    void removeRange(LiveRange LR) {
+      removeRange(LR.start, LR.end);
+    }
+
     bool operator<(const LiveInterval& other) const {
       return beginNumber() < other.beginNumber();
     }
 
     void print(std::ostream &OS, const MRegisterInfo *MRI = 0) const;
+    void print(std::ostream *OS, const MRegisterInfo *MRI = 0) const {
+      if (OS) print(*OS, MRI);
+    }
     void dump() const;
 
   private: