@@ -377,8 +377,9 @@ class HoistDestroys {
377
377
} // namespace
378
378
379
379
bool HoistDestroys::perform () {
380
- auto storage = AccessStorage::compute (storageRoot);
381
- if (!storage.isUniquelyIdentified ())
380
+ auto storage = AccessStorage::computeInScope (storageRoot);
381
+ if (!storage.isUniquelyIdentified () &&
382
+ storage.getKind () != AccessStorage::Kind::Nested)
382
383
return false ;
383
384
384
385
KnownStorageUses knownUses (storage, getFunction ());
@@ -561,18 +562,40 @@ void SSADestroyHoisting::run() {
561
562
562
563
InstructionDeleter deleter;
563
564
bool changed = false ;
564
- for ( auto *arg : getFunction ()-> getArguments ()) {
565
- if (arg-> getType (). isAddress ()) {
566
- changed |= hoistDestroys (arg, deleter) ;
567
- }
568
- }
565
+
566
+ llvm::SmallVector<AllocStackInst *, 4 > asis;
567
+ llvm::SmallVector<BeginAccessInst *, 4 > bais ;
568
+
569
+ // Collect the instructions that we'll be transforming.
569
570
for (auto &block : *getFunction ()) {
570
571
for (auto &inst : block) {
571
- if (auto *alloc = dyn_cast<AllocStackInst>(&inst)) {
572
- changed |= hoistDestroys (alloc, deleter);
572
+ if (auto *asi = dyn_cast<AllocStackInst>(&inst)) {
573
+ asis.push_back (asi);
574
+ } else if (auto *bai = dyn_cast<BeginAccessInst>(&inst)) {
575
+ if (bai->getAccessKind () == SILAccessKind::Modify) {
576
+ bais.push_back (bai);
577
+ }
573
578
}
574
579
}
575
580
}
581
+
582
+ // We assume that the function is in reverse post order so visiting the
583
+ // blocks and pushing begin_access as we see them and then popping them off
584
+ // the end will result in hoisting inner begin_access' destroy_addrs first.
585
+ while (!bais.empty ()) {
586
+ auto *bai = bais.pop_back_val ();
587
+ changed |= hoistDestroys (bai, deleter);
588
+ }
589
+ // Alloc stacks always enclose their accesses.
590
+ for (auto *asi : asis) {
591
+ changed |= hoistDestroys (asi, deleter);
592
+ }
593
+ // Arguments enclose everything.
594
+ for (auto *arg : getFunction ()->getArguments ()) {
595
+ if (arg->getType ().isAddress ()) {
596
+ changed |= hoistDestroys (arg, deleter);
597
+ }
598
+ }
576
599
if (changed) {
577
600
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
578
601
}
0 commit comments