@@ -41,6 +41,12 @@ llvm::cl::opt<bool> DisableConvertEscapeToNoEscapeSwitchEnumPeephole(
41
41
" Disable the convert_escape_to_noescape switch enum peephole. " ),
42
42
llvm::cl::Hidden);
43
43
44
+ llvm::cl::opt<bool > DisableCopyEliminationOfCopyableCapture (
45
+ " sil-disable-copy-elimination-of-copyable-closure-capture" ,
46
+ llvm::cl::init (false ),
47
+ llvm::cl::desc(" Don't eliminate copy_addr of Copyable closure captures "
48
+ " inserted by SILGen" ));
49
+
44
50
using namespace swift ;
45
51
46
52
// / Given an optional diamond, return the bottom of the diamond.
@@ -734,7 +740,7 @@ static SILValue tryRewriteToPartialApplyStack(
734
740
SmallVector<SILInstruction *, 4 > lifetimeEnds;
735
741
collectStackClosureLifetimeEnds (lifetimeEnds, closureOp);
736
742
737
- // For noncopyable address-only captures, see if we can eliminate the copy
743
+ // For address-only captures, see if we can eliminate the copy
738
744
// that SILGen emitted to allow the original partial_apply to take ownership.
739
745
// We do this here because otherwise the move checker will see the copy as an
740
746
// attempt to consume the value, which we don't want.
@@ -760,14 +766,14 @@ static SILValue tryRewriteToPartialApplyStack(
760
766
LLVM_DEBUG (llvm::dbgs () << " -- not an alloc_stack\n " );
761
767
continue ;
762
768
}
763
-
764
- // This would be a nice optimization to attempt for all types, but for now,
765
- // limit the effect to move-only types.
766
- if (!copy-> getType (). isMoveOnly ()) {
767
- LLVM_DEBUG ( llvm::dbgs () << " -- not move-only \n " ) ;
768
- continue ;
769
+
770
+ if (DisableCopyEliminationOfCopyableCapture) {
771
+ if (!copy-> getType (). isMoveOnly ()) {
772
+ LLVM_DEBUG ( llvm::dbgs () << " -- not move-only \n " );
773
+ continue ;
774
+ }
769
775
}
770
-
776
+
771
777
// Is the capture a borrow?
772
778
773
779
auto paramIndex = i + appliedArgStartIdx;
@@ -806,33 +812,33 @@ static SILValue tryRewriteToPartialApplyStack(
806
812
if (!lookThroughMarkDependenceChainForValue (mark, newPA) ||
807
813
mark->getBase () != stack) {
808
814
LLVM_DEBUG (llvm::dbgs () << " -- had unexpected mark_dependence use\n " ;
809
- use->getUser ()->print (llvm::dbgs ());
810
- llvm::dbgs () << " \n " );
815
+ use->getUser ()->print (llvm::dbgs ()); llvm::dbgs () << " \n " );
811
816
initialization = nullptr ;
812
817
break ;
813
818
}
814
819
markDep = mark;
815
820
816
821
continue ;
817
822
}
818
-
823
+
819
824
// If we saw more than just the initialization, this isn't a pattern we
820
825
// recognize.
821
826
if (initialization) {
822
- LLVM_DEBUG (llvm::dbgs () << " -- had non-initialization, non-partial-apply use \n " ;
823
- use-> getUser ()-> print ( llvm::dbgs ()) ;
824
- llvm::dbgs () << " \n " );
825
-
827
+ LLVM_DEBUG (llvm::dbgs ()
828
+ << " -- had non-initialization, non-partial-apply use \n " ;
829
+ use-> getUser ()-> print ( llvm::dbgs ()); llvm::dbgs () << " \n " );
830
+
826
831
initialization = nullptr ;
827
832
break ;
828
833
}
829
834
if (auto possibleInit = dyn_cast<CopyAddrInst>(use->getUser ())) {
830
835
// Should copy the source and initialize the destination.
831
- if (possibleInit->isTakeOfSrc ()
832
- || !possibleInit->isInitializationOfDest ()) {
833
- LLVM_DEBUG (llvm::dbgs () << " -- had non-initialization, non-partial-apply use\n " ;
834
- use->getUser ()->print (llvm::dbgs ());
835
- llvm::dbgs () << " \n " );
836
+ if (possibleInit->isTakeOfSrc () ||
837
+ !possibleInit->isInitializationOfDest ()) {
838
+ LLVM_DEBUG (
839
+ llvm::dbgs ()
840
+ << " -- had non-initialization, non-partial-apply use\n " ;
841
+ use->getUser ()->print (llvm::dbgs ()); llvm::dbgs () << " \n " );
836
842
837
843
break ;
838
844
}
@@ -860,33 +866,36 @@ static SILValue tryRewriteToPartialApplyStack(
860
866
LLVM_DEBUG (llvm::dbgs () << " ++ found original:\n " ;
861
867
orig->print (llvm::dbgs ());
862
868
llvm::dbgs () << " \n " );
863
-
864
- bool origIsUnusedDuringClosureLifetime = true ;
865
869
866
- class OrigUnusedDuringClosureLifetimeWalker
870
+ bool origIsUnmodifiedDuringClosureLifetime = true ;
871
+
872
+ class OrigUnmodifiedDuringClosureLifetimeWalker
867
873
: public TransitiveAddressWalker<
868
- OrigUnusedDuringClosureLifetimeWalker > {
874
+ OrigUnmodifiedDuringClosureLifetimeWalker > {
869
875
SSAPrunedLiveness &closureLiveness;
870
- bool &origIsUnusedDuringClosureLifetime;
876
+ bool &origIsUnmodifiedDuringClosureLifetime;
877
+
871
878
public:
872
- OrigUnusedDuringClosureLifetimeWalker (SSAPrunedLiveness &closureLiveness,
873
- bool &origIsUnusedDuringClosureLifetime)
874
- : closureLiveness(closureLiveness),
875
- origIsUnusedDuringClosureLifetime (origIsUnusedDuringClosureLifetime)
876
- {}
879
+ OrigUnmodifiedDuringClosureLifetimeWalker (
880
+ SSAPrunedLiveness &closureLiveness,
881
+ bool &origIsUnmodifiedDuringClosureLifetime)
882
+ : closureLiveness(closureLiveness),
883
+ origIsUnmodifiedDuringClosureLifetime (
884
+ origIsUnmodifiedDuringClosureLifetime) {}
877
885
878
886
bool visitUse (Operand *origUse) {
879
887
LLVM_DEBUG (llvm::dbgs () << " looking at use\n " ;
880
888
origUse->getUser ()->printInContext (llvm::dbgs ());
881
889
llvm::dbgs () << " \n " );
882
-
890
+
883
891
// If the user doesn't write to memory, then it's harmless.
884
892
if (!origUse->getUser ()->mayWriteToMemory ()) {
885
893
return true ;
886
894
}
887
895
if (closureLiveness.isWithinBoundary (origUse->getUser ())) {
888
- origIsUnusedDuringClosureLifetime = false ;
889
- LLVM_DEBUG (llvm::dbgs () << " -- original has other possibly writing use during closure lifetime\n " ;
896
+ origIsUnmodifiedDuringClosureLifetime = false ;
897
+ LLVM_DEBUG (llvm::dbgs () << " -- original has other possibly writing "
898
+ " use during closure lifetime\n " ;
890
899
origUse->getUser ()->print (llvm::dbgs ());
891
900
llvm::dbgs () << " \n " );
892
901
return false ;
@@ -895,12 +904,12 @@ static SILValue tryRewriteToPartialApplyStack(
895
904
}
896
905
};
897
906
898
- OrigUnusedDuringClosureLifetimeWalker origUseWalker (closureLiveness,
899
- origIsUnusedDuringClosureLifetime );
907
+ OrigUnmodifiedDuringClosureLifetimeWalker origUseWalker (
908
+ closureLiveness, origIsUnmodifiedDuringClosureLifetime );
900
909
auto walkResult = std::move(origUseWalker).walk(orig);
901
-
902
- if (walkResult == AddressUseKind::Unknown
903
- || !origIsUnusedDuringClosureLifetime ) {
910
+
911
+ if (walkResult == AddressUseKind::Unknown ||
912
+ !origIsUnmodifiedDuringClosureLifetime ) {
904
913
continue ;
905
914
}
906
915
0 commit comments