LLVM  4.0.0
LiveIntervalUnion.cpp
Go to the documentation of this file.
1 //===-- LiveIntervalUnion.cpp - Live interval union data structure --------===//
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 // LiveIntervalUnion represents a coalesced set of live intervals. This may be
11 // used during coalescing to represent a congruence class, or during register
12 // allocation to model liveness of a physical register.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Support/Debug.h"
22 #include <algorithm>
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "regalloc"
27 
28 
29 // Merge a LiveInterval's segments. Guarantee no overlaps.
30 void LiveIntervalUnion::unify(LiveInterval &VirtReg, const LiveRange &Range) {
31  if (Range.empty())
32  return;
33  ++Tag;
34 
35  // Insert each of the virtual register's live segments into the map.
36  LiveRange::const_iterator RegPos = Range.begin();
37  LiveRange::const_iterator RegEnd = Range.end();
38  SegmentIter SegPos = Segments.find(RegPos->start);
39 
40  while (SegPos.valid()) {
41  SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
42  if (++RegPos == RegEnd)
43  return;
44  SegPos.advanceTo(RegPos->start);
45  }
46 
47  // We have reached the end of Segments, so it is no longer necessary to search
48  // for the insertion position.
49  // It is faster to insert the end first.
50  --RegEnd;
51  SegPos.insert(RegEnd->start, RegEnd->end, &VirtReg);
52  for (; RegPos != RegEnd; ++RegPos, ++SegPos)
53  SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
54 }
55 
56 // Remove a live virtual register's segments from this union.
57 void LiveIntervalUnion::extract(LiveInterval &VirtReg, const LiveRange &Range) {
58  if (Range.empty())
59  return;
60  ++Tag;
61 
62  // Remove each of the virtual register's live segments from the map.
63  LiveRange::const_iterator RegPos = Range.begin();
64  LiveRange::const_iterator RegEnd = Range.end();
65  SegmentIter SegPos = Segments.find(RegPos->start);
66 
67  for (;;) {
68  assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval");
69  SegPos.erase();
70  if (!SegPos.valid())
71  return;
72 
73  // Skip all segments that may have been coalesced.
74  RegPos = Range.advanceTo(RegPos, SegPos.start());
75  if (RegPos == RegEnd)
76  return;
77 
78  SegPos.advanceTo(RegPos->start);
79  }
80 }
81 
82 void
84  if (empty()) {
85  OS << " empty\n";
86  return;
87  }
88  for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) {
89  OS << " [" << SI.start() << ' ' << SI.stop() << "):"
90  << PrintReg(SI.value()->reg, TRI);
91  }
92  OS << '\n';
93 }
94 
95 #ifndef NDEBUG
96 // Verify the live intervals in this union and add them to the visited set.
98  for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI)
99  VisitedVRegs.set(SI.value()->reg);
100 }
101 #endif //!NDEBUG
102 
103 // Scan the vector of interfering virtual registers in this union. Assume it's
104 // quite small.
106  return is_contained(InterferingVRegs, VirtReg);
107 }
108 
109 // Collect virtual registers in this union that interfere with this
110 // query's live virtual register.
111 //
112 // The query state is one of:
113 //
114 // 1. CheckedFirstInterference == false: Iterators are uninitialized.
115 // 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused.
116 // 3. Iterators left at the last seen intersection.
117 //
119 collectInterferingVRegs(unsigned MaxInterferingRegs) {
120  // Fast path return if we already have the desired information.
121  if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
122  return InterferingVRegs.size();
123 
124  // Set up iterators on the first call.
125  if (!CheckedFirstInterference) {
126  CheckedFirstInterference = true;
127 
128  // Quickly skip interference check for empty sets.
129  if (VirtReg->empty() || LiveUnion->empty()) {
130  SeenAllInterferences = true;
131  return 0;
132  }
133 
134  // In most cases, the union will start before VirtReg.
135  VirtRegI = VirtReg->begin();
136  LiveUnionI.setMap(LiveUnion->getMap());
137  LiveUnionI.find(VirtRegI->start);
138  }
139 
140  LiveInterval::iterator VirtRegEnd = VirtReg->end();
141  LiveInterval *RecentReg = nullptr;
142  while (LiveUnionI.valid()) {
143  assert(VirtRegI != VirtRegEnd && "Reached end of VirtReg");
144 
145  // Check for overlapping interference.
146  while (VirtRegI->start < LiveUnionI.stop() &&
147  VirtRegI->end > LiveUnionI.start()) {
148  // This is an overlap, record the interfering register.
149  LiveInterval *VReg = LiveUnionI.value();
150  if (VReg != RecentReg && !isSeenInterference(VReg)) {
151  RecentReg = VReg;
152  InterferingVRegs.push_back(VReg);
153  if (InterferingVRegs.size() >= MaxInterferingRegs)
154  return InterferingVRegs.size();
155  }
156  // This LiveUnion segment is no longer interesting.
157  if (!(++LiveUnionI).valid()) {
158  SeenAllInterferences = true;
159  return InterferingVRegs.size();
160  }
161  }
162 
163  // The iterators are now not overlapping, LiveUnionI has been advanced
164  // beyond VirtRegI.
165  assert(VirtRegI->end <= LiveUnionI.start() && "Expected non-overlap");
166 
167  // Advance the iterator that ends first.
168  VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start());
169  if (VirtRegI == VirtRegEnd)
170  break;
171 
172  // Detect overlap, handle above.
173  if (VirtRegI->start < LiveUnionI.stop())
174  continue;
175 
176  // Still not overlapping. Catch up LiveUnionI.
177  LiveUnionI.advanceTo(VirtRegI->start);
178  }
179  SeenAllInterferences = true;
180  return InterferingVRegs.size();
181 }
182 
184  unsigned NSize) {
185  // Reuse existing allocation.
186  if (NSize == Size)
187  return;
188  clear();
189  Size = NSize;
190  LIUs = static_cast<LiveIntervalUnion*>(
191  malloc(sizeof(LiveIntervalUnion)*NSize));
192  for (unsigned i = 0; i != Size; ++i)
193  new(LIUs + i) LiveIntervalUnion(Alloc);
194 }
195 
197  if (!LIUs)
198  return;
199  for (unsigned i = 0; i != Size; ++i)
200  LIUs[i].~LiveIntervalUnion();
201  free(LIUs);
202  Size = 0;
203  LIUs = nullptr;
204 }
const_iterator begin() const
Definition: IntervalMap.h:1102
LiveIntervalUnion(Allocator &a)
size_t i
void set(unsigned Idx)
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:625
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position...
Definition: LiveInterval.h:246
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end()...
Definition: IntervalMap.h:1128
size_t size() const
Definition: LiveInterval.h:280
bool empty() const
Definition: LiveInterval.h:357
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:153
iterator end()
Definition: LiveInterval.h:206
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
Union of live intervals that are strong candidates for coalescing into a single register (either phys...
void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const
bool isSeenInterference(LiveInterval *VReg) const
NDEBUG.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void unify(LiveInterval &VirtReg, const LiveRange &Range)
void init(LiveIntervalUnion::Allocator &, unsigned Size)
LiveSegments::iterator SegmentIter
void verify(LiveVirtRegBitSet &VisitedVRegs)
unsigned collectInterferingVRegs(unsigned MaxInterferingRegs=UINT_MAX)
void extract(LiveInterval &VirtReg, const LiveRange &Range)
iterator begin()
Definition: LiveInterval.h:205
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:783