LiveInterval.h revision 34cd4a484e532cc463fd5a4bf59b88d13c5467c1
1//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the LiveRange and LiveInterval classes.  Given some
11// numbering of each the machine instructions an interval [i, j) is said to be a
12// live interval for register v if there is no instruction with number j' > j
13// such that v is live at j' and there is no instruction with number i' < i such
14// that v is live at i'. In this implementation intervals can have holes,
15// i.e. an interval might look like [1,20), [50,65), [1000,1001).  Each
16// individual range is represented as an instance of LiveRange, and the whole
17// interval is represented as an instance of LiveInterval.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
22#define LLVM_CODEGEN_LIVEINTERVAL_H
23
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Support/Allocator.h"
26#include "llvm/Support/Streams.h"
27#include <iosfwd>
28#include <vector>
29#include <cassert>
30
31namespace llvm {
32  class MachineInstr;
33  class TargetRegisterInfo;
34  struct LiveInterval;
35
36  /// VNInfo - If the value number definition is undefined (e.g. phi
37  /// merge point), it contains ~0u,x. If the value number is not in use, it
38  /// contains ~1u,x to indicate that the value # is not used.
39  ///   def   - Instruction # of the definition.
40  ///   copy  - Copy iff val# is defined by a copy; zero otherwise.
41  ///   hasPHIKill - One or more of the kills are PHI nodes.
42  ///   kills - Instruction # of the kills.
43  struct VNInfo {
44    unsigned id;
45    unsigned def;
46    MachineInstr *copy;
47    bool hasPHIKill;
48    SmallVector<unsigned, 4> kills;
49    VNInfo() : id(~1U), def(~1U), copy(0), hasPHIKill(false) {}
50    VNInfo(unsigned i, unsigned d, MachineInstr *c)
51      : id(i), def(d), copy(c), hasPHIKill(false) {}
52  };
53
54  /// LiveRange structure - This represents a simple register range in the
55  /// program, with an inclusive start point and an exclusive end point.
56  /// These ranges are rendered as [start,end).
57  struct LiveRange {
58    unsigned start;  // Start point of the interval (inclusive)
59    unsigned end;    // End point of the interval (exclusive)
60    VNInfo *valno;   // identifier for the value contained in this interval.
61
62    LiveRange(unsigned S, unsigned E, VNInfo *V) : start(S), end(E), valno(V) {
63      assert(S < E && "Cannot create empty or backwards range");
64    }
65
66    /// contains - Return true if the index is covered by this range.
67    ///
68    bool contains(unsigned I) const {
69      return start <= I && I < end;
70    }
71
72    bool operator<(const LiveRange &LR) const {
73      return start < LR.start || (start == LR.start && end < LR.end);
74    }
75    bool operator==(const LiveRange &LR) const {
76      return start == LR.start && end == LR.end;
77    }
78
79    void dump() const;
80    void print(std::ostream &os) const;
81    void print(std::ostream *os) const { if (os) print(*os); }
82
83  private:
84    LiveRange(); // DO NOT IMPLEMENT
85  };
86
87  std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
88
89
90  inline bool operator<(unsigned V, const LiveRange &LR) {
91    return V < LR.start;
92  }
93
94  inline bool operator<(const LiveRange &LR, unsigned V) {
95    return LR.start < V;
96  }
97
98  /// LiveInterval - This class represents some number of live ranges for a
99  /// register or value.  This class also contains a bit of register allocator
100  /// state.
101  struct LiveInterval {
102    typedef SmallVector<LiveRange,4> Ranges;
103    typedef SmallVector<VNInfo*,4> VNInfoList;
104
105    unsigned reg;        // the register of this interval
106    unsigned preference; // preferred register to allocate for this interval
107    float weight;        // weight of this interval
108    Ranges ranges;       // the ranges in which this register is live
109    VNInfoList valnos;   // value#'s
110
111  public:
112    LiveInterval(unsigned Reg, float Weight)
113      : reg(Reg), preference(0), weight(Weight) {
114    }
115
116    typedef Ranges::iterator iterator;
117    iterator begin() { return ranges.begin(); }
118    iterator end()   { return ranges.end(); }
119
120    typedef Ranges::const_iterator const_iterator;
121    const_iterator begin() const { return ranges.begin(); }
122    const_iterator end() const  { return ranges.end(); }
123
124    typedef VNInfoList::iterator vni_iterator;
125    vni_iterator vni_begin() { return valnos.begin(); }
126    vni_iterator vni_end() { return valnos.end(); }
127
128    typedef VNInfoList::const_iterator const_vni_iterator;
129    const_vni_iterator vni_begin() const { return valnos.begin(); }
130    const_vni_iterator vni_end() const { return valnos.end(); }
131
132    /// advanceTo - Advance the specified iterator to point to the LiveRange
133    /// containing the specified position, or end() if the position is past the
134    /// end of the interval.  If no LiveRange contains this position, but the
135    /// position is in a hole, this method returns an iterator pointing the the
136    /// LiveRange immediately after the hole.
137    iterator advanceTo(iterator I, unsigned Pos) {
138      if (Pos >= endNumber())
139        return end();
140      while (I->end <= Pos) ++I;
141      return I;
142    }
143
144    bool containsOneValue() const { return valnos.size() == 1; }
145
146    unsigned getNumValNums() const { return (unsigned)valnos.size(); }
147
148    /// getValNumInfo - Returns pointer to the specified val#.
149    ///
150    inline VNInfo *getValNumInfo(unsigned ValNo) {
151      return valnos[ValNo];
152    }
153    inline const VNInfo *getValNumInfo(unsigned ValNo) const {
154      return valnos[ValNo];
155    }
156
157    /// copyValNumInfo - Copy the value number info for one value number to
158    /// another.
159    void copyValNumInfo(VNInfo *DstValNo, const VNInfo *SrcValNo) {
160      DstValNo->def = SrcValNo->def;
161      DstValNo->copy = SrcValNo->copy;
162      DstValNo->hasPHIKill = SrcValNo->hasPHIKill;
163      DstValNo->kills = SrcValNo->kills;
164    }
165
166    /// getNextValue - Create a new value number and return it.  MIIdx specifies
167    /// the instruction that defines the value number.
168    VNInfo *getNextValue(unsigned MIIdx, MachineInstr *CopyMI,
169                         BumpPtrAllocator &VNInfoAllocator) {
170#ifdef __GNUC__
171      unsigned Alignment = (unsigned)__alignof__(VNInfo);
172#else
173      // FIXME: ugly.
174      unsigned Alignment = 8;
175#endif
176      VNInfo *VNI =
177        static_cast<VNInfo*>(VNInfoAllocator.Allocate((unsigned)sizeof(VNInfo),
178                                                      Alignment));
179      new (VNI) VNInfo((unsigned)valnos.size(), MIIdx, CopyMI);
180      valnos.push_back(VNI);
181      return VNI;
182    }
183
184    /// addKillForValNum - Add a kill instruction index to the specified value
185    /// number.
186    static void addKill(VNInfo *VNI, unsigned KillIdx) {
187      SmallVector<unsigned, 4> &kills = VNI->kills;
188      if (kills.empty()) {
189        kills.push_back(KillIdx);
190      } else {
191        SmallVector<unsigned, 4>::iterator
192          I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
193        kills.insert(I, KillIdx);
194      }
195    }
196
197    /// addKills - Add a number of kills into the VNInfo kill vector. If this
198    /// interval is live at a kill point, then the kill is not added.
199    void addKills(VNInfo *VNI, const SmallVector<unsigned, 4> &kills) {
200      for (unsigned i = 0, e = static_cast<unsigned>(kills.size());
201           i != e; ++i) {
202        unsigned KillIdx = kills[i];
203        if (!liveBeforeAndAt(KillIdx)) {
204          SmallVector<unsigned, 4>::iterator
205            I = std::lower_bound(VNI->kills.begin(), VNI->kills.end(), KillIdx);
206          VNI->kills.insert(I, KillIdx);
207        }
208      }
209    }
210
211    /// removeKill - Remove the specified kill from the list of kills of
212    /// the specified val#.
213    static bool removeKill(VNInfo *VNI, unsigned KillIdx) {
214      SmallVector<unsigned, 4> &kills = VNI->kills;
215      SmallVector<unsigned, 4>::iterator
216        I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
217      if (I != kills.end() && *I == KillIdx) {
218        kills.erase(I);
219        return true;
220      }
221      return false;
222    }
223
224    /// removeKills - Remove all the kills in specified range
225    /// [Start, End] of the specified val#.
226    void removeKills(VNInfo *VNI, unsigned Start, unsigned End) {
227      SmallVector<unsigned, 4> &kills = VNI->kills;
228      SmallVector<unsigned, 4>::iterator
229        I = std::lower_bound(kills.begin(), kills.end(), Start);
230      SmallVector<unsigned, 4>::iterator
231        E = std::upper_bound(kills.begin(), kills.end(), End);
232      kills.erase(I, E);
233    }
234
235    /// isKill - Return true if the specified index is a kill of the
236    /// specified val#.
237    bool isKill(const VNInfo *VNI, unsigned KillIdx) const {
238      const SmallVector<unsigned, 4> &kills = VNI->kills;
239      SmallVector<unsigned, 4>::const_iterator
240        I = std::lower_bound(kills.begin(), kills.end(), KillIdx);
241      return I != kills.end() && *I == KillIdx;
242    }
243
244    /// MergeValueNumberInto - This method is called when two value nubmers
245    /// are found to be equivalent.  This eliminates V1, replacing all
246    /// LiveRanges with the V1 value number with the V2 value number.  This can
247    /// cause merging of V1/V2 values numbers and compaction of the value space.
248    void MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
249
250    /// MergeInClobberRanges - For any live ranges that are not defined in the
251    /// current interval, but are defined in the Clobbers interval, mark them
252    /// used with an unknown definition value. Caller must pass in reference to
253    /// VNInfoAllocator since it will create a new val#.
254    void MergeInClobberRanges(const LiveInterval &Clobbers,
255                              BumpPtrAllocator &VNInfoAllocator);
256
257    /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
258    /// in RHS into this live interval as the specified value number.
259    /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
260    /// current interval, it will replace the value numbers of the overlaped
261    /// live ranges with the specified value number.
262    void MergeRangesInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo);
263
264    /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
265    /// in RHS into this live interval as the specified value number.
266    /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
267    /// current interval, but only if the overlapping LiveRanges have the
268    /// specified value number.
269    void MergeValueInAsValue(const LiveInterval &RHS,
270                             const VNInfo *RHSValNo, VNInfo *LHSValNo);
271
272    /// Copy - Copy the specified live interval. This copies all the fields
273    /// except for the register of the interval.
274    void Copy(const LiveInterval &RHS, BumpPtrAllocator &VNInfoAllocator);
275
276    bool empty() const { return ranges.empty(); }
277
278    /// beginNumber - Return the lowest numbered slot covered by interval.
279    unsigned beginNumber() const {
280      if (empty())
281        return 0;
282      return ranges.front().start;
283    }
284
285    /// endNumber - return the maximum point of the interval of the whole,
286    /// exclusive.
287    unsigned endNumber() const {
288      if (empty())
289        return 0;
290      return ranges.back().end;
291    }
292
293    bool expiredAt(unsigned index) const {
294      return index >= endNumber();
295    }
296
297    bool liveAt(unsigned index) const;
298
299    // liveBeforeAndAt - Check if the interval is live at the index and the
300    // index just before it. If index is liveAt, check if it starts a new live
301    // range.If it does, then check if the previous live range ends at index-1.
302    bool liveBeforeAndAt(unsigned index) const;
303
304    /// getLiveRangeContaining - Return the live range that contains the
305    /// specified index, or null if there is none.
306    const LiveRange *getLiveRangeContaining(unsigned Idx) const {
307      const_iterator I = FindLiveRangeContaining(Idx);
308      return I == end() ? 0 : &*I;
309    }
310
311    /// FindLiveRangeContaining - Return an iterator to the live range that
312    /// contains the specified index, or end() if there is none.
313    const_iterator FindLiveRangeContaining(unsigned Idx) const;
314
315    /// FindLiveRangeContaining - Return an iterator to the live range that
316    /// contains the specified index, or end() if there is none.
317    iterator FindLiveRangeContaining(unsigned Idx);
318
319    /// overlaps - Return true if the intersection of the two live intervals is
320    /// not empty.
321    bool overlaps(const LiveInterval& other) const {
322      return overlapsFrom(other, other.begin());
323    }
324
325    /// overlapsFrom - Return true if the intersection of the two live intervals
326    /// is not empty.  The specified iterator is a hint that we can begin
327    /// scanning the Other interval starting at I.
328    bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
329
330    /// addRange - Add the specified LiveRange to this interval, merging
331    /// intervals as appropriate.  This returns an iterator to the inserted live
332    /// range (which may have grown since it was inserted.
333    void addRange(LiveRange LR) {
334      addRangeFrom(LR, ranges.begin());
335    }
336
337    /// join - Join two live intervals (this, and other) together.  This applies
338    /// mappings to the value numbers in the LHS/RHS intervals as specified.  If
339    /// the intervals are not joinable, this aborts.
340    void join(LiveInterval &Other, const int *ValNoAssignments,
341              const int *RHSValNoAssignments,
342              SmallVector<VNInfo*, 16> &NewVNInfo);
343
344    /// removeRange - Remove the specified range from this interval.  Note that
345    /// the range must already be in this interval in its entirety.
346    void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false);
347
348    void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
349      removeRange(LR.start, LR.end, RemoveDeadValNo);
350    }
351
352    /// removeValNo - Remove all the ranges defined by the specified value#.
353    /// Also remove the value# from value# list.
354    void removeValNo(VNInfo *ValNo);
355
356    /// getSize - Returns the sum of sizes of all the LiveRange's.
357    ///
358    unsigned getSize() const;
359
360    bool operator<(const LiveInterval& other) const {
361      return beginNumber() < other.beginNumber();
362    }
363
364    void print(std::ostream &OS, const TargetRegisterInfo *TRI = 0) const;
365    void print(std::ostream *OS, const TargetRegisterInfo *TRI = 0) const {
366      if (OS) print(*OS, TRI);
367    }
368    void dump() const;
369
370  private:
371    Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
372    void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
373    Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
374    LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
375  };
376
377  inline std::ostream &operator<<(std::ostream &OS, const LiveInterval &LI) {
378    LI.print(OS);
379    return OS;
380  }
381}
382
383#endif
384