@@ -482,12 +482,12 @@ static ApplyInst *replaceApplyInst(SILBuilder &builder, SILLocation loc,
482482 return newAI;
483483}
484484
485- static TryApplyInst * replaceTryApplyInst (SILBuilder &builder, SILLocation loc,
486- TryApplyInst *oldTAI, SILValue newFn,
487- SubstitutionMap newSubs ,
488- ArrayRef<SILValue> newArgs ,
489- SILFunctionConventions conv,
490- ArrayRef<SILValue> newArgBorrows) {
485+ // Return the new try_apply and true if a cast required CFG modification.
486+ static std::pair< TryApplyInst *, bool >
487+ replaceTryApplyInst (SILBuilder &builder, SILLocation loc, TryApplyInst *oldTAI ,
488+ SILValue newFn, SubstitutionMap newSubs ,
489+ ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
490+ ArrayRef<SILValue> newArgBorrows) {
491491 SILBasicBlock *normalBB = oldTAI->getNormalBB ();
492492 SILBasicBlock *resultBB = nullptr ;
493493
@@ -537,7 +537,7 @@ static TryApplyInst *replaceTryApplyInst(SILBuilder &builder, SILLocation loc,
537537 }
538538
539539 builder.setInsertionPoint (normalBB->begin ());
540- return newTAI;
540+ return { newTAI, resultCastRequired} ;
541541}
542542
543543static BeginApplyInst *
@@ -599,17 +599,18 @@ replacePartialApplyInst(SILBuilder &builder, SILLocation loc,
599599 return newPAI;
600600}
601601
602- static ApplySite replaceApplySite (SILBuilder &builder, SILLocation loc,
603- ApplySite oldAS, SILValue newFn,
604- SubstitutionMap newSubs ,
605- ArrayRef<SILValue> newArgs ,
606- SILFunctionConventions conv,
607- ArrayRef<SILValue> newArgBorrows) {
602+ // Return the new apply and true if the CFG was also modified.
603+ static std::pair< ApplySite, bool >
604+ replaceApplySite (SILBuilder &builder, SILLocation loc, ApplySite oldAS ,
605+ SILValue newFn, SubstitutionMap newSubs ,
606+ ArrayRef<SILValue> newArgs, SILFunctionConventions conv,
607+ ArrayRef<SILValue> newArgBorrows) {
608608 switch (oldAS.getKind ()) {
609609 case ApplySiteKind::ApplyInst: {
610610 auto *oldAI = cast<ApplyInst>(oldAS);
611- return replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
612- newArgBorrows);
611+ return {replaceApplyInst (builder, loc, oldAI, newFn, newSubs, newArgs,
612+ newArgBorrows),
613+ false };
613614 }
614615 case ApplySiteKind::TryApplyInst: {
615616 auto *oldTAI = cast<TryApplyInst>(oldAS);
@@ -618,14 +619,16 @@ static ApplySite replaceApplySite(SILBuilder &builder, SILLocation loc,
618619 }
619620 case ApplySiteKind::BeginApplyInst: {
620621 auto *oldBAI = dyn_cast<BeginApplyInst>(oldAS);
621- return replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
622- newArgBorrows);
622+ return {replaceBeginApplyInst (builder, loc, oldBAI, newFn, newSubs, newArgs,
623+ newArgBorrows),
624+ false };
623625 }
624626 case ApplySiteKind::PartialApplyInst: {
625627 assert (newArgBorrows.empty ());
626628 auto *oldPAI = cast<PartialApplyInst>(oldAS);
627- return replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs,
628- newArgs);
629+ return {
630+ replacePartialApplyInst (builder, loc, oldPAI, newFn, newSubs, newArgs),
631+ false };
629632 }
630633 }
631634 llvm_unreachable (" covered switch" );
@@ -729,10 +732,12 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
729732// / \p ClassOrMetatype is a class value or metatype value that is the
730733// / self argument of the apply we will devirtualize.
731734// / return the result value of the new ApplyInst if created one or null.
732- FullApplySite swift::devirtualizeClassMethod (FullApplySite applySite,
733- SILValue classOrMetatype,
734- ClassDecl *cd,
735- OptRemark::Emitter *ore) {
735+ // /
736+ // / Return the new apply and true if the CFG was also modified.
737+ std::pair<FullApplySite, bool >
738+ swift::devirtualizeClassMethod (FullApplySite applySite,
739+ SILValue classOrMetatype, ClassDecl *cd,
740+ OptRemark::Emitter *ore) {
736741 LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
737742 << *applySite.getInstruction ());
738743
@@ -793,8 +798,10 @@ FullApplySite swift::devirtualizeClassMethod(FullApplySite applySite,
793798 newArgs.push_back (arg);
794799 ++paramArgIter;
795800 }
796- ApplySite newAS = replaceApplySite (builder, loc, applySite, fri, subs,
797- newArgs, substConv, newArgBorrows);
801+ ApplySite newAS;
802+ bool modifiedCFG;
803+ std::tie (newAS, modifiedCFG) = replaceApplySite (
804+ builder, loc, applySite, fri, subs, newArgs, substConv, newArgBorrows);
798805 FullApplySite newAI = FullApplySite::isa (newAS.getInstruction ());
799806 assert (newAI);
800807
@@ -808,16 +815,14 @@ FullApplySite swift::devirtualizeClassMethod(FullApplySite applySite,
808815 });
809816 NumClassDevirt++;
810817
811- return newAI;
818+ return { newAI, modifiedCFG} ;
812819}
813820
814- FullApplySite swift::tryDevirtualizeClassMethod (FullApplySite applySite,
815- SILValue classInstance,
816- ClassDecl *cd,
817- OptRemark::Emitter *ore,
818- bool isEffectivelyFinalMethod) {
821+ std::pair<FullApplySite, bool > swift::tryDevirtualizeClassMethod (
822+ FullApplySite applySite, SILValue classInstance, ClassDecl *cd,
823+ OptRemark::Emitter *ore, bool isEffectivelyFinalMethod) {
819824 if (!canDevirtualizeClassMethod (applySite, cd, ore, isEffectivelyFinalMethod))
820- return FullApplySite ();
825+ return { FullApplySite (), false } ;
821826 return devirtualizeClassMethod (applySite, classInstance, cd, ore);
822827}
823828
@@ -960,9 +965,12 @@ swift::getWitnessMethodSubstitutions(SILModule &module, ApplySite applySite,
960965// / Generate a new apply of a function_ref to replace an apply of a
961966// / witness_method when we've determined the actual function we'll end
962967// / up calling.
963- static ApplySite devirtualizeWitnessMethod (ApplySite applySite, SILFunction *f,
964- ProtocolConformanceRef cRef,
965- OptRemark::Emitter *ore) {
968+ // /
969+ // / Return the new apply and true if the CFG was also modified.
970+ static std::pair<ApplySite, bool >
971+ devirtualizeWitnessMethod (ApplySite applySite, SILFunction *f,
972+ ProtocolConformanceRef cRef,
973+ OptRemark::Emitter *ore) {
966974 // We know the witness thunk and the corresponding set of substitutions
967975 // required to invoke the protocol method at this point.
968976 auto &module = applySite.getModule ();
@@ -1017,7 +1025,9 @@ static ApplySite devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
10171025 SILLocation loc = applySite.getLoc ();
10181026 auto *fri = applyBuilder.createFunctionRefFor (loc, f);
10191027
1020- ApplySite newApplySite =
1028+ ApplySite newApplySite;
1029+ bool modifiedCFG;
1030+ std::tie (newApplySite, modifiedCFG) =
10211031 replaceApplySite (applyBuilder, loc, applySite, fri, subMap, arguments,
10221032 substConv, borrowedArgs);
10231033
@@ -1029,7 +1039,7 @@ static ApplySite devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
10291039 << " Devirtualized call to " << NV (" Method" , f);
10301040 });
10311041 NumWitnessDevirt++;
1032- return newApplySite;
1042+ return { newApplySite, modifiedCFG} ;
10331043}
10341044
10351045static bool canDevirtualizeWitnessMethod (ApplySite applySite) {
@@ -1066,10 +1076,11 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite) {
10661076// / In the cases where we can statically determine the function that
10671077// / we'll call to, replace an apply of a witness_method with an apply
10681078// / of a function_ref, returning the new apply.
1069- ApplySite swift::tryDevirtualizeWitnessMethod (ApplySite applySite,
1070- OptRemark::Emitter *ore) {
1079+ std::pair<ApplySite, bool >
1080+ swift::tryDevirtualizeWitnessMethod (ApplySite applySite,
1081+ OptRemark::Emitter *ore) {
10711082 if (!canDevirtualizeWitnessMethod (applySite))
1072- return ApplySite ();
1083+ return { ApplySite (), false } ;
10731084
10741085 SILFunction *f;
10751086 SILWitnessTable *wt;
@@ -1088,9 +1099,11 @@ ApplySite swift::tryDevirtualizeWitnessMethod(ApplySite applySite,
10881099
10891100// / Attempt to devirtualize the given apply if possible, and return a
10901101// / new instruction in that case, or nullptr otherwise.
1091- ApplySite swift::tryDevirtualizeApply (ApplySite applySite,
1092- ClassHierarchyAnalysis *cha,
1093- OptRemark::Emitter *ore) {
1102+ // /
1103+ // / Return the new apply and true if the CFG was also modified.
1104+ std::pair<ApplySite, bool >
1105+ swift::tryDevirtualizeApply (ApplySite applySite, ClassHierarchyAnalysis *cha,
1106+ OptRemark::Emitter *ore) {
10941107 LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize: "
10951108 << *applySite.getInstruction ());
10961109
@@ -1105,7 +1118,7 @@ ApplySite swift::tryDevirtualizeApply(ApplySite applySite,
11051118 // TODO: check if we can also de-virtualize partial applies of class methods.
11061119 FullApplySite fas = FullApplySite::isa (applySite.getInstruction ());
11071120 if (!fas)
1108- return ApplySite ();
1121+ return { ApplySite (), false } ;
11091122
11101123 // / Optimize a class_method and alloc_ref pair into a direct function
11111124 // / reference:
@@ -1151,7 +1164,7 @@ ApplySite swift::tryDevirtualizeApply(ApplySite applySite,
11511164 return tryDevirtualizeClassMethod (fas, instance, cd, ore);
11521165 }
11531166
1154- return ApplySite ();
1167+ return { ApplySite (), false } ;
11551168}
11561169
11571170bool swift::canDevirtualizeApply (FullApplySite applySite,
0 commit comments