Re-implement trivial rematerialization. This allows def MIs whose live intervals...
[oota-llvm.git] / include / llvm / CodeGen / LiveInterval.h
index 863d9b5b0718e92a77b7f813d95e14c7c7ada20d..068a15d9a2edefe79151fa7606040b945af69cd0 100644 (file)
 #define LLVM_CODEGEN_LIVEINTERVAL_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Streams.h"
 #include <iosfwd>
 #include <vector>
 #include <cassert>
 
 namespace llvm {
+  class MachineInstr;
   class MRegisterInfo;
 
   /// LiveRange structure - This represents a simple register range in the
@@ -55,12 +57,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;
   }
@@ -75,19 +81,26 @@ namespace llvm {
   struct LiveInterval {
     typedef SmallVector<LiveRange,4> Ranges;
     unsigned reg;        // the register of this interval
+    unsigned preference; // preferred register to allocate for this interval
     float weight;        // weight of this interval
     Ranges ranges;       // the ranges in which this register is live
+
+    /// ValueNumberInfo - If the value number definition is undefined (e.g. phi
+    /// merge point), it contains ~0u,x. If the value number is not in use, it
+    /// contains ~1u,x to indicate that the value # is not used. 
+    struct VNInfo {
+      unsigned def;  // instruction # of the definition
+      unsigned reg;  // src reg: non-zero iff val# is defined by a copy
+      SmallVector<unsigned, 4> kills;  // instruction #s of the kills
+      VNInfo() : def(~1U), reg(0) {};
+      VNInfo(unsigned d, unsigned r) : def(d), reg(r) {};
+    };
   private:
-    /// 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;
+    SmallVector<VNInfo, 4> ValueNumberInfo;
   public:
 
     LiveInterval(unsigned Reg, float Weight)
-      : reg(Reg), weight(Weight) {
+      : reg(Reg), preference(0), weight(Weight) {
     }
 
     typedef Ranges::iterator iterator;
@@ -125,36 +138,168 @@ namespace llvm {
     /// getNextValue - Create a new value number and return it.  MIIdx specifies
     /// the instruction that defines the value number.
     unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) {
-      ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg));
+      ValueNumberInfo.push_back(VNInfo(MIIdx, SrcReg));
       return ValueNumberInfo.size()-1;
     }
     
-    /// getInstForValNum - Return the machine instruction index that defines the
+    /// getDefForValNum - Return the machine instruction index that defines the
     /// specified value number.
-    unsigned getInstForValNum(unsigned ValNo) const {
-      //assert(ValNo < ValueNumberInfo.size());
-      return ValueNumberInfo[ValNo].first;
+    unsigned getDefForValNum(unsigned ValNo) const {
+      assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo].def;
     }
     
+    /// getSrcRegForValNum - If the machine instruction that defines the
+    /// specified value number is a copy, returns the source register. Otherwise,
+    /// returns zero.
     unsigned getSrcRegForValNum(unsigned ValNo) const {
-      //assert(ValNo < ValueNumberInfo.size());
-      if (ValueNumberInfo[ValNo].first < ~2U)
-        return ValueNumberInfo[ValNo].second;
-      return 0;
+      assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo].reg;
+    }
+
+    /// setDefForValNum - Set the machine instruction index that defines the
+    /// specified value number. 
+    void setDefForValNum(unsigned ValNo, unsigned NewDef) {
+      assert(ValNo < ValueNumberInfo.size());
+      ValueNumberInfo[ValNo].def = NewDef;
     }
     
-    std::pair<unsigned, unsigned> getValNumInfo(unsigned ValNo) const {
-      //assert(ValNo < ValueNumberInfo.size());
+    /// setSrcRegForValNum - Set the source register of the specified value
+    /// number. 
+    void setSrcRegForValNum(unsigned ValNo, unsigned NewReg) {
+      assert(ValNo < ValueNumberInfo.size());
+      ValueNumberInfo[ValNo].reg = NewReg;
+    }
+
+    /// getKillsForValNum - Return the kill instruction indexes of the specified
+    /// value number.
+    const SmallVector<unsigned, 4> &getKillsForValNum(unsigned ValNo) const {
+      assert(ValNo < ValueNumberInfo.size());
+      return ValueNumberInfo[ValNo].kills;
+    }
+
+    /// addKillForValNum - Add a kill instruction index to the specified value
+    /// number.
+    void addKillForValNum(unsigned ValNo, unsigned KillIdx) {
+      assert(ValNo < ValueNumberInfo.size());
+      SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
+      if (kills.empty()) {
+        kills.push_back(KillIdx);
+      } else {
+        SmallVector<unsigned, 4>::iterator
+          I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
+        kills.insert(I, KillIdx);
+      }
+    }
+
+    /// addKills - Add a number of kills into the VNInfo kill vector. If this
+    /// interval is live at a kill point, then the kill is not added.
+    void addKills(VNInfo &VNI, const SmallVector<unsigned, 4> &kills) {
+      for (unsigned i = 0, e = kills.size(); i != e; ++i) {
+        unsigned KillIdx = kills[i];
+        if (!liveAt(KillIdx)) {
+          SmallVector<unsigned, 4>::iterator
+            I = std::lower_bound(VNI.kills.begin(), VNI.kills.end(), KillIdx);
+          VNI.kills.insert(I, KillIdx);
+        }
+      }
+    }
+
+    /// addKillsForValNum - Add a number of kills into the kills vector of
+    /// the specified value number.
+    void addKillsForValNum(unsigned ValNo,
+                           const SmallVector<unsigned, 4> &kills) {
+      addKills(ValueNumberInfo[ValNo], kills);
+    }
+
+    /// isKillForValNum - Returns true if KillIdx is a kill of the specified
+    /// val#.
+    bool isKillForValNum(unsigned ValNo, unsigned KillIdx) const {
+      assert(ValNo < ValueNumberInfo.size());
+      const SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
+      SmallVector<unsigned, 4>::const_iterator
+        I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
+      if (I == kills.end())
+        return false;
+      return *I == KillIdx;
+    }
+
+    /// removeKill - Remove the specified kill from the list of kills of
+    /// the specified val#.
+    static bool removeKill(VNInfo &VNI, unsigned KillIdx) {
+      SmallVector<unsigned, 4> &kills = VNI.kills;
+      SmallVector<unsigned, 4>::iterator
+        I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
+      if (I != kills.end() && *I == KillIdx) {
+        kills.erase(I);
+        return true;
+      }
+      return false;
+    }
+
+    /// removeKillForValNum - Remove the specified kill from the list of kills
+    /// of the specified val#.
+    bool removeKillForValNum(unsigned ValNo, unsigned KillIdx) {
+      assert(ValNo < ValueNumberInfo.size());
+      return removeKill(ValueNumberInfo[ValNo], KillIdx);
+    }
+
+    /// removeKillForValNum - Remove all the kills in specified range
+    /// [Start, End] of the specified val#.
+    void removeKillForValNum(unsigned ValNo, unsigned Start, unsigned End) {
+      assert(ValNo < ValueNumberInfo.size());
+      SmallVector<unsigned, 4> &kills = ValueNumberInfo[ValNo].kills;
+      SmallVector<unsigned, 4>::iterator
+        I = std::lower_bound(kills.begin(), kills.end(), Start);
+      SmallVector<unsigned, 4>::iterator
+        E = std::upper_bound(kills.begin(), kills.end(), End);
+      kills.erase(I, E);
+    }
+
+    /// replaceKill - Replace a kill index of the specified value# with a new
+    /// kill. Returns true if OldKill was indeed a kill point.
+    static bool replaceKill(VNInfo &VNI, unsigned OldKill, unsigned NewKill) {
+      SmallVector<unsigned, 4> &kills = VNI.kills;
+      SmallVector<unsigned, 4>::iterator
+        I = std::lower_bound(kills.begin(), kills.end(), OldKill);
+      if (I != kills.end() && *I == OldKill) {
+        *I = NewKill;
+        return true;
+      }
+      return false;
+    }
+
+    /// replaceKillForValNum - Replace a kill index of the specified value# with
+    /// a new kill. Returns true if OldKill was indeed a kill point.
+    bool replaceKillForValNum(unsigned ValNo, unsigned OldKill,
+                              unsigned NewKill) {
+      assert(ValNo < ValueNumberInfo.size());
+      return replaceKill(ValueNumberInfo[ValNo], OldKill, NewKill);
+    }
+    
+    /// getValNumInfo - Returns a copy of the specified val#.
+    ///
+    VNInfo getValNumInfo(unsigned ValNo) const {
+      assert(ValNo < ValueNumberInfo.size());
       return ValueNumberInfo[ValNo];
     }
     
-    /// setValueNumberInfo - Change the value number info for the specified
+    /// setValNumInfo - Change the value number info for the specified
     /// value number.
-    void setValueNumberInfo(unsigned ValNo,
-                            const std::pair<unsigned, unsigned> &I){
+    void setValNumInfo(unsigned ValNo, const VNInfo &I) {
       ValueNumberInfo[ValNo] = I;
     }
-    
+
+    /// copyValNumInfo - Copy the value number info for one value number to
+    /// another.
+    void copyValNumInfo(unsigned DstValNo, unsigned SrcValNo) {
+      ValueNumberInfo[DstValNo] = ValueNumberInfo[SrcValNo];
+    }
+    void copyValNumInfo(unsigned DstValNo, const LiveInterval &SrcLI,
+                        unsigned SrcValNo) {
+      ValueNumberInfo[DstValNo] = SrcLI.ValueNumberInfo[SrcValNo];
+    }
+
     /// 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
@@ -238,7 +383,7 @@ namespace llvm {
     /// the intervals are not joinable, this aborts.
     void join(LiveInterval &Other, int *ValNoAssignments,
               int *RHSValNoAssignments,
-              SmallVector<std::pair<unsigned,unsigned>,16> &NewValueNumberInfo);
+              SmallVector<VNInfo,16> &NewValueNumberInfo);
 
     /// removeRange - Remove the specified range from this interval.  Note that
     /// the range must already be in this interval in its entirety.
@@ -248,11 +393,18 @@ namespace llvm {
       removeRange(LR.start, LR.end);
     }
 
+    /// getSize - Returns the sum of sizes of all the LiveRange's.
+    ///
+    unsigned getSize() const;
+
     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: