Skip to content

Commit 40e57e1

Browse files
committed
[SSADestroyHoisting] Split destroy from copy.
As was done with store [init], transform instructions like copy_addr %n to %m into the sequence destroy_addr %m copy_addr %n to [initialization] %m in order to create more opportunities for hoisting destroys. After hoisting, if these opportunities for hoisting don't result in hoisting actually occurring, recombine the two instructions.
1 parent cea8d75 commit 40e57e1

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

lib/SILOptimizer/Transforms/SSADestroyHoisting.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ void SSADestroyHoisting::run() {
754754
llvm::SmallVector<AllocStackInst *, 4> asis;
755755
llvm::SmallVector<BeginAccessInst *, 4> bais;
756756
llvm::SmallVector<StoreInst *, 4> sis;
757+
llvm::SmallVector<CopyAddrInst *, 4> cais;
757758

758759
// Collect the instructions that we'll be transforming.
759760
for (auto &block : *getFunction()) {
@@ -768,6 +769,10 @@ void SSADestroyHoisting::run() {
768769
if (si->getOwnershipQualifier() == StoreOwnershipQualifier::Assign) {
769770
sis.push_back(si);
770771
}
772+
} else if (auto *cai = dyn_cast<CopyAddrInst>(&inst)) {
773+
if (cai->isInitializationOfDest() == IsNotInitialization) {
774+
cais.push_back(cai);
775+
}
771776
}
772777
}
773778
}
@@ -804,6 +809,32 @@ void SSADestroyHoisting::run() {
804809
remainingDestroyAddrs.insert(dai);
805810
++splitDestroys;
806811
}
812+
// Similarly, also expand each
813+
//
814+
// copy_addr to
815+
//
816+
// instruction into
817+
//
818+
// destroy_addr
819+
// copy_addr to [initialization]
820+
//
821+
// sequences to create still more destroy_addrs to hoist.
822+
//
823+
// As above, record the newly created destroy_addrs and copy_addrs off of
824+
// which they were split. After hoisting, we'll merge them back together when
825+
// possible.
826+
llvm::SmallVector<std::pair<DestroyAddrInst *, CopyAddrInst *>, 8>
827+
splitDestroysAndCopies;
828+
for (auto *cai : cais) {
829+
auto builder = SILBuilderWithScope(cai);
830+
auto *dai = builder.createDestroyAddr(
831+
RegularLocation::getAutoGeneratedLocation(cai->getLoc()),
832+
cai->getOperand(1));
833+
cai->setIsInitializationOfDest(IsInitialization);
834+
splitDestroysAndCopies.push_back({dai, cai});
835+
remainingDestroyAddrs.insert(dai);
836+
++splitDestroys;
837+
}
807838

808839
// We assume that the function is in reverse post order so visiting the
809840
// blocks and pushing begin_access as we see them and then popping them off
@@ -852,6 +883,18 @@ void SSADestroyHoisting::run() {
852883
si->setOwnershipQualifier(StoreOwnershipQualifier::Assign);
853884
--splitDestroys;
854885
}
886+
for (auto pair : splitDestroysAndCopies) {
887+
auto *dai = pair.first;
888+
if (!remainingDestroyAddrs.contains(dai))
889+
continue;
890+
auto *cai = pair.second;
891+
if (dai->getNextInstruction() != cai)
892+
continue;
893+
assert(cai->isInitializationOfDest() == IsInitialization);
894+
deleter.forceDelete(dai);
895+
cai->setIsInitializationOfDest(IsNotInitialization);
896+
--splitDestroys;
897+
}
855898
// If there were any destroy_addrs split off of stores and not recombined
856899
// with them, then the function has changed.
857900
changed |= splitDestroys > 0;

0 commit comments

Comments
 (0)