LLVM  8.0.1
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"
22 #include <cassert>
23 #include <cstdlib>
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "regalloc"
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  while (true) {
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 (LR->empty() || LiveUnion->empty()) {
130  SeenAllInterferences = true;
131  return 0;
132  }
133 
134  // In most cases, the union will start before LR.
135  LRI = LR->begin();
136  LiveUnionI.setMap(LiveUnion->getMap());
137  LiveUnionI.find(LRI->start);
138  }
139 
140  LiveRange::const_iterator LREnd = LR->end();
141  LiveInterval *RecentReg = nullptr;
142  while (LiveUnionI.valid()) {
143  assert(LRI != LREnd && "Reached end of LR");
144 
145  // Check for overlapping interference.
146  while (LRI->start < LiveUnionI.stop() && LRI->end > LiveUnionI.start()) {
147  // This is an overlap, record the interfering register.
148  LiveInterval *VReg = LiveUnionI.value();
149  if (VReg != RecentReg && !isSeenInterference(VReg)) {
150  RecentReg = VReg;
151  InterferingVRegs.push_back(VReg);
152  if (InterferingVRegs.size() >= MaxInterferingRegs)
153  return InterferingVRegs.size();
154  }
155  // This LiveUnion segment is no longer interesting.
156  if (!(++LiveUnionI).valid()) {
157  SeenAllInterferences = true;
158  return InterferingVRegs.size();
159  }
160  }
161 
162  // The iterators are now not overlapping, LiveUnionI has been advanced
163  // beyond LRI.
164  assert(LRI->end <= LiveUnionI.start() && "Expected non-overlap");
165 
166  // Advance the iterator that ends first.
167  LRI = LR->advanceTo(LRI, LiveUnionI.start());
168  if (LRI == LREnd)
169  break;
170 
171  // Detect overlap, handle above.
172  if (LRI->start < LiveUnionI.stop())
173  continue;
174 
175  // Still not overlapping. Catch up LiveUnionI.
176  LiveUnionI.advanceTo(LRI->start);
177  }
178  SeenAllInterferences = true;
179  return InterferingVRegs.size();
180 }
181 
183  unsigned NSize) {
184  // Reuse existing allocation.
185  if (NSize == Size)
186  return;
187  clear();
188  Size = NSize;
189  LIUs = static_cast<LiveIntervalUnion*>(
190  safe_malloc(sizeof(LiveIntervalUnion)*NSize));
191  for (unsigned i = 0; i != Size; ++i)
192  new(LIUs + i) LiveIntervalUnion(Alloc);
193 }
194 
196  if (!LIUs)
197  return;
198  for (unsigned i = 0; i != Size; ++i)
199  LIUs[i].~LiveIntervalUnion();
200  free(LIUs);
201  Size = 0;
202  LIUs = nullptr;
203 }
bool empty() const
Definition: LiveInterval.h:370
LiveIntervalUnion(Allocator &a)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void set(unsigned Idx)
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:638
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position...
Definition: LiveInterval.h:259
unsigned const TargetRegisterInfo * TRI
bool valid() const
valid - Return true if the current position is valid, false for end().
Definition: IntervalMap.h:1359
const_iterator begin() const
Definition: IntervalMap.h:1100
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:157
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
iterator end()
Definition: LiveInterval.h:212
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
Definition: IntervalMap.h:1443
void erase()
erase - Erase the current interval.
Definition: IntervalMap.h:1871
size_t size() const
Definition: LiveInterval.h:293
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:1126
unsigned collectInterferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())
const KeyT & start() const
start - Return the beginning of the current interval.
Definition: IntervalMap.h:1365
Union of live intervals that are strong candidates for coalescing into a single register (either phys...
LiveSegments::Allocator Allocator
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
Definition: MemAlloc.h:26
void unify(LiveInterval &VirtReg, const LiveRange &Range)
void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const
Segments::const_iterator const_iterator
Definition: LiveInterval.h:209
void init(LiveIntervalUnion::Allocator &, unsigned Size)
const ValT & value() const
value - Return the mapped value at the current interval.
Definition: IntervalMap.h:1371
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
Definition: IntervalMap.h:1782
void verify(LiveVirtRegBitSet &VisitedVRegs)
uint32_t Size
Definition: Profile.cpp:47
void extract(LiveInterval &VirtReg, const LiveRange &Range)
bool isSeenInterference(LiveInterval *VirtReg) const
NDEBUG.
iterator begin()
Definition: LiveInterval.h:211
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:46
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:1245