@@ -41,6 +41,12 @@ llvm::cl::opt<bool> DisableConvertEscapeToNoEscapeSwitchEnumPeephole(
4141 " Disable the convert_escape_to_noescape switch enum peephole. " ),
4242 llvm::cl::Hidden);
4343
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+
4450using namespace swift ;
4551
4652// / Given an optional diamond, return the bottom of the diamond.
@@ -734,7 +740,7 @@ static SILValue tryRewriteToPartialApplyStack(
734740 SmallVector<SILInstruction *, 4 > lifetimeEnds;
735741 collectStackClosureLifetimeEnds (lifetimeEnds, closureOp);
736742
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
738744 // that SILGen emitted to allow the original partial_apply to take ownership.
739745 // We do this here because otherwise the move checker will see the copy as an
740746 // attempt to consume the value, which we don't want.
@@ -760,14 +766,14 @@ static SILValue tryRewriteToPartialApplyStack(
760766 LLVM_DEBUG (llvm::dbgs () << " -- not an alloc_stack\n " );
761767 continue ;
762768 }
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+ }
769775 }
770-
776+
771777 // Is the capture a borrow?
772778
773779 auto paramIndex = i + appliedArgStartIdx;
@@ -806,33 +812,33 @@ static SILValue tryRewriteToPartialApplyStack(
806812 if (!lookThroughMarkDependenceChainForValue (mark, newPA) ||
807813 mark->getBase () != stack) {
808814 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 " );
811816 initialization = nullptr ;
812817 break ;
813818 }
814819 markDep = mark;
815820
816821 continue ;
817822 }
818-
823+
819824 // If we saw more than just the initialization, this isn't a pattern we
820825 // recognize.
821826 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+
826831 initialization = nullptr ;
827832 break ;
828833 }
829834 if (auto possibleInit = dyn_cast<CopyAddrInst>(use->getUser ())) {
830835 // 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 " );
836842
837843 break ;
838844 }
@@ -860,33 +866,36 @@ static SILValue tryRewriteToPartialApplyStack(
860866 LLVM_DEBUG (llvm::dbgs () << " ++ found original:\n " ;
861867 orig->print (llvm::dbgs ());
862868 llvm::dbgs () << " \n " );
863-
864- bool origIsUnusedDuringClosureLifetime = true ;
865869
866- class OrigUnusedDuringClosureLifetimeWalker
870+ bool origIsUnmodifiedDuringClosureLifetime = true ;
871+
872+ class OrigUnmodifiedDuringClosureLifetimeWalker
867873 : public TransitiveAddressWalker<
868- OrigUnusedDuringClosureLifetimeWalker > {
874+ OrigUnmodifiedDuringClosureLifetimeWalker > {
869875 SSAPrunedLiveness &closureLiveness;
870- bool &origIsUnusedDuringClosureLifetime;
876+ bool &origIsUnmodifiedDuringClosureLifetime;
877+
871878 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) {}
877885
878886 bool visitUse (Operand *origUse) {
879887 LLVM_DEBUG (llvm::dbgs () << " looking at use\n " ;
880888 origUse->getUser ()->printInContext (llvm::dbgs ());
881889 llvm::dbgs () << " \n " );
882-
890+
883891 // If the user doesn't write to memory, then it's harmless.
884892 if (!origUse->getUser ()->mayWriteToMemory ()) {
885893 return true ;
886894 }
887895 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 " ;
890899 origUse->getUser ()->print (llvm::dbgs ());
891900 llvm::dbgs () << " \n " );
892901 return false ;
@@ -895,12 +904,12 @@ static SILValue tryRewriteToPartialApplyStack(
895904 }
896905 };
897906
898- OrigUnusedDuringClosureLifetimeWalker origUseWalker (closureLiveness,
899- origIsUnusedDuringClosureLifetime );
907+ OrigUnmodifiedDuringClosureLifetimeWalker origUseWalker (
908+ closureLiveness, origIsUnmodifiedDuringClosureLifetime );
900909 auto walkResult = std::move(origUseWalker).walk(orig);
901-
902- if (walkResult == AddressUseKind::Unknown
903- || !origIsUnusedDuringClosureLifetime ) {
910+
911+ if (walkResult == AddressUseKind::Unknown ||
912+ !origIsUnmodifiedDuringClosureLifetime ) {
904913 continue ;
905914 }
906915
0 commit comments