5858
5959namespace swift {
6060
61- template <typename PtrTy> class ImmutablePointerSetFactory ;
61+ template <typename T>
62+ class ImmutablePointerSetFactory ;
6263
6364// / An immutable set of pointers. It is backed by a tail allocated sorted array
6465// / 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 {
6768 friend class ImmutablePointerSetFactory <T>;
6869
70+ using PtrTraits = llvm::PointerLikeTypeTraits<T>;
71+
6972 NullablePtr<ImmutablePointerSetFactory<T>> ParentFactory;
70- llvm::ArrayRef<PtrTy > Data;
73+ llvm::ArrayRef<T > Data;
7174
7275 ImmutablePointerSet (ImmutablePointerSetFactory<T> *ParentFactory,
73- llvm::ArrayRef<PtrTy > NewData)
76+ llvm::ArrayRef<T > NewData)
7477 : ParentFactory(ParentFactory), Data(NewData) {}
7578
7679public:
@@ -100,7 +103,7 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
100103 return !(*this == P);
101104 }
102105
103- unsigned count (PtrTy Ptr) const {
106+ unsigned count (T Ptr) const {
104107 // This returns the first element >= Ptr. Since we know that our array is
105108 // sorted and uniqued, Ptr must be that element.
106109 auto LowerBound = std::lower_bound (begin (), end (), Ptr);
@@ -113,7 +116,7 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
113116 return *LowerBound == Ptr;
114117 }
115118
116- using iterator = typename llvm::ArrayRef<PtrTy >::iterator;
119+ using iterator = typename llvm::ArrayRef<T >::iterator;
117120 iterator begin () const { return Data.begin (); }
118121 iterator end () const { return Data.end (); }
119122
@@ -122,8 +125,8 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
122125
123126 void Profile (llvm::FoldingSetNodeID &ID) const {
124127 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) );
127130 }
128131 }
129132
@@ -177,10 +180,11 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
177180 }
178181};
179182
180- template <typename T> class ImmutablePointerSetFactory {
181- using PtrTy = typename std::add_pointer<T>::type;
182-
183+ template <typename T>
184+ class ImmutablePointerSetFactory {
183185 using PtrSet = ImmutablePointerSet<T>;
186+ using PtrTraits = typename PtrSet::PtrTraits;
187+
184188 // This is computed out-of-line so that ImmutablePointerSetFactory is
185189 // treated as a complete type.
186190 static const unsigned AllocAlignment;
@@ -205,7 +209,7 @@ template <typename T> class ImmutablePointerSetFactory {
205209
206210 // / Given a sorted and uniqued list \p Array, return the ImmutablePointerSet
207211 // / 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) {
209213 if (Array.empty ())
210214 return ImmutablePointerSetFactory::getEmptySet ();
211215
@@ -215,8 +219,8 @@ template <typename T> class ImmutablePointerSetFactory {
215219 assert (is_sorted_and_uniqued (Array));
216220
217221 llvm::FoldingSetNodeID ID;
218- for (PtrTy Ptr : Array) {
219- ID.AddPointer (Ptr);
222+ for (T Ptr : Array) {
223+ ID.AddPointer (PtrTraits::getAsVoidPointer ( Ptr) );
220224 }
221225
222226 void *InsertPt;
@@ -225,7 +229,7 @@ template <typename T> class ImmutablePointerSetFactory {
225229 }
226230
227231 size_t NumElts = Array.size ();
228- size_t MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
232+ size_t MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
229233
230234 // Allocate the memory.
231235 auto *Mem =
@@ -234,8 +238,8 @@ template <typename T> class ImmutablePointerSetFactory {
234238 // Copy in the pointers into the tail allocated memory. We do not need to do
235239 // any sorting/uniquing ourselves since we assume that our users perform
236240 // 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);
239243 std::copy (Array.begin (), Array.end (), DataMem.begin ());
240244
241245 // Allocate the new node and insert it into the Set.
@@ -244,7 +248,35 @@ template <typename T> class ImmutablePointerSetFactory {
244248 return NewNode;
245249 }
246250
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) {
248280 if (S1->empty ())
249281 return get (S2);
250282
@@ -266,7 +298,7 @@ template <typename T> class ImmutablePointerSetFactory {
266298 // perform a sorted set merging algorithm to create the ID. We also count
267299 // the number of unique elements for allocation purposes.
268300 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 {
270302 ID.AddPointer (Ptr);
271303 NumElts++;
272304 });
@@ -277,7 +309,7 @@ template <typename T> class ImmutablePointerSetFactory {
277309 return PSet;
278310 }
279311
280- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
312+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
281313
282314 // Allocate the memory.
283315 auto *Mem =
@@ -286,8 +318,7 @@ template <typename T> class ImmutablePointerSetFactory {
286318 // Copy in the union of the two pointer sets into the tail allocated
287319 // memory. Since we know that our sorted arrays are uniqued, we can use
288320 // 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);
291322 std::set_union (S1->begin (), S1->end (), S2.begin (), S2.end (),
292323 DataMem.begin ());
293324
@@ -316,8 +347,8 @@ template <typename T> class ImmutablePointerSetFactory {
316347 // perform a sorted set merging algorithm to create the ID. We also count
317348 // the number of unique elements for allocation purposes.
318349 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) );
321352 NumElts++;
322353 });
323354
@@ -327,7 +358,7 @@ template <typename T> class ImmutablePointerSetFactory {
327358 return PSet;
328359 }
329360
330- unsigned MemSize = sizeof (PtrSet) + sizeof (PtrTy ) * NumElts;
361+ unsigned MemSize = sizeof (PtrSet) + sizeof (T ) * NumElts;
331362
332363 // Allocate the memory.
333364 auto *Mem =
@@ -336,8 +367,7 @@ template <typename T> class ImmutablePointerSetFactory {
336367 // Copy in the union of the two pointer sets into the tail allocated
337368 // memory. Since we know that our sorted arrays are uniqued, we can use
338369 // 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);
341371 std::set_union (S1->begin (), S1->end (), S2->begin (), S2->end (),
342372 DataMem.begin ());
343373
@@ -356,8 +386,8 @@ template <typename T>
356386#if !defined(_MSC_VER) || defined(__clang__)
357387constexpr
358388#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 );
361391
362392} // end swift namespace
363393
0 commit comments