Skip to content

Commit bd8626c

Browse files
committed
[SSADestroyHoisting] Hoist everything inner first.
In addition to hoisting destroy_addrs for alloc_stacks and function arguments, also hoist begin_access [modify] insts. Hoist starting from innermost scopes and proceeding outwards.
1 parent d227cef commit bd8626c

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,9 @@ class HoistDestroys {
377377
} // namespace
378378

379379
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)
382383
return false;
383384

384385
KnownStorageUses knownUses(storage, getFunction());
@@ -561,18 +562,40 @@ void SSADestroyHoisting::run() {
561562

562563
InstructionDeleter deleter;
563564
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.
569570
for (auto &block : *getFunction()) {
570571
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+
}
573578
}
574579
}
575580
}
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+
}
576599
if (changed) {
577600
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
578601
}

0 commit comments

Comments
 (0)