@@ -112,14 +112,17 @@ namespace {
112112// / Step #1: Find all known uses of the unique storage object.
113113struct KnownStorageUses : UniqueStorageUseVisitor {
114114 bool preserveDebugInfo;
115+ bool ignoreDeinitBarriers;
115116
116117 SmallPtrSet<SILInstruction *, 16 > storageUsers;
117118 llvm::SmallSetVector<SILInstruction *, 4 > originalDestroys;
118119 SmallPtrSet<SILInstruction *, 4 > debugInsts;
119120
120- KnownStorageUses (AccessStorage storage, SILFunction *function)
121+ KnownStorageUses (AccessStorage storage, SILFunction *function,
122+ bool ignoreDeinitBarriers)
121123 : UniqueStorageUseVisitor(storage, function),
122- preserveDebugInfo (function->preserveDebugInfo ()) {}
124+ preserveDebugInfo (function->preserveDebugInfo ()),
125+ ignoreDeinitBarriers(ignoreDeinitBarriers) {}
123126
124127 bool empty () const {
125128 return storageUsers.empty () && originalDestroys.empty () &&
@@ -178,11 +181,19 @@ struct KnownStorageUses : UniqueStorageUseVisitor {
178181
179182 bool visitUnknownUse (Operand *use) override {
180183 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.
186197 return true ;
187198 }
188199 LLVM_DEBUG (llvm::dbgs () << " Unknown user " << *user);
@@ -473,7 +484,7 @@ bool HoistDestroys::perform() {
473484 storage.getKind () != AccessStorage::Kind::Nested)
474485 return false ;
475486
476- KnownStorageUses knownUses (storage, getFunction ());
487+ KnownStorageUses knownUses (storage, getFunction (), ignoreDeinitBarriers );
477488 if (!knownUses.findUses ())
478489 return false ;
479490
0 commit comments