1 //===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // LiveIntervalUnion is a union of live segments across multiple live virtual
11 // registers. This may be used during coalescing to represent a congruence
12 // class, or during register allocation to model liveness of a physical
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CODEGEN_LIVEINTERVALUNION
18 #define LLVM_CODEGEN_LIVEINTERVALUNION
20 #include "llvm/ADT/IntervalMap.h"
21 #include "llvm/CodeGen/LiveInterval.h"
27 class MachineLoopRange
;
28 class TargetRegisterInfo
;
31 // forward declaration
32 template <unsigned Element
> class SparseBitVector
;
33 typedef SparseBitVector
<128> LiveVirtRegBitSet
;
36 /// Compare a live virtual register segment to a LiveIntervalUnion segment.
38 overlap(const LiveRange
&VRSeg
,
39 const IntervalMap
<SlotIndex
, LiveInterval
*>::const_iterator
&LUSeg
) {
40 return VRSeg
.start
< LUSeg
.stop() && LUSeg
.start() < VRSeg
.end
;
43 /// Union of live intervals that are strong candidates for coalescing into a
44 /// single register (either physical or virtual depending on the context). We
45 /// expect the constituent live intervals to be disjoint, although we may
46 /// eventually make exceptions to handle value-based interference.
47 class LiveIntervalUnion
{
48 // A set of live virtual register segments that supports fast insertion,
49 // intersection, and removal.
50 // Mapping SlotIndex intervals to virtual register numbers.
51 typedef IntervalMap
<SlotIndex
, LiveInterval
*> LiveSegments
;
54 // SegmentIter can advance to the next segment ordered by starting position
55 // which may belong to a different live virtual register. We also must be able
56 // to reach the current segment's containing virtual register.
57 typedef LiveSegments::iterator SegmentIter
;
59 // LiveIntervalUnions share an external allocator.
60 typedef LiveSegments::Allocator Allocator
;
62 class InterferenceResult
;
66 const unsigned RepReg
; // representative register number
67 unsigned Tag
; // unique tag for current contents.
68 LiveSegments Segments
; // union of virtual reg segments
71 LiveIntervalUnion(unsigned r
, Allocator
&a
) : RepReg(r
), Tag(0), Segments(a
)
74 // Iterate over all segments in the union of live virtual registers ordered
75 // by their starting position.
76 SegmentIter
begin() { return Segments
.begin(); }
77 SegmentIter
end() { return Segments
.end(); }
78 SegmentIter
find(SlotIndex x
) { return Segments
.find(x
); }
79 bool empty() const { return Segments
.empty(); }
80 SlotIndex
startIndex() const { return Segments
.start(); }
82 // Provide public access to the underlying map to allow overlap iteration.
83 typedef LiveSegments Map
;
84 const Map
&getMap() { return Segments
; }
86 /// getTag - Return an opaque tag representing the current state of the union.
87 unsigned getTag() const { return Tag
; }
89 /// changedSince - Return true if the union change since getTag returned tag.
90 bool changedSince(unsigned tag
) const { return tag
!= Tag
; }
92 // Add a live virtual register to this union and merge its segments.
93 void unify(LiveInterval
&VirtReg
);
95 // Remove a live virtual register's segments from this union.
96 void extract(LiveInterval
&VirtReg
);
98 // Print union, using TRI to translate register names
99 void print(raw_ostream
&OS
, const TargetRegisterInfo
*TRI
) const;
102 // Verify the live intervals in this union and add them to the visited set.
103 void verify(LiveVirtRegBitSet
& VisitedVRegs
);
106 /// Cache a single interference test result in the form of two intersecting
107 /// segments. This allows efficiently iterating over the interferences. The
108 /// iteration logic is handled by LiveIntervalUnion::Query which may
109 /// filter interferences depending on the type of query.
110 class InterferenceResult
{
113 LiveInterval::iterator VirtRegI
; // current position in VirtReg
114 SegmentIter LiveUnionI
; // current position in LiveUnion
117 InterferenceResult(LiveInterval::iterator VRegI
, SegmentIter UnionI
)
118 : VirtRegI(VRegI
), LiveUnionI(UnionI
) {}
121 // Public default ctor.
122 InterferenceResult(): VirtRegI(), LiveUnionI() {}
124 /// start - Return the start of the current overlap.
125 SlotIndex
start() const {
126 return std::max(VirtRegI
->start
, LiveUnionI
.start());
129 /// stop - Return the end of the current overlap.
130 SlotIndex
stop() const {
131 return std::min(VirtRegI
->end
, LiveUnionI
.stop());
134 /// interference - Return the register that is interfering here.
135 LiveInterval
*interference() const { return LiveUnionI
.value(); }
137 // Note: this interface provides raw access to the iterators because the
138 // result has no way to tell if it's valid to dereference them.
140 // Access the VirtReg segment.
141 LiveInterval::iterator
virtRegPos() const { return VirtRegI
; }
143 // Access the LiveUnion segment.
144 const SegmentIter
&liveUnionPos() const { return LiveUnionI
; }
146 bool operator==(const InterferenceResult
&IR
) const {
147 return VirtRegI
== IR
.VirtRegI
&& LiveUnionI
== IR
.LiveUnionI
;
149 bool operator!=(const InterferenceResult
&IR
) const {
150 return !operator==(IR
);
153 void print(raw_ostream
&OS
, const TargetRegisterInfo
*TRI
) const;
156 /// Query interferences between a single live virtual register and a live
159 LiveIntervalUnion
*LiveUnion
;
160 LiveInterval
*VirtReg
;
161 InterferenceResult FirstInterference
;
162 SmallVector
<LiveInterval
*,4> InterferingVRegs
;
163 bool CheckedFirstInterference
;
164 bool SeenAllInterferences
;
165 bool SeenUnspillableVReg
;
166 unsigned Tag
, UserTag
;
169 Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
171 Query(LiveInterval
*VReg
, LiveIntervalUnion
*LIU
):
172 LiveUnion(LIU
), VirtReg(VReg
), CheckedFirstInterference(false),
173 SeenAllInterferences(false), SeenUnspillableVReg(false)
179 InterferingVRegs
.clear();
180 CheckedFirstInterference
= false;
181 SeenAllInterferences
= false;
182 SeenUnspillableVReg
= false;
187 void init(unsigned UTag
, LiveInterval
*VReg
, LiveIntervalUnion
*LIU
) {
188 assert(VReg
&& LIU
&& "Invalid arguments");
189 if (UserTag
== UTag
&& VirtReg
== VReg
&&
190 LiveUnion
== LIU
&& !LIU
->changedSince(Tag
)) {
191 // Retain cached results, e.g. firstInterference.
201 LiveInterval
&virtReg() const {
202 assert(VirtReg
&& "uninitialized");
206 bool isInterference(const InterferenceResult
&IR
) const {
207 if (IR
.VirtRegI
!= VirtReg
->end()) {
208 assert(overlap(*IR
.VirtRegI
, IR
.LiveUnionI
) &&
209 "invalid segment iterators");
215 // Does this live virtual register interfere with the union?
216 bool checkInterference() { return isInterference(firstInterference()); }
218 // Get the first pair of interfering segments, or a noninterfering result.
219 // This initializes the firstInterference_ cache.
220 const InterferenceResult
&firstInterference();
222 // Treat the result as an iterator and advance to the next interfering pair
223 // of segments. Visiting each unique interfering pairs means that the same
224 // VirtReg or LiveUnion segment may be visited multiple times.
225 bool nextInterference(InterferenceResult
&IR
) const;
227 // Count the virtual registers in this union that interfere with this
228 // query's live virtual register, up to maxInterferingRegs.
229 unsigned collectInterferingVRegs(unsigned MaxInterferingRegs
= UINT_MAX
);
231 // Was this virtual register visited during collectInterferingVRegs?
232 bool isSeenInterference(LiveInterval
*VReg
) const;
234 // Did collectInterferingVRegs collect all interferences?
235 bool seenAllInterferences() const { return SeenAllInterferences
; }
237 // Did collectInterferingVRegs encounter an unspillable vreg?
238 bool seenUnspillableVReg() const { return SeenUnspillableVReg
; }
240 // Vector generated by collectInterferingVRegs.
241 const SmallVectorImpl
<LiveInterval
*> &interferingVRegs() const {
242 return InterferingVRegs
;
245 /// checkLoopInterference - Return true if there is interference overlapping
247 bool checkLoopInterference(MachineLoopRange
*);
249 void print(raw_ostream
&OS
, const TargetRegisterInfo
*TRI
);
251 Query(const Query
&); // DO NOT IMPLEMENT
252 void operator=(const Query
&); // DO NOT IMPLEMENT
254 // Private interface for queries
255 void findIntersection(InterferenceResult
&IR
) const;
259 } // end namespace llvm
261 #endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION)