LLVM API Documentation

LiveInterval.h

Go to the documentation of this file.
00001 //===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the LiveRange and LiveInterval classes.  Given some
00011 // numbering of each the machine instructions an interval [i, j) is said to be a
00012 // live interval for register v if there is no instruction with number j' >= j
00013 // such that v is live at j' and there is no instruction with number i' < i such
00014 // that v is live at i'. In this implementation intervals can have holes,
00015 // i.e. an interval might look like [1,20), [50,65), [1000,1001).  Each
00016 // individual range is represented as an instance of LiveRange, and the whole
00017 // interval is represented as an instance of LiveInterval.
00018 //
00019 //===----------------------------------------------------------------------===//
00020 
00021 #ifndef LLVM_CODEGEN_LIVEINTERVAL_H
00022 #define LLVM_CODEGEN_LIVEINTERVAL_H
00023 
00024 #include "llvm/ADT/SmallVector.h"
00025 #include "llvm/Support/Allocator.h"
00026 #include <iosfwd>
00027 #include <cassert>
00028 
00029 namespace llvm {
00030   class MachineInstr;
00031   class TargetRegisterInfo;
00032   struct LiveInterval;
00033 
00034   /// VNInfo - If the value number definition is undefined (e.g. phi
00035   /// merge point), it contains ~0u,x. If the value number is not in use, it
00036   /// contains ~1u,x to indicate that the value # is not used. 
00037   ///   def   - Instruction # of the definition.
00038   ///         - or reg # of the definition if it's a stack slot liveinterval.
00039   ///   copy  - Copy iff val# is defined by a copy; zero otherwise.
00040   ///   hasPHIKill - One or more of the kills are PHI nodes.
00041   ///   redefByEC - Re-defined by early clobber somewhere during the live range.
00042   ///   kills - Instruction # of the kills.
00043   struct VNInfo {
00044     unsigned id;
00045     unsigned def;
00046     MachineInstr *copy;
00047     bool hasPHIKill : 1;
00048     bool redefByEC : 1;
00049     SmallVector<unsigned, 4> kills;
00050     VNInfo()
00051       : id(~1U), def(~1U), copy(0), hasPHIKill(false), redefByEC(false) {}
00052     VNInfo(unsigned i, unsigned d, MachineInstr *c)
00053       : id(i), def(d), copy(c), hasPHIKill(false), redefByEC(false) {}
00054   };
00055 
00056   /// LiveRange structure - This represents a simple register range in the
00057   /// program, with an inclusive start point and an exclusive end point.
00058   /// These ranges are rendered as [start,end).
00059   struct LiveRange {
00060     unsigned start;  // Start point of the interval (inclusive)
00061     unsigned end;    // End point of the interval (exclusive)
00062     VNInfo *valno;   // identifier for the value contained in this interval.
00063 
00064     LiveRange(unsigned S, unsigned E, VNInfo *V) : start(S), end(E), valno(V) {
00065       assert(S < E && "Cannot create empty or backwards range");
00066     }
00067 
00068     /// contains - Return true if the index is covered by this range.
00069     ///
00070     bool contains(unsigned I) const {
00071       return start <= I && I < end;
00072     }
00073 
00074     bool operator<(const LiveRange &LR) const {
00075       return start < LR.start || (start == LR.start && end < LR.end);
00076     }
00077     bool operator==(const LiveRange &LR) const {
00078       return start == LR.start && end == LR.end;
00079     }
00080 
00081     void dump() const;
00082     void print(std::ostream &os) const;
00083     void print(std::ostream *os) const { if (os) print(*os); }
00084 
00085   private:
00086     LiveRange(); // DO NOT IMPLEMENT
00087   };
00088 
00089   std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
00090 
00091 
00092   inline bool operator<(unsigned V, const LiveRange &LR) {
00093     return V < LR.start;
00094   }
00095 
00096   inline bool operator<(const LiveRange &LR, unsigned V) {
00097     return LR.start < V;
00098   }
00099 
00100   /// LiveInterval - This class represents some number of live ranges for a
00101   /// register or value.  This class also contains a bit of register allocator
00102   /// state.
00103   struct LiveInterval {
00104     typedef SmallVector<LiveRange,4> Ranges;
00105     typedef SmallVector<VNInfo*,4> VNInfoList;
00106 
00107     unsigned reg;        // the register or stack slot of this interval
00108                          // if the top bits is set, it represents a stack slot.
00109     float weight;        // weight of this interval
00110     unsigned short preference; // preferred register for this interval
00111     Ranges ranges;       // the ranges in which this register is live
00112     VNInfoList valnos;   // value#'s
00113 
00114   public:
00115     LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
00116       : reg(Reg), weight(Weight), preference(0)  {
00117       if (IsSS)
00118         reg = reg | (1U << (sizeof(unsigned)*8-1));
00119     }
00120 
00121     typedef Ranges::iterator iterator;
00122     iterator begin() { return ranges.begin(); }
00123     iterator end()   { return ranges.end(); }
00124 
00125     typedef Ranges::const_iterator const_iterator;
00126     const_iterator begin() const { return ranges.begin(); }
00127     const_iterator end() const  { return ranges.end(); }
00128 
00129     typedef VNInfoList::iterator vni_iterator;
00130     vni_iterator vni_begin() { return valnos.begin(); }
00131     vni_iterator vni_end() { return valnos.end(); }
00132 
00133     typedef VNInfoList::const_iterator const_vni_iterator;
00134     const_vni_iterator vni_begin() const { return valnos.begin(); }
00135     const_vni_iterator vni_end() const { return valnos.end(); }
00136 
00137     /// advanceTo - Advance the specified iterator to point to the LiveRange
00138     /// containing the specified position, or end() if the position is past the
00139     /// end of the interval.  If no LiveRange contains this position, but the
00140     /// position is in a hole, this method returns an iterator pointing the the
00141     /// LiveRange immediately after the hole.
00142     iterator advanceTo(iterator I, unsigned Pos) {
00143       if (Pos >= endNumber())
00144         return end();
00145       while (I->end <= Pos) ++I;
00146       return I;
00147     }
00148     
00149     void clear() {
00150       while (!valnos.empty()) {
00151         VNInfo *VNI = valnos.back();
00152         valnos.pop_back();
00153         VNI->~VNInfo();
00154       }
00155       
00156       ranges.clear();
00157     }
00158 
00159     /// isStackSlot - Return true if this is a stack slot interval.
00160     ///
00161     bool isStackSlot() const {
00162       return reg & (1U << (sizeof(unsigned)*8-1));
00163     }
00164 
00165     /// getStackSlotIndex - Return stack slot index if this is a stack slot
00166     /// interval.
00167     int getStackSlotIndex() const {
00168       assert(isStackSlot() && "Interval is not a stack slot interval!");
00169       return reg & ~(1U << (sizeof(unsigned)*8-1));
00170     }
00171 
00172     bool hasAtLeastOneValue() const { return !valnos.empty(); }
00173 
00174     bool containsOneValue() const { return valnos.size() == 1; }
00175 
00176     unsigned getNumValNums() const { return (unsigned)valnos.size(); }
00177     
00178     /// getValNumInfo - Returns pointer to the specified val#.
00179     ///
00180     inline VNInfo *getValNumInfo(unsigned ValNo) {
00181       return valnos[ValNo];
00182     }
00183     inline const VNInfo *getValNumInfo(unsigned ValNo) const {
00184       return valnos[ValNo];
00185     }
00186     
00187     /// copyValNumInfo - Copy the value number info for one value number to
00188     /// another.
00189     void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) {
00190       DstValNo->def = SrcValNo->def;
00191       DstValNo->copy = SrcValNo->copy;
00192       DstValNo->hasPHIKill = SrcValNo->hasPHIKill;
00193       DstValNo->redefByEC = SrcValNo->redefByEC;
00194       DstValNo->kills = SrcValNo->kills;
00195     }
00196 
00197     /// getNextValue - Create a new value number and return it.  MIIdx specifies
00198     /// the instruction that defines the value number.
00199     VNInfo *getNextValue(unsigned MIIdx, MachineInstr *CopyMI,
00200                          BumpPtrAllocator &VNInfoAllocator) {
00201 #ifdef __GNUC__
00202       unsigned Alignment = (unsigned)__alignof__(VNInfo);
00203 #else
00204       // FIXME: ugly.
00205       unsigned Alignment = 8;
00206 #endif
00207       VNInfo *VNI =
00208         static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
00209                                                       Alignment));
00210       new (VNI) VNInfo((unsigned)valnos.size(), MIIdx, CopyMI);
00211       valnos.push_back(VNI);
00212       return VNI;
00213     }
00214 
00215     /// addKill - Add a kill instruction index to the specified value
00216     /// number.
00217     static void addKill(VNInfo *VNI, unsigned KillIdx) {
00218       SmallVector<unsigned, 4> &kills = VNI->kills;
00219       if (kills.empty()) {
00220         kills.push_back(KillIdx);
00221       } else {
00222         SmallVector<unsigned, 4>::iterator
00223           I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
00224         kills.insert(I, KillIdx);
00225       }
00226     }
00227 
00228     /// addKills - Add a number of kills into the VNInfo kill vector. If this
00229     /// interval is live at a kill point, then the kill is not added.
00230     void addKills(VNInfo *VNI, const SmallVector<unsigned, 4> &kills) {
00231       for (unsigned i = 0, e = static_cast<unsigned>(kills.size());
00232            i != e; ++i) {
00233         unsigned KillIdx = kills[i];
00234         if (!liveBeforeAndAt(KillIdx)) {
00235           SmallVector<unsigned, 4>::iterator
00236             I = std::lower_bound(VNI->kills.begin(), VNI->kills.end(), KillIdx);
00237           VNI->kills.insert(I, KillIdx);
00238         }
00239       }
00240     }
00241 
00242     /// removeKill - Remove the specified kill from the list of kills of
00243     /// the specified val#.
00244     static bool removeKill(VNInfo *VNI, unsigned KillIdx) {
00245       SmallVector<unsigned, 4> &kills = VNI->kills;
00246       SmallVector<unsigned, 4>::iterator
00247         I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
00248       if (I != kills.end() && *I == KillIdx) {
00249         kills.erase(I);
00250         return true;
00251       }
00252       return false;
00253     }
00254 
00255     /// removeKills - Remove all the kills in specified range
00256     /// [Start, End] of the specified val#.
00257     static void removeKills(VNInfo *VNI, unsigned Start, unsigned End) {
00258       SmallVector<unsigned, 4> &kills = VNI->kills;
00259       SmallVector<unsigned, 4>::iterator
00260         I = std::lower_bound(kills.begin(), kills.end(), Start);
00261       SmallVector<unsigned, 4>::iterator
00262         E = std::upper_bound(kills.begin(), kills.end(), End);
00263       kills.erase(I, E);
00264     }
00265 
00266     /// isKill - Return true if the specified index is a kill of the
00267     /// specified val#.
00268     static bool isKill(const VNInfo *VNI, unsigned KillIdx) {
00269       const SmallVector<unsigned, 4> &kills = VNI->kills;
00270       SmallVector<unsigned, 4>::const_iterator
00271         I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
00272       return I != kills.end() && *I == KillIdx;
00273     }
00274 
00275     /// isOnlyLROfValNo - Return true if the specified live range is the only
00276     /// one defined by the its val#.
00277     bool isOnlyLROfValNo( const LiveRange *LR) {
00278       for (const_iterator I = begin(), E = end(); I != E; ++I) {
00279         const LiveRange *Tmp = I;
00280         if (Tmp != LR && Tmp->valno == LR->valno)
00281           return false;
00282       }
00283       return true;
00284     }
00285     
00286     /// MergeValueNumberInto - This method is called when two value nubmers
00287     /// are found to be equivalent.  This eliminates V1, replacing all
00288     /// LiveRanges with the V1 value number with the V2 value number.  This can
00289     /// cause merging of V1/V2 values numbers and compaction of the value space.
00290     VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
00291 
00292     /// MergeInClobberRanges - For any live ranges that are not defined in the
00293     /// current interval, but are defined in the Clobbers interval, mark them
00294     /// used with an unknown definition value. Caller must pass in reference to
00295     /// VNInfoAllocator since it will create a new val#.
00296     void MergeInClobberRanges(const LiveInterval &Clobbers,
00297                               BumpPtrAllocator &VNInfoAllocator);
00298 
00299     /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
00300     /// in RHS into this live interval as the specified value number.
00301     /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
00302     /// current interval, it will replace the value numbers of the overlaped
00303     /// live ranges with the specified value number.
00304     void MergeRangesInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo);
00305 
00306     /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
00307     /// in RHS into this live interval as the specified value number.
00308     /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
00309     /// current interval, but only if the overlapping LiveRanges have the
00310     /// specified value number.
00311     void MergeValueInAsValue(const LiveInterval &RHS,
00312                              const VNInfo *RHSValNo, VNInfo *LHSValNo);
00313 
00314     /// Copy - Copy the specified live interval. This copies all the fields
00315     /// except for the register of the interval.
00316     void Copy(const LiveInterval &RHS, BumpPtrAllocator &VNInfoAllocator);
00317     
00318     bool empty() const { return ranges.empty(); }
00319 
00320     /// beginNumber - Return the lowest numbered slot covered by interval.
00321     unsigned beginNumber() const {
00322       if (empty())
00323         return 0;
00324       return ranges.front().start;
00325     }
00326 
00327     /// endNumber - return the maximum point of the interval of the whole,
00328     /// exclusive.
00329     unsigned endNumber() const {
00330       if (empty())
00331         return 0;
00332       return ranges.back().end;
00333     }
00334 
00335     bool expiredAt(unsigned index) const {
00336       return index >= endNumber();
00337     }
00338 
00339     bool liveAt(unsigned index) const;
00340 
00341     // liveBeforeAndAt - Check if the interval is live at the index and the
00342     // index just before it. If index is liveAt, check if it starts a new live
00343     // range.If it does, then check if the previous live range ends at index-1.
00344     bool liveBeforeAndAt(unsigned index) const;
00345 
00346     /// getLiveRangeContaining - Return the live range that contains the
00347     /// specified index, or null if there is none.
00348     const LiveRange *getLiveRangeContaining(unsigned Idx) const {
00349       const_iterator I = FindLiveRangeContaining(Idx);
00350       return I == end() ? 0 : &*I;
00351     }
00352 
00353     /// FindLiveRangeContaining - Return an iterator to the live range that
00354     /// contains the specified index, or end() if there is none.
00355     const_iterator FindLiveRangeContaining(unsigned Idx) const;
00356 
00357     /// FindLiveRangeContaining - Return an iterator to the live range that
00358     /// contains the specified index, or end() if there is none.
00359     iterator FindLiveRangeContaining(unsigned Idx);
00360 
00361     /// findDefinedVNInfo - Find the VNInfo that's defined at the specified
00362     /// index (register interval) or defined by the specified register (stack
00363     /// inteval).
00364     VNInfo *findDefinedVNInfo(unsigned DefIdxOrReg) const;
00365     
00366     /// overlaps - Return true if the intersection of the two live intervals is
00367     /// not empty.
00368     bool overlaps(const LiveInterval& other) const {
00369       return overlapsFrom(other, other.begin());
00370     }
00371 
00372     /// overlapsFrom - Return true if the intersection of the two live intervals
00373     /// is not empty.  The specified iterator is a hint that we can begin
00374     /// scanning the Other interval starting at I.
00375     bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
00376 
00377     /// addRange - Add the specified LiveRange to this interval, merging
00378     /// intervals as appropriate.  This returns an iterator to the inserted live
00379     /// range (which may have grown since it was inserted.
00380     void addRange(LiveRange LR) {
00381       addRangeFrom(LR, ranges.begin());
00382     }
00383 
00384     /// join - Join two live intervals (this, and other) together.  This applies
00385     /// mappings to the value numbers in the LHS/RHS intervals as specified.  If
00386     /// the intervals are not joinable, this aborts.
00387     void join(LiveInterval &Other, const int *ValNoAssignments,
00388               const int *RHSValNoAssignments,
00389               SmallVector<VNInfo*, 16> &NewVNInfo);
00390 
00391     /// isInOneLiveRange - Return true if the range specified is entirely in the
00392     /// a single LiveRange of the live interval.
00393     bool isInOneLiveRange(unsigned Start, unsigned End);
00394 
00395     /// removeRange - Remove the specified range from this interval.  Note that
00396     /// the range must be a single LiveRange in its entirety.
00397     void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false);
00398 
00399     void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
00400       removeRange(LR.start, LR.end, RemoveDeadValNo);
00401     }
00402 
00403     /// removeValNo - Remove all the ranges defined by the specified value#.
00404     /// Also remove the value# from value# list.
00405     void removeValNo(VNInfo *ValNo);
00406 
00407     /// getSize - Returns the sum of sizes of all the LiveRange's.
00408     ///
00409     unsigned getSize() const;
00410 
00411     bool operator<(const LiveInterval& other) const {
00412       return beginNumber() < other.beginNumber();
00413     }
00414 
00415     void print(std::ostream &OS, const TargetRegisterInfo *TRI = 0) const;
00416     void print(std::ostream *OS, const TargetRegisterInfo *TRI = 0) const {
00417       if (OS) print(*OS, TRI);
00418     }
00419     void dump() const;
00420 
00421   private:
00422     Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
00423     void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
00424     Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
00425     LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
00426   };
00427 
00428   inline std::ostream &operator<<(std::ostream &OS, const LiveInterval &LI) {
00429     LI.print(OS);
00430     return OS;
00431   }
00432 }
00433 
00434 #endif