Skip to content

Commit 150efb6

Browse files
committed
[immutable-ptr-set] Change data structure to use T instead of T *, but require T to conform to PointerLikeTypeTraits.
This allows one to place types like PointerIntPair and value types that wrap a pointer into the pointer set. I am making this change before I use this data structure in TransferNonSendable and using ARC to validate that I haven't broken anything.
1 parent a2604dc commit 150efb6

10 files changed

+89
-61
lines changed

include/swift/Basic/ImmutablePointerSet.h

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,22 @@
5858

5959
namespace 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

7679
public:
@@ -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__)
357387
constexpr
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

lib/SILOptimizer/ARC/ARCRegionState.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ bool ARCRegionState::processBlockBottomUp(
166166
EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
167167
bool FreezeOwnedArgEpilogueReleases,
168168
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
169-
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
169+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory) {
170170
LLVM_DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n");
171171

172172
SILBasicBlock &BB = *R->getBlock();
@@ -311,7 +311,7 @@ bool ARCRegionState::processBottomUp(
311311
llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
312312
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
313313
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
314-
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
314+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory) {
315315
const LoopRegion *R = getRegion();
316316

317317
// We only process basic blocks for now. This ensures that we always propagate
@@ -331,7 +331,7 @@ bool ARCRegionState::processBottomUp(
331331
bool ARCRegionState::processBlockTopDown(
332332
SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
333333
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
334-
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
334+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory) {
335335
LLVM_DEBUG(llvm::dbgs() << ">>>> Top Down!\n");
336336

337337
bool NestingDetected = false;
@@ -460,7 +460,7 @@ bool ARCRegionState::processTopDown(
460460
llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
461461
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
462462
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
463-
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
463+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory) {
464464
const LoopRegion *R = getRegion();
465465

466466
// We only process basic blocks for now. This ensures that we always propagate

lib/SILOptimizer/ARC/ARCRegionState.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class ARCRegionState {
191191
llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
192192
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
193193
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &LoopRegionState,
194-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
194+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
195195

196196
/// If this region is a block, process all instructions bottom up. Otherwise,
197197
/// apply the summarized bottom up information to the merged bottom up
@@ -204,7 +204,7 @@ class ARCRegionState {
204204
llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
205205
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
206206
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
207-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
207+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
208208

209209
void summarizeBlock(SILBasicBlock *BB);
210210

@@ -223,10 +223,10 @@ class ARCRegionState {
223223
private:
224224
bool processBlockBottomUp(
225225
const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
226-
EpilogueARCFunctionInfo *EAFI,
227-
LoopRegionFunctionInfo *LRFI, bool FreezeOwnedArgEpilogueReleases,
226+
EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
227+
bool FreezeOwnedArgEpilogueReleases,
228228
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
229-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
229+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
230230
bool processLoopBottomUp(
231231
const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
232232
RCIdentityFunctionInfo *RCIA,
@@ -236,7 +236,7 @@ class ARCRegionState {
236236
bool processBlockTopDown(
237237
SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
238238
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
239-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
239+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
240240
bool processLoopTopDown(
241241
const LoopRegion *R, ARCRegionState *State, AliasAnalysis *AA,
242242
LoopRegionFunctionInfo *LRFI, RCIdentityFunctionInfo *RCIA,

lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class ARCSequenceDataflowEvaluator {
6464
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap;
6565

6666
llvm::BumpPtrAllocator Allocator;
67-
ImmutablePointerSetFactory<SILInstruction> SetFactory;
67+
ImmutablePointerSetFactory<SILInstruction *> SetFactory;
6868

6969
/// Stashed BB information.
7070
std::unique_ptr<ARCBBStateInfo> BBStateInfo;

lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class LoopARCSequenceDataflowEvaluator {
4040
llvm::BumpPtrAllocator Allocator;
4141

4242
/// The factory that we use to generate immutable pointer sets.
43-
ImmutablePointerSetFactory<SILInstruction> SetFactory;
43+
ImmutablePointerSetFactory<SILInstruction *> SetFactory;
4444

4545
/// The SILFunction that we are applying the dataflow to.
4646
SILFunction &F;

lib/SILOptimizer/ARC/RCStateTransition.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ class RCStateTransition {
7373
/// An RCStateTransition can represent either an RC end point (i.e. an initial
7474
/// or terminal RC transition) or a ptr set of Mutators.
7575
SILNode *EndPoint;
76-
ImmutablePointerSet<SILInstruction> *Mutators =
77-
ImmutablePointerSetFactory<SILInstruction>::getEmptySet();
76+
ImmutablePointerSet<SILInstruction *> *Mutators =
77+
ImmutablePointerSetFactory<SILInstruction *>::getEmptySet();
7878
RCStateTransitionKind Kind;
7979

8080
// Should only be constructed be default RefCountState.
@@ -84,9 +84,9 @@ class RCStateTransition {
8484
~RCStateTransition() = default;
8585
RCStateTransition(const RCStateTransition &R) = default;
8686

87-
RCStateTransition(ImmutablePointerSet<SILInstruction> *I) {
87+
RCStateTransition(ImmutablePointerSet<SILInstruction *> *I) {
8888
assert(I->size() == 1);
89-
SILInstruction *Inst = *I->begin();
89+
auto *Inst = *I->begin();
9090
Kind = getRCStateTransitionKind(Inst->asSILNode());
9191
if (isRCStateTransitionEndPoint(Kind)) {
9292
EndPoint = Inst->asSILNode();

lib/SILOptimizer/ARC/RCStateTransitionVisitors.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ BottomUpDataflowRCStateVisitor<ARCState>::BottomUpDataflowRCStateVisitor(
5757
RCIdentityFunctionInfo *RCFI, EpilogueARCFunctionInfo *EAFI,
5858
ARCState &State, bool FreezeOwnedArgEpilogueReleases,
5959
IncToDecStateMapTy &IncToDecStateMap,
60-
ImmutablePointerSetFactory<SILInstruction> &SetFactory)
60+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory)
6161
: RCFI(RCFI), EAFI(EAFI), DataflowState(State),
6262
FreezeOwnedArgEpilogueReleases(FreezeOwnedArgEpilogueReleases),
6363
IncToDecStateMap(IncToDecStateMap), SetFactory(SetFactory) {}
@@ -184,7 +184,7 @@ template <class ARCState>
184184
TopDownDataflowRCStateVisitor<ARCState>::TopDownDataflowRCStateVisitor(
185185
RCIdentityFunctionInfo *RCFI, ARCState &DataflowState,
186186
DecToIncStateMapTy &DecToIncStateMap,
187-
ImmutablePointerSetFactory<SILInstruction> &SetFactory)
187+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory)
188188
: RCFI(RCFI), DataflowState(DataflowState),
189189
DecToIncStateMap(DecToIncStateMap), SetFactory(SetFactory) {}
190190

lib/SILOptimizer/ARC/RCStateTransitionVisitors.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,14 @@ class BottomUpDataflowRCStateVisitor
120120
ARCState &DataflowState;
121121
bool FreezeOwnedArgEpilogueReleases;
122122
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap;
123-
ImmutablePointerSetFactory<SILInstruction> &SetFactory;
123+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory;
124124

125125
public:
126126
BottomUpDataflowRCStateVisitor(
127127
RCIdentityFunctionInfo *RCFI, EpilogueARCFunctionInfo *EAFI,
128128
ARCState &DataflowState, bool FreezeOwnedArgEpilogueReleases,
129129
IncToDecStateMapTy &IncToDecStateMap,
130-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
130+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
131131
DataflowResult visitAutoreleasePoolCall(SILNode *N);
132132
DataflowResult visitStrongDecrement(SILNode *N);
133133
DataflowResult visitStrongIncrement(SILNode *N);
@@ -156,13 +156,13 @@ class TopDownDataflowRCStateVisitor
156156
RCIdentityFunctionInfo *RCFI;
157157
ARCState &DataflowState;
158158
DecToIncStateMapTy &DecToIncStateMap;
159-
ImmutablePointerSetFactory<SILInstruction> &SetFactory;
159+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory;
160160

161161
public:
162162
TopDownDataflowRCStateVisitor(
163163
RCIdentityFunctionInfo *RCFI, ARCState &State,
164164
DecToIncStateMapTy &DecToIncStateMap,
165-
ImmutablePointerSetFactory<SILInstruction> &SetFactory);
165+
ImmutablePointerSetFactory<SILInstruction *> &SetFactory);
166166
DataflowResult visitAutoreleasePoolCall(SILNode *N);
167167
DataflowResult visitStrongDecrement(SILNode *N);
168168
DataflowResult visitStrongIncrement(SILNode *N);

0 commit comments

Comments
 (0)