llvm.org GIT mirror llvm / abf295f
Little stuff: * Fix comment typeo * add dump() methods * add a few new methods like getLiveRangeContaining, removeRange & joinable (which is currently the same as overlaps) * Remove the unused operator== Bigger change: * In LiveInterval, instead of using a boolean isDefinedOnce to keep track of if there are > 1 definitions in a particular interval, keep a counter, NumValues to keep track of exactly how many there are. * In LiveRange, add a new ValId element to indicate which of the numbered values each LiveRange belongs to. We now no longer merge LiveRanges if they are of differing value ID's even if they are neighbors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15152 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 15 years ago
3 changed file(s) with 206 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
99 // This file implements the LiveRange and LiveInterval classes. Given some
1010 // numbering of each the machine instructions an interval [i, j) is said to be a
1111 // live interval for register v if there is no instruction with number j' > j
12 // such that v is live at j' abd there is no instruction with number i' < i such
12 // such that v is live at j' and there is no instruction with number i' < i such
1313 // that v is live at i'. In this implementation intervals can have holes,
1414 // i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
1515 // individual range is represented as an instance of LiveRange, and the whole
3030 /// These ranges are rendered as [start,end).
3131 struct LiveRange {
3232 unsigned start; // Start point of the interval (inclusive)
33 unsigned end; // End point of the interval (exclusive)
34 LiveRange(unsigned S, unsigned E) : start(S), end(E) {
33 unsigned end; // End point of the interval (exclusive)
34 unsigned ValId; // identifier for the value contained in this interval.
35
36 LiveRange(unsigned S, unsigned E, unsigned V) : start(S), end(E), ValId(V) {
3537 assert(S < E && "Cannot create empty or backwards range");
3638 }
3739
4749 bool operator==(const LiveRange &LR) const {
4850 return start == LR.start && end == LR.end;
4951 }
52
53 void dump() const;
54
5055 private:
5156 LiveRange(); // DO NOT IMPLEMENT
5257 };
6570 unsigned reg; // the register of this interval
6671 float weight; // weight of this interval
6772 Ranges ranges; // the ranges in which this register is live
68 bool isDefinedOnce; // True if this interval contains one value.
6973
7074 LiveInterval(unsigned Reg, float Weight)
71 : reg(Reg), weight(Weight), isDefinedOnce(false) {
75 : reg(Reg), weight(Weight), NumValues(0) {
7276 }
7377
74 bool containsOneValue() const { return isDefinedOnce; }
78 bool containsOneValue() const { return NumValues == 1; }
79
80 unsigned getNextValue() {
81 return NumValues++;
82 }
7583
7684 bool empty() const { return ranges.empty(); }
7785
94102
95103 bool liveAt(unsigned index) const;
96104
105 /// getLiveRangeContaining - Return the live range that contains the
106 /// specified index, or null if there is none.
107 LiveRange *getLiveRangeContaining(unsigned Idx);
108
109
110 /// joinable - Two intervals are joinable if the either don't overlap at all
111 /// or if the destination of the copy is a single assignment value, and it
112 /// only overlaps with one value in the source interval.
113 bool joinable(const LiveInterval& other, unsigned CopyIdx) const;
114
115
97116 bool overlaps(const LiveInterval& other) const;
98117
99118 /// addRange - Add the specified LiveRange to this interval, merging
103122 addRangeFrom(LR, ranges.begin());
104123 }
105124
106 void join(const LiveInterval& other);
125 /// join - Join two live intervals (this, and other) together. This
126 /// operation is the result of a copy instruction in the source program,
127 /// that occurs at index 'CopyIdx' that copies from 'other' to 'this'. This
128 /// destroys 'other'.
129 void join(LiveInterval& other, unsigned CopyIdx);
130
131
132 /// removeRange - Remove the specified range from this interval. Note that
133 /// the range must already be in this interval in its entirety.
134 void removeRange(unsigned Start, unsigned End);
107135
108136 bool operator<(const LiveInterval& other) const {
109137 return start() < other.start();
110138 }
111139
112 bool operator==(const LiveInterval& other) const {
113 return reg == other.reg;
114 }
140 void dump() const;
115141
116142 private:
143 unsigned NumValues; // the number of distinct values in this interval.
117144 Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
118145 void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
119146 Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
1919
2020 #include "LiveInterval.h"
2121 #include "Support/STLExtras.h"
22 #include <ostream>
22 #include <iostream>
23 #include
2324 using namespace llvm;
2425
2526 // An example for liveAt():
8687 return false;
8788 }
8889
90 /// joinable - Two intervals are joinable if the either don't overlap at all
91 /// or if the destination of the copy is a single assignment value, and it
92 /// only overlaps with one value in the source interval.
93 bool LiveInterval::joinable(const LiveInterval &other, unsigned CopyIdx) const {
94 return overlaps(other);
95 }
96
97
8998 /// extendIntervalEndTo - This method is used when we want to extend the range
9099 /// specified by I to end at the specified endpoint. To do this, we should
91100 /// merge and eliminate all ranges that this will overlap with. The iterator is
92101 /// not invalidated.
93102 void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) {
94103 assert(I != ranges.end() && "Not a valid interval!");
104 unsigned ValId = I->ValId;
95105
96106 // Search for the first interval that we can't merge with.
97107 Ranges::iterator MergeTo = next(I);
98 for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo)
99 /*empty*/;
108 for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo) {
109 assert(MergeTo->ValId == ValId && "Cannot merge with differing values!");
110 }
100111
101112 // If NewEnd was in the middle of an interval, make sure to get its endpoint.
102113 I->end = std::max(NewEnd, prior(MergeTo)->end);
112123 LiveInterval::Ranges::iterator
113124 LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) {
114125 assert(I != ranges.end() && "Not a valid interval!");
126 unsigned ValId = I->ValId;
115127
116128 // Search for the first interval that we can't merge with.
117129 Ranges::iterator MergeTo = I;
118130 do {
119131 if (MergeTo == ranges.begin()) {
120132 I->start = NewStart;
133 ranges.erase(MergeTo, I);
121134 return I;
122135 }
136 assert(MergeTo->ValId == ValId && "Cannot merge with differing values!");
123137 --MergeTo;
124138 } while (NewStart <= MergeTo->start);
125139
126140 // If we start in the middle of another interval, just delete a range and
127141 // extend that interval.
128 if (MergeTo->end >= NewStart) {
142 if (MergeTo->end >= NewStart && MergeTo->ValId == ValId) {
129143 MergeTo->end = I->end;
130144 } else {
131145 // Otherwise, extend the interval right after.
147161 // another interval, just extend that interval to contain the range of LR.
148162 if (it != ranges.begin()) {
149163 Ranges::iterator B = prior(it);
150 if (B->start <= Start && B->end >= Start) {
151 extendIntervalEndTo(B, End);
152 return B;
164 if (LR.ValId == B->ValId) {
165 if (B->start <= Start && B->end >= Start) {
166 extendIntervalEndTo(B, End);
167 return B;
168 }
169 } else {
170 // Check to make sure that we are not overlapping two live ranges with
171 // different ValId's.
172 assert(B->end <= Start &&
173 "Cannot overlap two LiveRanges with differing ValID's");
153174 }
154175 }
155176
156177 // Otherwise, if this range ends in the middle of, or right next to, another
157178 // interval, merge it into that interval.
158 if (it != ranges.end() && it->start <= End)
159 return extendIntervalStartTo(it, Start);
179 if (it != ranges.end())
180 if (LR.ValId == it->ValId) {
181 if (it->start <= End) {
182 it = extendIntervalStartTo(it, Start);
183
184 // If LR is a complete superset of an interval, we may need to grow its
185 // endpoint as well.
186 if (End > it->end)
187 extendIntervalEndTo(it, End);
188 return it;
189 }
190 } else {
191 // Check to make sure that we are not overlapping two live ranges with
192 // different ValId's.
193 assert(it->start >= End &&
194 "Cannot overlap two LiveRanges with differing ValID's");
195 }
160196
161197 // Otherwise, this is just a new range that doesn't interact with anything.
162198 // Insert it.
163199 return ranges.insert(it, LR);
164200 }
165201
166 void LiveInterval::join(const LiveInterval& other) {
167 isDefinedOnce &= other.isDefinedOnce;
202
203 /// removeRange - Remove the specified range from this interval. Note that
204 /// the range must already be in this interval in its entirety.
205 void LiveInterval::removeRange(unsigned Start, unsigned End) {
206 // Find the LiveRange containing this span.
207 Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start);
208 assert(I != ranges.begin() && "Range is not in interval!");
209 --I;
210 assert(I->contains(Start) && I->contains(End-1) &&
211 "Range is not entirely in interval!");
212
213 // If the span we are removing is at the start of the LiveRange, adjust it.
214 if (I->start == Start) {
215 if (I->end == End)
216 ranges.erase(I); // Removed the whole LiveRange.
217 else
218 I->start = End;
219 return;
220 }
221
222 // Otherwise if the span we are removing is at the end of the LiveRange,
223 // adjust the other way.
224 if (I->end == End) {
225 I->start = Start;
226 return;
227 }
228
229 // Otherwise, we are splitting the LiveRange into two pieces.
230 unsigned OldEnd = I->end;
231 I->end = Start; // Trim the old interval.
232
233 // Insert the new one.
234 ranges.insert(next(I), LiveRange(End, OldEnd, I->ValId));
235 }
236
237 /// getLiveRangeContaining - Return the live range that contains the
238 /// specified index, or null if there is none.
239 LiveRange *LiveInterval::getLiveRangeContaining(unsigned Idx) {
240 Ranges::iterator It = std::upper_bound(ranges.begin(), ranges.end(), Idx);
241 if (It != ranges.begin()) {
242 LiveRange &LR = *prior(It);
243 if (LR.contains(Idx))
244 return &LR;
245 }
246
247 return 0;
248 }
249
250
251
252 /// join - Join two live intervals (this, and other) together. This operation
253 /// is the result of a copy instruction in the source program, that occurs at
254 /// index 'CopyIdx' that copies from 'Other' to 'this'.
255 void LiveInterval::join(LiveInterval &Other, unsigned CopyIdx) {
256 LiveRange *SourceLR = Other.getLiveRangeContaining(CopyIdx-1);
257 LiveRange *DestLR = getLiveRangeContaining(CopyIdx);
258 assert(SourceLR && DestLR && "Not joining due to a copy?");
259 unsigned MergedSrcValIdx = SourceLR->ValId;
260 unsigned MergedDstValIdx = DestLR->ValId;
168261
169262 // Join the ranges of other into the ranges of this interval.
170 Ranges::iterator cur = ranges.begin();
171 for (Ranges::const_iterator i = other.ranges.begin(),
172 e = other.ranges.end(); i != e; ++i)
173 cur = addRangeFrom(*i, cur);
174
175 weight += other.weight;
263 Ranges::iterator InsertPos = ranges.begin();
264 std::map Dst2SrcIdxMap;
265 for (Ranges::iterator I = Other.ranges.begin(),
266 E = Other.ranges.end(); I != E; ++I) {
267 // Map the ValId in the other live range to the current live range.
268 if (I->ValId == MergedSrcValIdx)
269 I->ValId = MergedDstValIdx;
270 else {
271 unsigned &NV = Dst2SrcIdxMap[I->ValId];
272 if (NV == 0) NV = getNextValue();
273 I->ValId = NV;
274 }
275
276 InsertPos = addRangeFrom(*I, InsertPos);
277 }
278
279 weight += Other.weight;
176280 }
177281
178282 std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
179 return os << "[" << LR.start << "," << LR.end << ")";
180 }
283 return os << '[' << LR.start << ',' << LR.end << ':' << LR.ValId << ")";
284 }
285
286 void LiveRange::dump() const {
287 std::cerr << *this << "\n";
288 }
289
181290
182291 std::ostream& llvm::operator<<(std::ostream& os, const LiveInterval& li) {
183292 os << "%reg" << li.reg << ',' << li.weight;
190299 os << *i;
191300 return os;
192301 }
302
303 void LiveInterval::dump() const {
304 std::cerr << *this << "\n";
305 }
99 // This file implements the LiveRange and LiveInterval classes. Given some
1010 // numbering of each the machine instructions an interval [i, j) is said to be a
1111 // live interval for register v if there is no instruction with number j' > j
12 // such that v is live at j' abd there is no instruction with number i' < i such
12 // such that v is live at j' and there is no instruction with number i' < i such
1313 // that v is live at i'. In this implementation intervals can have holes,
1414 // i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
1515 // individual range is represented as an instance of LiveRange, and the whole
3030 /// These ranges are rendered as [start,end).
3131 struct LiveRange {
3232 unsigned start; // Start point of the interval (inclusive)
33 unsigned end; // End point of the interval (exclusive)
34 LiveRange(unsigned S, unsigned E) : start(S), end(E) {
33 unsigned end; // End point of the interval (exclusive)
34 unsigned ValId; // identifier for the value contained in this interval.
35
36 LiveRange(unsigned S, unsigned E, unsigned V) : start(S), end(E), ValId(V) {
3537 assert(S < E && "Cannot create empty or backwards range");
3638 }
3739
4749 bool operator==(const LiveRange &LR) const {
4850 return start == LR.start && end == LR.end;
4951 }
52
53 void dump() const;
54
5055 private:
5156 LiveRange(); // DO NOT IMPLEMENT
5257 };
6570 unsigned reg; // the register of this interval
6671 float weight; // weight of this interval
6772 Ranges ranges; // the ranges in which this register is live
68 bool isDefinedOnce; // True if this interval contains one value.
6973
7074 LiveInterval(unsigned Reg, float Weight)
71 : reg(Reg), weight(Weight), isDefinedOnce(false) {
75 : reg(Reg), weight(Weight), NumValues(0) {
7276 }
7377
74 bool containsOneValue() const { return isDefinedOnce; }
78 bool containsOneValue() const { return NumValues == 1; }
79
80 unsigned getNextValue() {
81 return NumValues++;
82 }
7583
7684 bool empty() const { return ranges.empty(); }
7785
94102
95103 bool liveAt(unsigned index) const;
96104
105 /// getLiveRangeContaining - Return the live range that contains the
106 /// specified index, or null if there is none.
107 LiveRange *getLiveRangeContaining(unsigned Idx);
108
109
110 /// joinable - Two intervals are joinable if the either don't overlap at all
111 /// or if the destination of the copy is a single assignment value, and it
112 /// only overlaps with one value in the source interval.
113 bool joinable(const LiveInterval& other, unsigned CopyIdx) const;
114
115
97116 bool overlaps(const LiveInterval& other) const;
98117
99118 /// addRange - Add the specified LiveRange to this interval, merging
103122 addRangeFrom(LR, ranges.begin());
104123 }
105124
106 void join(const LiveInterval& other);
125 /// join - Join two live intervals (this, and other) together. This
126 /// operation is the result of a copy instruction in the source program,
127 /// that occurs at index 'CopyIdx' that copies from 'other' to 'this'. This
128 /// destroys 'other'.
129 void join(LiveInterval& other, unsigned CopyIdx);
130
131
132 /// removeRange - Remove the specified range from this interval. Note that
133 /// the range must already be in this interval in its entirety.
134 void removeRange(unsigned Start, unsigned End);
107135
108136 bool operator<(const LiveInterval& other) const {
109137 return start() < other.start();
110138 }
111139
112 bool operator==(const LiveInterval& other) const {
113 return reg == other.reg;
114 }
140 void dump() const;
115141
116142 private:
143 unsigned NumValues; // the number of distinct values in this interval.
117144 Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
118145 void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
119146 Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);