@@ -110,6 +110,14 @@ class OperatorRelationsTable {
110
110
111
111
RangeSet::ContainerType RangeSet::Factory::EmptySet{};
112
112
113
+ RangeSet RangeSet::Factory::add (RangeSet LHS, RangeSet RHS) {
114
+ ContainerType Result;
115
+ Result.reserve (LHS.size () + RHS.size ());
116
+ std::merge (LHS.begin (), LHS.end (), RHS.begin (), RHS.end (),
117
+ std::back_inserter (Result));
118
+ return makePersistent (std::move (Result));
119
+ }
120
+
113
121
RangeSet RangeSet::Factory::add (RangeSet Original, Range Element) {
114
122
ContainerType Result;
115
123
Result.reserve (Original.size () + 1 );
@@ -126,6 +134,186 @@ RangeSet RangeSet::Factory::add(RangeSet Original, const llvm::APSInt &Point) {
126
134
return add (Original, Range (Point));
127
135
}
128
136
137
+ RangeSet RangeSet::Factory::unite (RangeSet LHS, RangeSet RHS) {
138
+ ContainerType Result = unite (*LHS.Impl , *RHS.Impl );
139
+ return makePersistent (std::move (Result));
140
+ }
141
+
142
+ RangeSet RangeSet::Factory::unite (RangeSet Original, Range R) {
143
+ ContainerType Result;
144
+ Result.push_back (R);
145
+ Result = unite (*Original.Impl , Result);
146
+ return makePersistent (std::move (Result));
147
+ }
148
+
149
+ RangeSet RangeSet::Factory::unite (RangeSet Original, llvm::APSInt Point) {
150
+ return unite (Original, Range (ValueFactory.getValue (Point)));
151
+ }
152
+
153
+ RangeSet RangeSet::Factory::unite (RangeSet Original, llvm::APSInt From,
154
+ llvm::APSInt To) {
155
+ return unite (Original,
156
+ Range (ValueFactory.getValue (From), ValueFactory.getValue (To)));
157
+ }
158
+
159
+ template <typename T>
160
+ void swapIterators (T &First, T &FirstEnd, T &Second, T &SecondEnd) {
161
+ std::swap (First, Second);
162
+ std::swap (FirstEnd, SecondEnd);
163
+ }
164
+
165
+ RangeSet::ContainerType RangeSet::Factory::unite (const ContainerType &LHS,
166
+ const ContainerType &RHS) {
167
+ if (LHS.empty ())
168
+ return RHS;
169
+ if (RHS.empty ())
170
+ return LHS;
171
+
172
+ using llvm::APSInt;
173
+ using iterator = ContainerType::const_iterator;
174
+
175
+ iterator First = LHS.begin ();
176
+ iterator FirstEnd = LHS.end ();
177
+ iterator Second = RHS.begin ();
178
+ iterator SecondEnd = RHS.end ();
179
+ APSIntType Ty = APSIntType (First->From ());
180
+ const APSInt Min = Ty.getMinValue ();
181
+
182
+ // Handle a corner case first when both range sets start from MIN.
183
+ // This helps to avoid complicated conditions below. Specifically, this
184
+ // particular check for `MIN` is not needed in the loop below every time
185
+ // when we do `Second->From() - One` operation.
186
+ if (Min == First->From () && Min == Second->From ()) {
187
+ if (First->To () > Second->To ()) {
188
+ // [ First ]--->
189
+ // [ Second ]----->
190
+ // MIN^
191
+ // The Second range is entirely inside the First one.
192
+
193
+ // Check if Second is the last in its RangeSet.
194
+ if (++Second == SecondEnd)
195
+ // [ First ]--[ First + 1 ]--->
196
+ // [ Second ]--------------------->
197
+ // MIN^
198
+ // The Union is equal to First's RangeSet.
199
+ return LHS;
200
+ } else {
201
+ // case 1: [ First ]----->
202
+ // case 2: [ First ]--->
203
+ // [ Second ]--->
204
+ // MIN^
205
+ // The First range is entirely inside or equal to the Second one.
206
+
207
+ // Check if First is the last in its RangeSet.
208
+ if (++First == FirstEnd)
209
+ // [ First ]----------------------->
210
+ // [ Second ]--[ Second + 1 ]---->
211
+ // MIN^
212
+ // The Union is equal to Second's RangeSet.
213
+ return RHS;
214
+ }
215
+ }
216
+
217
+ const APSInt One = Ty.getValue (1 );
218
+ ContainerType Result;
219
+
220
+ // This is called when there are no ranges left in one of the ranges.
221
+ // Append the rest of the ranges from another range set to the Result
222
+ // and return with that.
223
+ const auto AppendTheRest = [&Result](iterator I, iterator E) {
224
+ Result.append (I, E);
225
+ return Result;
226
+ };
227
+
228
+ while (true ) {
229
+ // We want to keep the following invariant at all times:
230
+ // ---[ First ------>
231
+ // -----[ Second --->
232
+ if (First->From () > Second->From ())
233
+ swapIterators (First, FirstEnd, Second, SecondEnd);
234
+
235
+ // The Union definitely starts with First->From().
236
+ // ----------[ First ------>
237
+ // ------------[ Second --->
238
+ // ----------[ Union ------>
239
+ // UnionStart^
240
+ const llvm::APSInt &UnionStart = First->From ();
241
+
242
+ // Loop where the invariant holds.
243
+ while (true ) {
244
+ // Skip all enclosed ranges.
245
+ // ---[ First ]--->
246
+ // -----[ Second ]--[ Second + 1 ]--[ Second + N ]----->
247
+ while (First->To () >= Second->To ()) {
248
+ // Check if Second is the last in its RangeSet.
249
+ if (++Second == SecondEnd) {
250
+ // Append the Union.
251
+ // ---[ Union ]--->
252
+ // -----[ Second ]----->
253
+ // --------[ First ]--->
254
+ // UnionEnd^
255
+ Result.emplace_back (UnionStart, First->To ());
256
+ // ---[ Union ]----------------->
257
+ // --------------[ First + 1]--->
258
+ // Append all remaining ranges from the First's RangeSet.
259
+ return AppendTheRest (++First, FirstEnd);
260
+ }
261
+ }
262
+
263
+ // Check if First and Second are disjoint. It means that we find
264
+ // the end of the Union. Exit the loop and append the Union.
265
+ // ---[ First ]=------------->
266
+ // ------------=[ Second ]--->
267
+ // ----MinusOne^
268
+ if (First->To () < Second->From () - One)
269
+ break ;
270
+
271
+ // First is entirely inside the Union. Go next.
272
+ // ---[ Union ----------->
273
+ // ---- [ First ]-------->
274
+ // -------[ Second ]----->
275
+ // Check if First is the last in its RangeSet.
276
+ if (++First == FirstEnd) {
277
+ // Append the Union.
278
+ // ---[ Union ]--->
279
+ // -----[ First ]------->
280
+ // --------[ Second ]--->
281
+ // UnionEnd^
282
+ Result.emplace_back (UnionStart, Second->To ());
283
+ // ---[ Union ]------------------>
284
+ // --------------[ Second + 1]--->
285
+ // Append all remaining ranges from the Second's RangeSet.
286
+ return AppendTheRest (++Second, SecondEnd);
287
+ }
288
+
289
+ // We know that we are at one of the two cases:
290
+ // case 1: --[ First ]--------->
291
+ // case 2: ----[ First ]------->
292
+ // --------[ Second ]---------->
293
+ // In both cases First starts after Second->From().
294
+ // Make sure that the loop invariant holds.
295
+ swapIterators (First, FirstEnd, Second, SecondEnd);
296
+ }
297
+
298
+ // Here First and Second are disjoint.
299
+ // Append the Union.
300
+ // ---[ Union ]--------------->
301
+ // -----------------[ Second ]--->
302
+ // ------[ First ]--------------->
303
+ // UnionEnd^
304
+ Result.emplace_back (UnionStart, First->To ());
305
+
306
+ // Check if First is the last in its RangeSet.
307
+ if (++First == FirstEnd)
308
+ // ---[ Union ]--------------->
309
+ // --------------[ Second ]--->
310
+ // Append all remaining ranges from the Second's RangeSet.
311
+ return AppendTheRest (Second, SecondEnd);
312
+ }
313
+
314
+ llvm_unreachable (" Normally, we should not reach here" );
315
+ }
316
+
129
317
RangeSet RangeSet::Factory::getRangeSet (Range From) {
130
318
ContainerType Result;
131
319
Result.push_back (From);
@@ -155,13 +343,6 @@ RangeSet::ContainerType *RangeSet::Factory::construct(ContainerType &&From) {
155
343
return new (Buffer) ContainerType (std::move (From));
156
344
}
157
345
158
- RangeSet RangeSet::Factory::add (RangeSet LHS, RangeSet RHS) {
159
- ContainerType Result;
160
- std::merge (LHS.begin (), LHS.end (), RHS.begin (), RHS.end (),
161
- std::back_inserter (Result));
162
- return makePersistent (std::move (Result));
163
- }
164
-
165
346
const llvm::APSInt &RangeSet::getMinValue () const {
166
347
assert (!isEmpty ());
167
348
return begin ()->From ();
@@ -325,11 +506,6 @@ RangeSet RangeSet::Factory::intersect(const RangeSet::ContainerType &LHS,
325
506
const_iterator First = LHS.begin (), Second = RHS.begin (),
326
507
FirstEnd = LHS.end (), SecondEnd = RHS.end ();
327
508
328
- const auto SwapIterators = [&First, &FirstEnd, &Second, &SecondEnd]() {
329
- std::swap (First, Second);
330
- std::swap (FirstEnd, SecondEnd);
331
- };
332
-
333
509
// If we ran out of ranges in one set, but not in the other,
334
510
// it means that those elements are definitely not in the
335
511
// intersection.
@@ -339,7 +515,7 @@ RangeSet RangeSet::Factory::intersect(const RangeSet::ContainerType &LHS,
339
515
// ----[ First ---------------------->
340
516
// --------[ Second ----------------->
341
517
if (Second->From () < First->From ())
342
- SwapIterators ( );
518
+ swapIterators (First, FirstEnd, Second, SecondEnd );
343
519
344
520
// Loop where the invariant holds:
345
521
do {
@@ -373,7 +549,7 @@ RangeSet RangeSet::Factory::intersect(const RangeSet::ContainerType &LHS,
373
549
if (Second->To () > First->To ()) {
374
550
// Here we make a decision to keep First as the "longer"
375
551
// range.
376
- SwapIterators ( );
552
+ swapIterators (First, FirstEnd, Second, SecondEnd );
377
553
}
378
554
379
555
// At this point, we have the following situation:
0 commit comments