@@ -460,11 +460,11 @@ getSubstitutionsForCallee(SILModule &module, CanSILFunctionType baseCalleeType,
460460 baseCalleeSig);
461461}
462462
463- static ApplyInst * replaceApplyInst (SILBuilder &builder, SILLocation loc,
464- ApplyInst *oldAI, SILValue newFn,
465- SubstitutionMap newSubs ,
466- ArrayRef<SILValue> newArgs ,
467- ArrayRef<SILValue> newArgBorrows) {
463+ // Return the new apply and true if a cast required CFG modification.
464+ static std::pair< ApplyInst *, bool /* changedCFG */ >
465+ replaceApplyInst (SILBuilder &builder, SILLocation loc, ApplyInst *oldAI ,
466+ SILValue newFn, SubstitutionMap newSubs ,
467+ ArrayRef<SILValue> newArgs, ArrayRef<SILValue> newArgBorrows) {
468468 auto *newAI =
469469 builder.createApply (loc, newFn, newSubs, newArgs, oldAI->isNonThrowing ());
470470
@@ -475,15 +475,15 @@ static ApplyInst *replaceApplyInst(SILBuilder &builder, SILLocation loc,
475475 }
476476
477477 // Check if any casting is required for the return value.
478- SILValue resultValue = castValueToABICompatibleType (
478+ auto castRes = castValueToABICompatibleType (
479479 &builder, loc, newAI, newAI->getType (), oldAI->getType ());
480480
481- oldAI->replaceAllUsesWith (resultValue );
482- return newAI;
481+ oldAI->replaceAllUsesWith (castRes. first );
482+ return { newAI, castRes. second } ;
483483}
484484
485485// Return the new try_apply and true if a cast required CFG modification.
486- static std::pair<TryApplyInst *, bool >
486+ static std::pair<TryApplyInst *, bool /* changedCFG */ >
487487replaceTryApplyInst (SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI,
488488 SILValue newFn, SubstitutionMap newSubs,
489489 ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
@@ -531,20 +531,22 @@ replaceTryApplyInst(SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI,
531531 builder.setInsertionPoint (resultBB);
532532
533533 SILValue resultValue = resultBB->getArgument (0 );
534- resultValue = castValueToABICompatibleType (&builder, loc, resultValue,
535- newResultTy, oldResultTy);
534+ std::tie ( resultValue, std::ignore) = castValueToABICompatibleType (
535+ &builder, loc, resultValue, newResultTy, oldResultTy);
536536 builder.createBranch (loc, normalBB, {resultValue});
537537 }
538538
539539 builder.setInsertionPoint (normalBB->begin ());
540540 return {newTAI, resultCastRequired};
541541}
542542
543- static BeginApplyInst *
543+ // Return the new begin_apply and true if a cast required CFG modification.
544+ static std::pair<BeginApplyInst *, bool /* changedCFG */ >
544545replaceBeginApplyInst (SILBuilder &builder, SILLocation loc,
545546 BeginApplyInst *oldBAI, SILValue newFn,
546547 SubstitutionMap newSubs, ArrayRef<SILValue> newArgs,
547548 ArrayRef<SILValue> newArgBorrows) {
549+ bool changedCFG = false ;
548550 auto *newBAI = builder.createBeginApply (loc, newFn, newSubs, newArgs,
549551 oldBAI->isNonThrowing ());
550552
@@ -558,13 +560,14 @@ replaceBeginApplyInst(SILBuilder &builder, SILLocation loc,
558560 for (auto i : indices (oldYields)) {
559561 auto oldYield = oldYields[i];
560562 auto newYield = newYields[i];
561- newYield = castValueToABICompatibleType (
563+ auto yieldCastRes = castValueToABICompatibleType (
562564 &builder, loc, newYield, newYield->getType (), oldYield->getType ());
563- oldYield->replaceAllUsesWith (newYield);
565+ oldYield->replaceAllUsesWith (yieldCastRes.first );
566+ changedCFG |= yieldCastRes.second ;
564567 }
565568
566569 if (newArgBorrows.empty ())
567- return newBAI;
570+ return { newBAI, changedCFG} ;
568571
569572 SILValue token = newBAI->getTokenResult ();
570573
@@ -579,10 +582,11 @@ replaceBeginApplyInst(SILBuilder &builder, SILLocation loc,
579582 }
580583 }
581584
582- return newBAI;
585+ return { newBAI, changedCFG} ;
583586}
584587
585- static PartialApplyInst *
588+ // Return the new partial_apply and true if a cast required CFG modification.
589+ static std::pair<PartialApplyInst *, bool /* changedCFG */ >
586590replacePartialApplyInst (SILBuilder &builder, SILLocation loc,
587591 PartialApplyInst *oldPAI, SILValue newFn,
588592 SubstitutionMap newSubs, ArrayRef<SILValue> newArgs) {
@@ -592,25 +596,24 @@ replacePartialApplyInst(SILBuilder &builder, SILLocation loc,
592596 builder.createPartialApply (loc, newFn, newSubs, newArgs, convention);
593597
594598 // Check if any casting is required for the partially-applied function.
595- SILValue resultValue = castValueToABICompatibleType (
599+ auto castRes = castValueToABICompatibleType (
596600 &builder, loc, newPAI, newPAI->getType (), oldPAI->getType ());
597- oldPAI->replaceAllUsesWith (resultValue );
601+ oldPAI->replaceAllUsesWith (castRes. first );
598602
599- return newPAI;
603+ return { newPAI, castRes. second } ;
600604}
601605
602606// Return the new apply and true if the CFG was also modified.
603- static std::pair<ApplySite, bool >
607+ static std::pair<ApplySite, bool /* changedCFG */ >
604608replaceApplySite (SILBuilder &builder, SILLocation loc, ApplySite oldAS,
605609 SILValue newFn, SubstitutionMap newSubs,
606610 ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
607611 ArrayRef<SILValue> newArgBorrows) {
608612 switch (oldAS.getKind ()) {
609613 case ApplySiteKind::ApplyInst: {
610614 auto *oldAI = cast<ApplyInst>(oldAS);
611- return {replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
612- newArgBorrows),
613- false };
615+ return replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
616+ newArgBorrows);
614617 }
615618 case ApplySiteKind::TryApplyInst: {
616619 auto *oldTAI = cast<TryApplyInst>(oldAS);
@@ -619,16 +622,14 @@ replaceApplySite(SILBuilder &builder, SILLocation loc, ApplySite oldAS,
619622 }
620623 case ApplySiteKind::BeginApplyInst: {
621624 auto *oldBAI = dyn_cast<BeginApplyInst>(oldAS);
622- return {replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
623- newArgBorrows),
624- false };
625+ return replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
626+ newArgBorrows);
625627 }
626628 case ApplySiteKind::PartialApplyInst: {
627629 assert (newArgBorrows.empty ());
628630 auto *oldPAI = cast<PartialApplyInst>(oldAS);
629- return {
630- replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs, newArgs),
631- false };
631+ return replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs,
632+ newArgs);
632633 }
633634 }
634635 llvm_unreachable (" covered switch" );
@@ -734,10 +735,11 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
734735// / return the result value of the new ApplyInst if created one or null.
735736// /
736737// / Return the new apply and true if the CFG was also modified.
737- std::pair<FullApplySite, bool >
738+ std::pair<FullApplySite, bool /* changedCFG */ >
738739swift::devirtualizeClassMethod (FullApplySite applySite,
739740 SILValue classOrMetatype, ClassDecl *cd,
740741 OptRemark::Emitter *ore) {
742+ bool changedCFG = false ;
741743 LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
742744 << *applySite.getInstruction ());
743745
@@ -775,9 +777,11 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
775777
776778 auto indirectResultArgIter = applySite.getIndirectSILResults ().begin ();
777779 for (auto resultTy : substConv.getIndirectSILResultTypes ()) {
778- newArgs. push_back ( castValueToABICompatibleType (
780+ auto castRes = castValueToABICompatibleType (
779781 &builder, loc, *indirectResultArgIter, indirectResultArgIter->getType (),
780- resultTy));
782+ resultTy);
783+ newArgs.push_back (castRes.first );
784+ changedCFG |= castRes.second ;
781785 ++indirectResultArgIter;
782786 }
783787
@@ -793,15 +797,18 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
793797 arg = borrowBuilder.createBeginBorrow (loc, arg);
794798 newArgBorrows.push_back (arg);
795799 }
796- arg = castValueToABICompatibleType (&builder, loc, arg,
800+ auto argCastRes = castValueToABICompatibleType (&builder, loc, arg,
797801 paramArgIter->getType (), paramType);
798- newArgs.push_back (arg);
802+
803+ newArgs.push_back (argCastRes.first );
804+ changedCFG |= argCastRes.second ;
799805 ++paramArgIter;
800806 }
801807 ApplySite newAS;
802- bool modifiedCFG ;
803- std::tie (newAS, modifiedCFG ) = replaceApplySite (
808+ bool neededCFGChange ;
809+ std::tie (newAS, neededCFGChange ) = replaceApplySite (
804810 builder, loc, applySite, fri, subs, newArgs, substConv, newArgBorrows);
811+ changedCFG |= neededCFGChange;
805812 FullApplySite newAI = FullApplySite::isa (newAS.getInstruction ());
806813 assert (newAI);
807814
@@ -815,7 +822,7 @@ swift::devirtualizeClassMethod(FullApplySite applySite,
815822 });
816823 NumClassDevirt++;
817824
818- return {newAI, modifiedCFG };
825+ return {newAI, changedCFG };
819826}
820827
821828std::pair<FullApplySite, bool > swift::tryDevirtualizeClassMethod (
@@ -971,6 +978,7 @@ static std::pair<ApplySite, bool>
971978devirtualizeWitnessMethod (ApplySite applySite, SILFunction *f,
972979 ProtocolConformanceRef cRef,
973980 OptRemark::Emitter *ore) {
981+ bool changedCFG = false ;
974982 // We know the witness thunk and the corresponding set of substitutions
975983 // required to invoke the protocol method at this point.
976984 auto &module = applySite.getModule ();
@@ -1012,8 +1020,10 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
10121020 arg = borrowBuilder.createBeginBorrow (applySite.getLoc (), arg);
10131021 borrowedArgs.push_back (arg);
10141022 }
1015- arg = castValueToABICompatibleType (&argBuilder, applySite.getLoc (), arg,
1016- arg->getType (), paramType);
1023+ auto argCastRes = castValueToABICompatibleType (
1024+ &argBuilder, applySite.getLoc (), arg, arg->getType (), paramType);
1025+ arg = argCastRes.first ;
1026+ changedCFG |= argCastRes.second ;
10171027 }
10181028 arguments.push_back (arg);
10191029 }
@@ -1026,10 +1036,11 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
10261036 auto *fri = applyBuilder.createFunctionRefFor (loc, f);
10271037
10281038 ApplySite newApplySite;
1029- bool modifiedCFG ;
1030- std::tie (newApplySite, modifiedCFG ) =
1039+ bool neededCFGChange = false ;
1040+ std::tie (newApplySite, neededCFGChange ) =
10311041 replaceApplySite (applyBuilder, loc, applySite, fri, subMap, arguments,
10321042 substConv, borrowedArgs);
1043+ changedCFG |= neededCFGChange;
10331044
10341045 if (ore)
10351046 ore->emit ([&]() {
@@ -1039,7 +1050,7 @@ devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
10391050 << " Devirtualized call to " << NV (" Method" , f);
10401051 });
10411052 NumWitnessDevirt++;
1042- return {newApplySite, modifiedCFG };
1053+ return {newApplySite, changedCFG };
10431054}
10441055
10451056static bool canDevirtualizeWitnessMethod (ApplySite applySite) {
0 commit comments