@@ -754,6 +754,7 @@ void SSADestroyHoisting::run() {
754
754
llvm::SmallVector<AllocStackInst *, 4 > asis;
755
755
llvm::SmallVector<BeginAccessInst *, 4 > bais;
756
756
llvm::SmallVector<StoreInst *, 4 > sis;
757
+ llvm::SmallVector<CopyAddrInst *, 4 > cais;
757
758
758
759
// Collect the instructions that we'll be transforming.
759
760
for (auto &block : *getFunction ()) {
@@ -768,6 +769,10 @@ void SSADestroyHoisting::run() {
768
769
if (si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign) {
769
770
sis.push_back (si);
770
771
}
772
+ } else if (auto *cai = dyn_cast<CopyAddrInst>(&inst)) {
773
+ if (cai->isInitializationOfDest () == IsNotInitialization) {
774
+ cais.push_back (cai);
775
+ }
771
776
}
772
777
}
773
778
}
@@ -804,6 +809,32 @@ void SSADestroyHoisting::run() {
804
809
remainingDestroyAddrs.insert (dai);
805
810
++splitDestroys;
806
811
}
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
+ }
807
838
808
839
// We assume that the function is in reverse post order so visiting the
809
840
// blocks and pushing begin_access as we see them and then popping them off
@@ -852,6 +883,18 @@ void SSADestroyHoisting::run() {
852
883
si->setOwnershipQualifier (StoreOwnershipQualifier::Assign);
853
884
--splitDestroys;
854
885
}
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
+ }
855
898
// If there were any destroy_addrs split off of stores and not recombined
856
899
// with them, then the function has changed.
857
900
changed |= splitDestroys > 0 ;
0 commit comments