llvm.org GIT mirror llvm / b26c215
Change addRange and join to be a little bit smarter. In particular, we don't want to insert a new range into the middle of the vector, then delete ranges one at a time next to the inserted one as they are merged. Instead, if the inserted interval overlaps, just start merging. The only time we insert into the middle of the vector is when we don't overlap at all. Also delete blocks of live ranges if we overlap with many of them. This patch speeds up joining by .7 seconds on a large testcase, but more importantly gets all of the range adding code into addRangeFrom. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15141 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 15 years ago
3 changed file(s) with 97 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
9696
9797 bool overlaps(const LiveInterval& other) const;
9898
99 void addRange(LiveRange R);
99 /// addRange - Add the specified LiveRange to this interval, merging
100 /// intervals as appropriate. This returns an iterator to the inserted live
101 /// range (which may have grown since it was inserted.
102 void addRange(LiveRange LR) {
103 addRangeFrom(LR, ranges.begin());
104 }
100105
101106 void join(const LiveInterval& other);
102107
109114 }
110115
111116 private:
112 Ranges::iterator mergeRangesForward(Ranges::iterator it);
113 Ranges::iterator mergeRangesBackward(Ranges::iterator it);
117 Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
118 void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
119 Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
114120 };
115121
116122 std::ostream& operator<<(std::ostream& os, const LiveInterval& li);
8686 return false;
8787 }
8888
89 void LiveInterval::addRange(LiveRange LR) {
90 Ranges::iterator it =
91 ranges.insert(std::upper_bound(ranges.begin(), ranges.end(), LR.start), LR);
89 /// extendIntervalEndTo - This method is used when we want to extend the range
90 /// specified by I to end at the specified endpoint. To do this, we should
91 /// merge and eliminate all ranges that this will overlap with. The iterator is
92 /// not invalidated.
93 void LiveInterval::extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd) {
94 assert(I != ranges.end() && "Not a valid interval!");
9295
93 mergeRangesBackward(mergeRangesForward(it));
96 // Search for the first interval that we can't merge with.
97 Ranges::iterator MergeTo = next(I);
98 for (; MergeTo != ranges.end() && NewEnd >= MergeTo->end; ++MergeTo)
99 /*empty*/;
100
101 // If NewEnd was in the middle of an interval, make sure to get its endpoint.
102 I->end = std::max(NewEnd, prior(MergeTo)->end);
103
104 // Erase any dead ranges
105 ranges.erase(next(I), MergeTo);
106 }
107
108
109 /// extendIntervalStartTo - This method is used when we want to extend the range
110 /// specified by I to start at the specified endpoint. To do this, we should
111 /// merge and eliminate all ranges that this will overlap with.
112 LiveInterval::Ranges::iterator
113 LiveInterval::extendIntervalStartTo(Ranges::iterator I, unsigned NewStart) {
114 assert(I != ranges.end() && "Not a valid interval!");
115
116 // Search for the first interval that we can't merge with.
117 Ranges::iterator MergeTo = I;
118 do {
119 if (MergeTo == ranges.begin()) {
120 I->start = NewStart;
121 return I;
122 }
123 --MergeTo;
124 } while (NewStart <= MergeTo->start);
125
126 // If we start in the middle of another interval, just delete a range and
127 // extend that interval.
128 if (MergeTo->end >= NewStart) {
129 MergeTo->end = I->end;
130 } else {
131 // Otherwise, extend the interval right after.
132 ++MergeTo;
133 MergeTo->start = NewStart;
134 MergeTo->end = I->end;
135 }
136
137 ranges.erase(next(MergeTo), next(I));
138 return MergeTo;
139 }
140
141 LiveInterval::Ranges::iterator
142 LiveInterval::addRangeFrom(LiveRange LR, Ranges::iterator From) {
143 unsigned Start = LR.start, End = LR.end;
144 Ranges::iterator it = std::upper_bound(From, ranges.end(), Start);
145
146 // If the inserted interval starts in the middle or right at the end of
147 // another interval, just extend that interval to contain the range of LR.
148 if (it != ranges.begin()) {
149 Ranges::iterator B = prior(it);
150 if (B->start <= Start && B->end >= Start) {
151 extendIntervalEndTo(B, End);
152 return B;
153 }
154 }
155
156 // Otherwise, if this range ends in the middle of, or right next to, another
157 // interval, merge it into that interval.
158 if (it != ranges.end() && it->start <= End)
159 return extendIntervalStartTo(it, Start);
160
161 // Otherwise, this is just a new range that doesn't interact with anything.
162 // Insert it.
163 return ranges.insert(it, LR);
94164 }
95165
96166 void LiveInterval::join(const LiveInterval& other) {
97 Ranges::iterator cur = ranges.begin();
98167 isDefinedOnce &= other.isDefinedOnce;
99168
169 // Join the ranges of other into the ranges of this interval.
170 Ranges::iterator cur = ranges.begin();
100171 for (Ranges::const_iterator i = other.ranges.begin(),
101 e = other.ranges.end(); i != e; ++i) {
102 cur = ranges.insert(std::upper_bound(cur, ranges.end(), i->start), *i);
103 cur = mergeRangesBackward(mergeRangesForward(cur));
104 }
172 e = other.ranges.end(); i != e; ++i)
173 cur = addRangeFrom(*i, cur);
174
105175 weight += other.weight;
106 }
107
108 LiveInterval::Ranges::iterator
109 LiveInterval::mergeRangesForward(Ranges::iterator it) {
110 Ranges::iterator n;
111 while ((n = next(it)) != ranges.end()) {
112 if (n->start > it->end)
113 break;
114 it->end = std::max(it->end, n->end);
115 n = ranges.erase(n);
116 }
117 return it;
118 }
119
120 LiveInterval::Ranges::iterator
121 LiveInterval::mergeRangesBackward(Ranges::iterator it) {
122 while (it != ranges.begin()) {
123 Ranges::iterator p = prior(it);
124 if (it->start > p->end)
125 break;
126
127 it->start = std::min(it->start, p->start);
128 it->end = std::max(it->end, p->end);
129 it = ranges.erase(p);
130 }
131
132 return it;
133176 }
134177
135178 std::ostream& llvm::operator<<(std::ostream& os, const LiveRange &LR) {
9696
9797 bool overlaps(const LiveInterval& other) const;
9898
99 void addRange(LiveRange R);
99 /// addRange - Add the specified LiveRange to this interval, merging
100 /// intervals as appropriate. This returns an iterator to the inserted live
101 /// range (which may have grown since it was inserted.
102 void addRange(LiveRange LR) {
103 addRangeFrom(LR, ranges.begin());
104 }
100105
101106 void join(const LiveInterval& other);
102107
109114 }
110115
111116 private:
112 Ranges::iterator mergeRangesForward(Ranges::iterator it);
113 Ranges::iterator mergeRangesBackward(Ranges::iterator it);
117 Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
118 void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
119 Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
114120 };
115121
116122 std::ostream& operator<<(std::ostream& os, const LiveInterval& li);