Skip to content

[SSADestroyHoisting] Split destroy from copy. #41497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 54 additions & 11 deletions lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ void SSADestroyHoisting::run() {
llvm::SmallVector<AllocStackInst *, 4> asis;
llvm::SmallVector<BeginAccessInst *, 4> bais;
llvm::SmallVector<StoreInst *, 4> sis;
llvm::SmallVector<CopyAddrInst *, 4> cais;

// Collect the instructions that we'll be transforming.
for (auto &block : *getFunction()) {
Expand All @@ -768,6 +769,10 @@ void SSADestroyHoisting::run() {
if (si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign) {
sis.push_back(si);
}
} else if (auto *cai = dyn_cast<CopyAddrInst>(&inst)) {
if (cai->isInitializationOfDest() == IsNotInitialization) {
cais.push_back(cai);
}
}
}
}
Expand Down Expand Up @@ -804,6 +809,32 @@ void SSADestroyHoisting::run() {
remainingDestroyAddrs.insert(dai);
++splitDestroys;
}
// Similarly, also expand each
//
// copy_addr to
//
// instruction into
//
// destroy_addr
// copy_addr to [initialization]
//
// sequences to create still more destroy_addrs to hoist.
//
// As above, record the newly created destroy_addrs and copy_addrs off of
// which they were split. After hoisting, we'll merge them back together when
// possible.
llvm::SmallVector<std::pair<DestroyAddrInst *, CopyAddrInst *>, 8>
splitDestroysAndCopies;
for (auto *cai : cais) {
auto builder = SILBuilderWithScope(cai);
auto *dai = builder.createDestroyAddr(
RegularLocation::getAutoGeneratedLocation(cai->getLoc()),
cai->getOperand(1));
cai->setIsInitializationOfDest(IsInitialization);
splitDestroysAndCopies.push_back({dai, cai});
remainingDestroyAddrs.insert(dai);
++splitDestroys;
}

// We assume that the function is in reverse post order so visiting the
// blocks and pushing begin_access as we see them and then popping them off
Expand Down Expand Up @@ -840,17 +871,29 @@ void SSADestroyHoisting::run() {
if (!remainingDestroyAddrs.contains(dai))
continue;
auto *si = pair.second;
if (dai->getNextInstruction() == si) {
// No stores should have been rewritten during hoisting. Their ownership
// qualifiers were set to [init] when splitting off the destroy_addrs.
assert(si->getOwnershipQualifier() == StoreOwnershipQualifier::Init);
// If a newly created destroy_addr has not been hoisted from its previous
// location, combine it back together with the store [init] which it was
// split off from.
deleter.forceDelete(dai);
si->setOwnershipQualifier(StoreOwnershipQualifier::Assign);
--splitDestroys;
}
if (dai->getNextInstruction() != si)
continue;
// No stores should have been rewritten during hoisting. Their ownership
// qualifiers were set to [init] when splitting off the destroy_addrs.
assert(si->getOwnershipQualifier() == StoreOwnershipQualifier::Init);
// If a newly created destroy_addr has not been hoisted from its previous
// location, combine it back together with the store [init] which it was
// split off from.
deleter.forceDelete(dai);
si->setOwnershipQualifier(StoreOwnershipQualifier::Assign);
--splitDestroys;
}
for (auto pair : splitDestroysAndCopies) {
auto *dai = pair.first;
if (!remainingDestroyAddrs.contains(dai))
continue;
auto *cai = pair.second;
if (dai->getNextInstruction() != cai)
continue;
assert(cai->isInitializationOfDest() == IsInitialization);
deleter.forceDelete(dai);
cai->setIsInitializationOfDest(IsNotInitialization);
--splitDestroys;
}
// If there were any destroy_addrs split off of stores and not recombined
// with them, then the function has changed.
Expand Down