@@ -112,14 +112,17 @@ namespace {
112
112
// / Step #1: Find all known uses of the unique storage object.
113
113
struct KnownStorageUses : UniqueStorageUseVisitor {
114
114
bool preserveDebugInfo;
115
+ bool ignoreDeinitBarriers;
115
116
116
117
SmallPtrSet<SILInstruction *, 16 > storageUsers;
117
118
llvm::SmallSetVector<SILInstruction *, 4 > originalDestroys;
118
119
SmallPtrSet<SILInstruction *, 4 > debugInsts;
119
120
120
- KnownStorageUses (AccessStorage storage, SILFunction *function)
121
+ KnownStorageUses (AccessStorage storage, SILFunction *function,
122
+ bool ignoreDeinitBarriers)
121
123
: UniqueStorageUseVisitor(storage, function),
122
- preserveDebugInfo (function->preserveDebugInfo ()) {}
124
+ preserveDebugInfo (function->preserveDebugInfo ()),
125
+ ignoreDeinitBarriers(ignoreDeinitBarriers) {}
123
126
124
127
bool empty () const {
125
128
return storageUsers.empty () && originalDestroys.empty () &&
@@ -178,11 +181,19 @@ struct KnownStorageUses : UniqueStorageUseVisitor {
178
181
179
182
bool visitUnknownUse (Operand *use) override {
180
183
auto *user = use->getUser ();
181
- if (isa<BuiltinRawPointerType>(use->get ()->getType ().getASTType ())) {
182
- // Destroy hoisting considers address_to_pointer to be a leaf use because
183
- // any potential pointer access is already considered to be a
184
- // deinitialization barrier. Consequently, any instruction that uses a
185
- // value produced by address_to_pointer isn't regarded as a storage use.
184
+ if (isa<BuiltinRawPointerType>(use->get ()->getType ().getASTType ()) &&
185
+ !ignoreDeinitBarriers) {
186
+ // When respecting deinit barriers, destroy hoisting considers
187
+ // address_to_pointer to be a leaf use because any potential pointer
188
+ // access is already considered to be a barrier to hoisting (because as a
189
+ // pointer access it's a deinitialization barrier). Consequently, any
190
+ // instruction that uses a value produced by address_to_pointer isn't
191
+ // regarded as a storage use.
192
+ //
193
+ // On the other hand, when _not_ respecting deinit barriers, potential
194
+ // pointer accesses are _not_ already considered to be barriers to
195
+ // hoisting (deinit barriers being ignored); so uses of the pointer must
196
+ // obstruct all hoisting.
186
197
return true ;
187
198
}
188
199
LLVM_DEBUG (llvm::dbgs () << " Unknown user " << *user);
@@ -473,7 +484,7 @@ bool HoistDestroys::perform() {
473
484
storage.getKind () != AccessStorage::Kind::Nested)
474
485
return false ;
475
486
476
- KnownStorageUses knownUses (storage, getFunction ());
487
+ KnownStorageUses knownUses (storage, getFunction (), ignoreDeinitBarriers );
477
488
if (!knownUses.findUses ())
478
489
return false ;
479
490
0 commit comments