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,7 +116,7 @@ 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 (); }
119
122
@@ -122,8 +125,8 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
122
125
123
126
void Profile (llvm::FoldingSetNodeID &ID) const {
124
127
assert (!Data.empty () && " Should not profile empty ImmutablePointerSet" );
125
- for (PtrTy P : Data) {
126
- ID.AddPointer (P );
128
+ for (T P : Data) {
129
+ ID.AddPointer (PtrTraits::getAsVoidPointer (P) );
127
130
}
128
131
}
129
132
@@ -177,10 +180,11 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
177
180
}
178
181
};
179
182
180
- template <typename T> class ImmutablePointerSetFactory {
181
- using PtrTy = typename std::add_pointer<T>::type;
182
-
183
+ template <typename T>
184
+ class ImmutablePointerSetFactory {
183
185
using PtrSet = ImmutablePointerSet<T>;
186
+ using PtrTraits = typename PtrSet::PtrTraits;
187
+
184
188
// This is computed out-of-line so that ImmutablePointerSetFactory is
185
189
// treated as a complete type.
186
190
static const unsigned AllocAlignment;
@@ -205,7 +209,7 @@ template <typename T> class ImmutablePointerSetFactory {
205
209
206
210
// / Given a sorted and uniqued list \p Array, return the ImmutablePointerSet
207
211
// / containing Array. Asserts if \p Array is not sorted and uniqued.
208
- PtrSet *get (llvm::ArrayRef<PtrTy > Array) {
212
+ PtrSet *get (llvm::ArrayRef<T > Array) {
209
213
if (Array.empty ())
210
214
return ImmutablePointerSetFactory::getEmptySet ();
211
215
@@ -215,8 +219,8 @@ template <typename T> class ImmutablePointerSetFactory {
215
219
assert (is_sorted_and_uniqued (Array));
216
220
217
221
llvm::FoldingSetNodeID ID;
218
- for (PtrTy Ptr : Array) {
219
- ID.AddPointer (Ptr);
222
+ for (T Ptr : Array) {
223
+ ID.AddPointer (PtrTraits::getAsVoidPointer ( Ptr) );
220
224
}
221
225
222
226
void *InsertPt;
@@ -225,7 +229,7 @@ template <typename T> class ImmutablePointerSetFactory {
225
229
}
226
230
227
231
size_t NumElts = Array.size ();
228
- size_t MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
232
+ size_t MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
229
233
230
234
// Allocate the memory.
231
235
auto *Mem =
@@ -234,8 +238,8 @@ template <typename T> class ImmutablePointerSetFactory {
234
238
// Copy in the pointers into the tail allocated memory. We do not need to do
235
239
// any sorting/uniquing ourselves since we assume that our users perform
236
240
// this task for us.
237
- llvm::MutableArrayRef<PtrTy > DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
238
- NumElts);
241
+ llvm::MutableArrayRef<void * > DataMem (reinterpret_cast <void * *>(&Mem[1 ]),
242
+ NumElts);
239
243
std::copy (Array.begin (), Array.end (), DataMem.begin ());
240
244
241
245
// Allocate the new node and insert it into the Set.
@@ -244,7 +248,35 @@ template <typename T> class ImmutablePointerSetFactory {
244
248
return NewNode;
245
249
}
246
250
247
- PtrSet *merge (PtrSet *S1, llvm::ArrayRef<PtrTy> S2) {
251
+ PtrSet *get (T value) {
252
+ llvm::FoldingSetNodeID ID;
253
+ ID.AddPointer (PtrTraits::getAsVoidPointer (value));
254
+
255
+ void *InsertPt;
256
+ if (auto *PSet = Set.FindNodeOrInsertPos (ID, InsertPt)) {
257
+ return PSet;
258
+ }
259
+
260
+ size_t NumElts = 1 ;
261
+ size_t MemSize = sizeof (PtrSet) + sizeof (T) * NumElts;
262
+
263
+ // Allocate the memory.
264
+ auto *Mem =
265
+ reinterpret_cast <PtrSet *>(Allocator.Allocate (MemSize, AllocAlignment));
266
+
267
+ // Copy in the pointers into the tail allocated memory. We do not need to do
268
+ // any sorting/uniquing ourselves since we assume that our users perform
269
+ // this task for us.
270
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
271
+ DataMem[0 ] = value;
272
+
273
+ // Allocate the new node and insert it into the Set.
274
+ auto *NewNode = new (Mem) PtrSet (this , DataMem);
275
+ Set.InsertNode (NewNode, InsertPt);
276
+ return NewNode;
277
+ }
278
+
279
+ PtrSet *merge (PtrSet *S1, llvm::ArrayRef<T> S2) {
248
280
if (S1->empty ())
249
281
return get (S2);
250
282
@@ -266,7 +298,7 @@ template <typename T> class ImmutablePointerSetFactory {
266
298
// perform a sorted set merging algorithm to create the ID. We also count
267
299
// the number of unique elements for allocation purposes.
268
300
unsigned NumElts = 0 ;
269
- set_union_for_each (*S1, S2, [&ID, &NumElts](const PtrTy Ptr) -> void {
301
+ set_union_for_each (*S1, S2, [&ID, &NumElts](const T Ptr) -> void {
270
302
ID.AddPointer (Ptr);
271
303
NumElts++;
272
304
});
@@ -277,7 +309,7 @@ template <typename T> class ImmutablePointerSetFactory {
277
309
return PSet;
278
310
}
279
311
280
- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
312
+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
281
313
282
314
// Allocate the memory.
283
315
auto *Mem =
@@ -286,8 +318,7 @@ template <typename T> class ImmutablePointerSetFactory {
286
318
// Copy in the union of the two pointer sets into the tail allocated
287
319
// memory. Since we know that our sorted arrays are uniqued, we can use
288
320
// set_union to get the uniqued sorted array that we want.
289
- llvm::MutableArrayRef<PtrTy> DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
290
- NumElts);
321
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
291
322
std::set_union (S1->begin (), S1->end (), S2.begin (), S2.end (),
292
323
DataMem.begin ());
293
324
@@ -316,8 +347,8 @@ template <typename T> class ImmutablePointerSetFactory {
316
347
// perform a sorted set merging algorithm to create the ID. We also count
317
348
// the number of unique elements for allocation purposes.
318
349
unsigned NumElts = 0 ;
319
- set_union_for_each (*S1, *S2, [&ID, &NumElts](const PtrTy Ptr) -> void {
320
- ID.AddPointer (Ptr);
350
+ set_union_for_each (*S1, *S2, [&ID, &NumElts](const T Ptr) -> void {
351
+ ID.AddPointer (PtrTraits::getAsVoidPointer ( Ptr) );
321
352
NumElts++;
322
353
});
323
354
@@ -327,7 +358,7 @@ template <typename T> class ImmutablePointerSetFactory {
327
358
return PSet;
328
359
}
329
360
330
- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
361
+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
331
362
332
363
// Allocate the memory.
333
364
auto *Mem =
@@ -336,8 +367,7 @@ template <typename T> class ImmutablePointerSetFactory {
336
367
// Copy in the union of the two pointer sets into the tail allocated
337
368
// memory. Since we know that our sorted arrays are uniqued, we can use
338
369
// set_union to get the uniqued sorted array that we want.
339
- llvm::MutableArrayRef<PtrTy> DataMem (reinterpret_cast <PtrTy *>(&Mem[1 ]),
340
- NumElts);
370
+ llvm::MutableArrayRef<T> DataMem (reinterpret_cast <T *>(&Mem[1 ]), NumElts);
341
371
std::set_union (S1->begin (), S1->end (), S2->begin (), S2->end (),
342
372
DataMem.begin ());
343
373
@@ -356,8 +386,8 @@ template <typename T>
356
386
#if !defined(_MSC_VER) || defined(__clang__)
357
387
constexpr
358
388
#endif
359
- const unsigned ImmutablePointerSetFactory<T>::AllocAlignment =
360
- (alignof (PtrSet) > alignof (PtrTy )) ? alignof(PtrSet) : alignof(PtrTy );
389
+ const unsigned ImmutablePointerSetFactory<T>::AllocAlignment =
390
+ (alignof (PtrSet) > alignof (T )) ? alignof(PtrSet) : alignof(T );
361
391
362
392
} // end swift namespace
363
393
0 commit comments