rename DenseMap to IndexedMap.
[oota-llvm.git] / include / llvm / CodeGen / LiveInterval.h
index 30a397b22fba6590d3686bd8c0300f4e0cdd1759..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,16 +83,16 @@ namespace llvm {
     float weight;        // weight of this interval
     Ranges ranges;       // the ranges in which this register is live
   private:
-    unsigned NumValues;  // the number of distinct values in this interval.
-    
-    /// 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.
-    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)
-      : reg(Reg), weight(Weight), NumValues(0) {
+      : reg(Reg), weight(Weight) {
     }
 
     typedef Ranges::iterator iterator;
@@ -115,31 +120,64 @@ namespace llvm {
       std::swap(reg, other.reg);
       std::swap(weight, other.weight);
       std::swap(ranges, other.ranges);
-      std::swap(NumValues, other.NumValues);
+      std::swap(ValueNumberInfo, other.ValueNumberInfo);
     }
 
-    bool containsOneValue() const { return NumValues == 1; }
+    bool containsOneValue() const { return ValueNumberInfo.size() == 1; }
 
+    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 NumValues++;
+    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 {
-      return InstDefiningValue[ValNo];
+      //assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo].first;
     }
     
-    /// setInstDefiningValNum - Change the instruction defining the specified
-    /// value number to the specified instruction.
-    void setInstDefiningValNum(unsigned ValNo, unsigned MIIdx) {
-      InstDefiningValue[ValNo] = MIIdx;
+    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];
+    }
+    
+    /// 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
+    /// are found to be equivalent.  This eliminates V1, replacing all
+    /// LiveRanges with the V1 value number with the V2 value number.  This can
+    /// cause merging of V1/V2 values numbers and compaction of the value space.
+    void MergeValueNumberInto(unsigned V1, unsigned V2);
 
+    /// MergeInClobberRanges - For any live ranges that are not defined in the
+    /// current interval, but are defined in the Clobbers interval, mark them
+    /// 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.
@@ -163,14 +201,19 @@ namespace llvm {
 
     /// getLiveRangeContaining - Return the live range that contains the
     /// specified index, or null if there is none.
-    const LiveRange *getLiveRangeContaining(unsigned Idx) const;
-
+    const LiveRange *getLiveRangeContaining(unsigned Idx) const {
+      const_iterator I = FindLiveRangeContaining(Idx);
+      return I == end() ? 0 : &*I;
+    }
 
-    /// joinable - Two intervals are joinable if the either don't overlap at all
-    /// or if the destination of the copy is a single assignment value, and it
-    /// only overlaps with one value in the source interval.
-    bool joinable(const LiveInterval& other, unsigned CopyIdx) const;
+    /// FindLiveRangeContaining - Return an iterator to the live range that
+    /// contains the specified index, or end() if there is none.
+    const_iterator FindLiveRangeContaining(unsigned Idx) const;
 
+    /// FindLiveRangeContaining - Return an iterator to the live range that
+    /// contains the specified index, or end() if there is none.
+    iterator FindLiveRangeContaining(unsigned Idx);
+    
     /// getOverlapingRanges - Given another live interval which is defined as a
     /// copy from this one, return a list of all of the live ranges where the
     /// two overlap and have different value numbers.
@@ -195,22 +238,29 @@ namespace llvm {
       addRangeFrom(LR, ranges.begin());
     }
 
-    /// join - Join two live intervals (this, and other) together.  This
-    /// operation is the result of a copy instruction in the source program,
-    /// that occurs at index 'CopyIdx' that copies from 'other' to 'this'.  This
-    /// destroys 'other'.
-    void join(LiveInterval& other, unsigned CopyIdx);
-
+    /// join - Join two live intervals (this, and other) together.  This applies
+    /// mappings to the value numbers in the LHS/RHS intervals as specified.  If
+    /// the intervals are not joinable, this aborts.
+    void join(LiveInterval &Other, int *ValNoAssignments,
+              int *RHSValNoAssignments,
+              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: