58
58
59
59
namespace swift {
60
60
61
- template <typename PtrTy> class ImmutablePointerSetFactory ;
61
+ template <typename T>
62
+ class ImmutablePointerSetFactory ;
62
63
63
64
// / An immutable set of pointers. It is backed by a tail allocated sorted array
64
65
// / ref.
65
- template <typename T> class ImmutablePointerSet : public llvm ::FoldingSetNode {
66
- using PtrTy = typename std::add_pointer<T>::type;
66
+ template <typename T>
67
+ class ImmutablePointerSet : public llvm ::FoldingSetNode {
67
68
friend class ImmutablePointerSetFactory <T>;
68
69
70
+ using PtrTraits = llvm::PointerLikeTypeTraits<T>;
71
+
69
72
NullablePtr<ImmutablePointerSetFactory<T>> ParentFactory;
70
- llvm::ArrayRef<PtrTy > Data;
73
+ llvm::ArrayRef<T > Data;
71
74
72
75
ImmutablePointerSet (ImmutablePointerSetFactory<T> *ParentFactory,
73
- llvm::ArrayRef<PtrTy > NewData)
76
+ llvm::ArrayRef<T > NewData)
74
77
: ParentFactory(ParentFactory), Data(NewData) {}
75
78
76
79
public:
@@ -100,7 +103,7 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
100
103
return !(*this == P);
101
104
}
102
105
103
- unsigned count (PtrTy Ptr) const {
106
+ unsigned count (T Ptr) const {
104
107
// This returns the first element >= Ptr. Since we know that our array is
105
108
// sorted and uniqued, Ptr must be that element.
106
109
auto LowerBound = std::lower_bound (begin (), end (), Ptr);
@@ -113,17 +116,19 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
113
116
return *LowerBound == Ptr;
114
117
}
115
118
116
- using iterator = typename llvm::ArrayRef<PtrTy >::iterator;
119
+ using iterator = typename llvm::ArrayRef<T >::iterator;
117
120
iterator begin () const { return Data.begin (); }
118
121
iterator end () const { return Data.end (); }
122
+ llvm::iterator_range<iterator> range () const { return {begin (), end ()}; }
123
+ llvm::ArrayRef<T> data () const { return Data; }
119
124
120
125
unsigned size () const { return Data.size (); }
121
126
bool empty () const { return Data.empty (); }
122
127
123
128
void Profile (llvm::FoldingSetNodeID &ID) const {
124
129
assert (!Data.empty () && " Should not profile empty ImmutablePointerSet" );
125
- for (PtrTy P : Data) {
126
- ID.AddPointer (P );
130
+ for (T P : Data) {
131
+ ID.AddPointer (PtrTraits::getAsVoidPointer (P) );
127
132
}
128
133
}
129
134
@@ -177,10 +182,11 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
177
182
}
178
183
};
179
184
180
- template <typename T> class ImmutablePointerSetFactory {
181
- using PtrTy = typename std::add_pointer<T>::type;
182
-
185
+ template <typename T>
186
+ class ImmutablePointerSetFactory {
183
187
using PtrSet = ImmutablePointerSet<T>;
188
+ using PtrTraits = typename PtrSet::PtrTraits;
189
+
184
190
// This is computed out-of-line so that ImmutablePointerSetFactory is
185
191
// treated as a complete type.
186
192
static const unsigned AllocAlignment;
@@ -205,7 +211,7 @@ template <typename T> class ImmutablePointerSetFactory {
205
211
206
212
// / Given a sorted and uniqued list \p Array, return the ImmutablePointerSet
207
213
// / containing Array. Asserts if \p Array is not sorted and uniqued.
208
- PtrSet *get (llvm::ArrayRef<PtrTy > Array) {
214
+ PtrSet *get (llvm::ArrayRef<T > Array) {
209
215
if (Array.empty ())
210
216
return ImmutablePointerSetFactory::getEmptySet ();
211
217
@@ -215,8 +221,8 @@ template <typename T> class ImmutablePointerSetFactory {
215
221
assert (is_sorted_and_uniqued (Array));
216
222
217
223
llvm::FoldingSetNodeID ID;
218
- for (PtrTy Ptr : Array) {
219
- ID.AddPointer (Ptr);
224
+ for (T Ptr : Array) {
225
+ ID.AddPointer (PtrTraits::getAsVoidPointer ( Ptr) );
220
226
}
221
227
222
228
void *InsertPt;
@@ -225,7 +231,7 @@ template <typename T> class ImmutablePointerSetFactory {
225
231
}
226
232
227
233
size_t NumElts = Array.size ();
228
- size_t MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
234
+ size_t MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
229
235
230
236
// Allocate the memory.
231
237
auto *Mem =
@@ -234,8 +240,8 @@ template <typename T> class ImmutablePointerSetFactory {
234
240
// Copy in the pointers into the tail allocated memory. We do not need to do
235
241
// any sorting/uniquing ourselves since we assume that our users perform
236
242
// this task for us.
237
- llvm::MutableArrayRef<PtrTy > DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
238
- NumElts);
243
+ llvm::MutableArrayRef<T > DataMem (reinterpret_cast <T *>(&Mem[1 ]),
244
+ NumElts);
239
245
std::copy (Array.begin (), Array.end (), DataMem.begin ());
240
246
241
247
// Allocate the new node and insert it into the Set.
@@ -244,7 +250,35 @@ template <typename T> class ImmutablePointerSetFactory {
244
250
return NewNode;
245
251
}
246
252
247
- PtrSet *merge (PtrSet *S1, llvm::ArrayRef<PtrTy> S2) {
253
+ PtrSet *get (T value) {
254
+ llvm::FoldingSetNodeID ID;
255
+ ID.AddPointer (PtrTraits::getAsVoidPointer (value));
256
+
257
+ void *InsertPt;
258
+ if (auto *PSet = Set.FindNodeOrInsertPos (ID, InsertPt)) {
259
+ return PSet;
260
+ }
261
+
262
+ size_t NumElts = 1 ;
263
+ size_t MemSize = sizeof (PtrSet) + sizeof (T) * NumElts;
264
+
265
+ // Allocate the memory.
266
+ auto *Mem =
267
+ reinterpret_cast <PtrSet *>(Allocator.Allocate (MemSize, AllocAlignment));
268
+
269
+ // Copy in the pointers into the tail allocated memory. We do not need to do
270
+ // any sorting/uniquing ourselves since we assume that our users perform
271
+ // this task for us.
272
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
273
+ DataMem[0 ] = value;
274
+
275
+ // Allocate the new node and insert it into the Set.
276
+ auto *NewNode = new (Mem) PtrSet (this , DataMem);
277
+ Set.InsertNode (NewNode, InsertPt);
278
+ return NewNode;
279
+ }
280
+
281
+ PtrSet *merge (PtrSet *S1, llvm::ArrayRef<T> S2) {
248
282
if (S1->empty ())
249
283
return get (S2);
250
284
@@ -266,7 +300,7 @@ template <typename T> class ImmutablePointerSetFactory {
266
300
// perform a sorted set merging algorithm to create the ID. We also count
267
301
// the number of unique elements for allocation purposes.
268
302
unsigned NumElts = 0 ;
269
- set_union_for_each (*S1, S2, [&ID, &NumElts](const PtrTy Ptr) -> void {
303
+ set_union_for_each (*S1, S2, [&ID, &NumElts](const T Ptr) -> void {
270
304
ID.AddPointer (Ptr);
271
305
NumElts++;
272
306
});
@@ -277,7 +311,7 @@ template <typename T> class ImmutablePointerSetFactory {
277
311
return PSet;
278
312
}
279
313
280
- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
314
+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
281
315
282
316
// Allocate the memory.
283
317
auto *Mem =
@@ -286,8 +320,7 @@ template <typename T> class ImmutablePointerSetFactory {
286
320
// Copy in the union of the two pointer sets into the tail allocated
287
321
// memory. Since we know that our sorted arrays are uniqued, we can use
288
322
// set_union to get the uniqued sorted array that we want.
289
- llvm::MutableArrayRef<PtrTy> DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
290
- NumElts);
323
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
291
324
std::set_union (S1->begin (), S1->end (), S2.begin (), S2.end (),
292
325
DataMem.begin ());
293
326
@@ -316,8 +349,8 @@ template <typename T> class ImmutablePointerSetFactory {
316
349
// perform a sorted set merging algorithm to create the ID. We also count
317
350
// the number of unique elements for allocation purposes.
318
351
unsigned NumElts = 0 ;
319
- set_union_for_each (*S1, *S2, [&ID, &NumElts](const PtrTy Ptr) -> void {
320
- ID.AddPointer (Ptr);
352
+ set_union_for_each (*S1, *S2, [&ID, &NumElts](const T Ptr) -> void {
353
+ ID.AddPointer (PtrTraits::getAsVoidPointer ( Ptr) );
321
354
NumElts++;
322
355
});
323
356
@@ -327,7 +360,7 @@ template <typename T> class ImmutablePointerSetFactory {
327
360
return PSet;
328
361
}
329
362
330
- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
363
+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
331
364
332
365
// Allocate the memory.
333
366
auto *Mem =
@@ -336,8 +369,7 @@ template <typename T> class ImmutablePointerSetFactory {
336
369
// Copy in the union of the two pointer sets into the tail allocated
337
370
// memory. Since we know that our sorted arrays are uniqued, we can use
338
371
// set_union to get the uniqued sorted array that we want.
339
- llvm::MutableArrayRef<PtrTy> DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
340
- NumElts);
372
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
341
373
std::set_union (S1->begin (), S1->end (), S2->begin (), S2->end (),
342
374
DataMem.begin ());
343
375
@@ -356,8 +388,8 @@ template <typename T>
356
388
#if !defined(_MSC_VER) || defined(__clang__)
357
389
constexpr
358
390
#endif
359
- const unsigned ImmutablePointerSetFactory<T>::AllocAlignment =
360
- (alignof (PtrSet) > alignof (PtrTy )) ? alignof(PtrSet) : alignof(PtrTy );
391
+ const unsigned ImmutablePointerSetFactory<T>::AllocAlignment =
392
+ (alignof (PtrSet) > alignof (T )) ? alignof(PtrSet) : alignof(T );
361
393
362
394
} // end swift namespace
363
395
0 commit comments