@@ -194,6 +194,8 @@ class DestroyReachability;
194
194
// / Step #2: Perform backward dataflow from KnownStorageUses.originalDestroys to
195
195
// / KnownStorageUses.storageUsers to find deinitialization barriers.
196
196
class DeinitBarriers final {
197
+ BasicCalleeAnalysis *calleeAnalysis;
198
+
197
199
public:
198
200
// Instructions beyond which a destroy_addr cannot be hoisted, reachable from
199
201
// a destroy_addr. Deinit barriers or storage uses.
@@ -219,8 +221,10 @@ class DeinitBarriers final {
219
221
220
222
explicit DeinitBarriers (bool ignoreDeinitBarriers,
221
223
const KnownStorageUses &knownUses,
222
- SILFunction *function)
223
- : ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
224
+ SILFunction *function,
225
+ BasicCalleeAnalysis *calleeAnalysis)
226
+ : calleeAnalysis(calleeAnalysis),
227
+ ignoreDeinitBarriers(ignoreDeinitBarriers), knownUses(knownUses) {
224
228
auto rootValue = knownUses.getStorage ().getRoot ();
225
229
assert (rootValue && " HoistDestroys requires a single storage root" );
226
230
// null for function args
@@ -341,7 +345,7 @@ DeinitBarriers::classifyInstruction(SILInstruction *inst) const {
341
345
if (knownUses.storageUsers .contains (inst)) {
342
346
return Classification::Barrier;
343
347
}
344
- if (!ignoreDeinitBarriers && isDeinitBarrier (inst, nullptr )) {
348
+ if (!ignoreDeinitBarriers && isDeinitBarrier (inst, calleeAnalysis )) {
345
349
return Classification::Barrier;
346
350
}
347
351
if (auto *eai = dyn_cast<EndAccessInst>(inst)) {
@@ -403,6 +407,7 @@ class HoistDestroys {
403
407
bool ignoreDeinitBarriers;
404
408
SmallPtrSetImpl<SILInstruction *> &remainingDestroyAddrs;
405
409
InstructionDeleter &deleter;
410
+ BasicCalleeAnalysis *calleeAnalysis;
406
411
407
412
// Book-keeping for the rewriting stage.
408
413
SmallPtrSet<SILInstruction *, 4 > reusedDestroys;
@@ -412,12 +417,13 @@ class HoistDestroys {
412
417
public:
413
418
HoistDestroys (SILValue storageRoot, bool ignoreDeinitBarriers,
414
419
SmallPtrSetImpl<SILInstruction *> &remainingDestroyAddrs,
415
- InstructionDeleter &deleter)
420
+ InstructionDeleter &deleter,
421
+ BasicCalleeAnalysis *calleeAnalysis)
416
422
: storageRoot(storageRoot), function(storageRoot->getFunction ()),
417
423
module(function->getModule ()), typeExpansionContext(*function),
418
424
ignoreDeinitBarriers(ignoreDeinitBarriers),
419
425
remainingDestroyAddrs(remainingDestroyAddrs), deleter(deleter),
420
- destroyMergeBlocks(getFunction()) {}
426
+ calleeAnalysis(calleeAnalysis), destroyMergeBlocks(getFunction()) {}
421
427
422
428
bool perform ();
423
429
@@ -465,7 +471,8 @@ bool HoistDestroys::perform() {
465
471
if (!knownUses.findUses ())
466
472
return false ;
467
473
468
- DeinitBarriers deinitBarriers (ignoreDeinitBarriers, knownUses, getFunction ());
474
+ DeinitBarriers deinitBarriers (ignoreDeinitBarriers, knownUses, getFunction (),
475
+ calleeAnalysis);
469
476
deinitBarriers.compute ();
470
477
471
478
// No SIL changes happen before rewriting.
@@ -829,7 +836,8 @@ void HoistDestroys::mergeDestroys(SILBasicBlock *mergeBlock) {
829
836
830
837
bool hoistDestroys (SILValue root, bool ignoreDeinitBarriers,
831
838
SmallPtrSetImpl<SILInstruction *> &remainingDestroyAddrs,
832
- InstructionDeleter &deleter) {
839
+ InstructionDeleter &deleter,
840
+ BasicCalleeAnalysis *calleeAnalysis) {
833
841
LLVM_DEBUG (llvm::dbgs () << " Performing destroy hoisting on " << root);
834
842
835
843
SILFunction *function = root->getFunction ();
@@ -846,7 +854,7 @@ bool hoistDestroys(SILValue root, bool ignoreDeinitBarriers,
846
854
ignoreDeinitBarriers = ignoreDeinitBarriers || !enableLexicalLifetimes;
847
855
848
856
return HoistDestroys (root, ignoreDeinitBarriers, remainingDestroyAddrs,
849
- deleter)
857
+ deleter, calleeAnalysis )
850
858
.perform ();
851
859
}
852
860
@@ -955,17 +963,20 @@ void SSADestroyHoisting::run() {
955
963
++splitDestroys;
956
964
}
957
965
966
+ auto *calleeAnalysis = getAnalysis<BasicCalleeAnalysis>();
967
+
958
968
// We assume that the function is in reverse post order so visiting the
959
969
// blocks and pushing begin_access as we see them and then popping them off
960
970
// the end will result in hoisting inner begin_access' destroy_addrs first.
961
971
for (auto *bai : llvm::reverse (bais)) {
962
972
changed |= hoistDestroys (bai, /* ignoreDeinitBarriers=*/ true ,
963
- remainingDestroyAddrs, deleter);
973
+ remainingDestroyAddrs, deleter, calleeAnalysis );
964
974
}
965
975
// Alloc stacks always enclose their accesses.
966
976
for (auto *asi : asis) {
967
- changed |= hoistDestroys (asi, /* ignoreDeinitBarriers=*/ !asi->isLexical (),
968
- remainingDestroyAddrs, deleter);
977
+ changed |= hoistDestroys (asi,
978
+ /* ignoreDeinitBarriers=*/ !asi->isLexical (),
979
+ remainingDestroyAddrs, deleter, calleeAnalysis);
969
980
}
970
981
// Arguments enclose everything.
971
982
for (auto *uncastArg : getFunction ()->getArguments ()) {
@@ -983,7 +994,7 @@ void SSADestroyHoisting::run() {
983
994
auto lifetime = arg->getLifetime ();
984
995
bool ignoreDeinitBarriers = ignoredByConvention || lifetime.isEagerMove ();
985
996
changed |= hoistDestroys (arg, ignoreDeinitBarriers, remainingDestroyAddrs,
986
- deleter);
997
+ deleter, calleeAnalysis );
987
998
}
988
999
}
989
1000
0 commit comments