@@ -482,12 +482,12 @@ static ApplyInst *replaceApplyInst(SILBuilder &builder, SILLocation loc,
482
482
return newAI;
483
483
}
484
484
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) {
491
491
SILBasicBlock *normalBB = oldTAI->getNormalBB ();
492
492
SILBasicBlock *resultBB = nullptr ;
493
493
@@ -537,7 +537,7 @@ static TryApplyInst *replaceTryApplyInst(SILBuilder &builder, SILLocation loc,
537
537
}
538
538
539
539
builder.setInsertionPoint (normalBB->begin ());
540
- return newTAI;
540
+ return { newTAI, resultCastRequired} ;
541
541
}
542
542
543
543
static BeginApplyInst *
@@ -599,17 +599,18 @@ replacePartialApplyInst(SILBuilder &builder, SILLocation loc,
599
599
return newPAI;
600
600
}
601
601
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) {
608
608
switch (oldAS.getKind ()) {
609
609
case ApplySiteKind::ApplyInst: {
610
610
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 };
613
614
}
614
615
case ApplySiteKind::TryApplyInst: {
615
616
auto *oldTAI = cast<TryApplyInst>(oldAS);
@@ -618,14 +619,16 @@ static ApplySite replaceApplySite(SILBuilder &builder, SILLocation loc,
618
619
}
619
620
case ApplySiteKind::BeginApplyInst: {
620
621
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 };
623
625
}
624
626
case ApplySiteKind::PartialApplyInst: {
625
627
assert (newArgBorrows.empty ());
626
628
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 };
629
632
}
630
633
}
631
634
llvm_unreachable (" covered switch" );
@@ -729,10 +732,12 @@ bool swift::canDevirtualizeClassMethod(FullApplySite applySite, ClassDecl *cd,
729
732
// / \p ClassOrMetatype is a class value or metatype value that is the
730
733
// / self argument of the apply we will devirtualize.
731
734
// / 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) {
736
741
LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize : "
737
742
<< *applySite.getInstruction ());
738
743
@@ -793,8 +798,10 @@ FullApplySite swift::devirtualizeClassMethod(FullApplySite applySite,
793
798
newArgs.push_back (arg);
794
799
++paramArgIter;
795
800
}
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);
798
805
FullApplySite newAI = FullApplySite::isa (newAS.getInstruction ());
799
806
assert (newAI);
800
807
@@ -808,16 +815,14 @@ FullApplySite swift::devirtualizeClassMethod(FullApplySite applySite,
808
815
});
809
816
NumClassDevirt++;
810
817
811
- return newAI;
818
+ return { newAI, modifiedCFG} ;
812
819
}
813
820
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) {
819
824
if (!canDevirtualizeClassMethod (applySite, cd, ore, isEffectivelyFinalMethod))
820
- return FullApplySite ();
825
+ return { FullApplySite (), false } ;
821
826
return devirtualizeClassMethod (applySite, classInstance, cd, ore);
822
827
}
823
828
@@ -960,9 +965,12 @@ swift::getWitnessMethodSubstitutions(SILModule &module, ApplySite applySite,
960
965
// / Generate a new apply of a function_ref to replace an apply of a
961
966
// / witness_method when we've determined the actual function we'll end
962
967
// / 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) {
966
974
// We know the witness thunk and the corresponding set of substitutions
967
975
// required to invoke the protocol method at this point.
968
976
auto &module = applySite.getModule ();
@@ -1017,7 +1025,9 @@ static ApplySite devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
1017
1025
SILLocation loc = applySite.getLoc ();
1018
1026
auto *fri = applyBuilder.createFunctionRefFor (loc, f);
1019
1027
1020
- ApplySite newApplySite =
1028
+ ApplySite newApplySite;
1029
+ bool modifiedCFG;
1030
+ std::tie (newApplySite, modifiedCFG) =
1021
1031
replaceApplySite (applyBuilder, loc, applySite, fri, subMap, arguments,
1022
1032
substConv, borrowedArgs);
1023
1033
@@ -1029,7 +1039,7 @@ static ApplySite devirtualizeWitnessMethod(ApplySite applySite, SILFunction *f,
1029
1039
<< " Devirtualized call to " << NV (" Method" , f);
1030
1040
});
1031
1041
NumWitnessDevirt++;
1032
- return newApplySite;
1042
+ return { newApplySite, modifiedCFG} ;
1033
1043
}
1034
1044
1035
1045
static bool canDevirtualizeWitnessMethod (ApplySite applySite) {
@@ -1066,10 +1076,11 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite) {
1066
1076
// / In the cases where we can statically determine the function that
1067
1077
// / we'll call to, replace an apply of a witness_method with an apply
1068
1078
// / 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) {
1071
1082
if (!canDevirtualizeWitnessMethod (applySite))
1072
- return ApplySite ();
1083
+ return { ApplySite (), false } ;
1073
1084
1074
1085
SILFunction *f;
1075
1086
SILWitnessTable *wt;
@@ -1088,9 +1099,11 @@ ApplySite swift::tryDevirtualizeWitnessMethod(ApplySite applySite,
1088
1099
1089
1100
// / Attempt to devirtualize the given apply if possible, and return a
1090
1101
// / 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) {
1094
1107
LLVM_DEBUG (llvm::dbgs () << " Trying to devirtualize: "
1095
1108
<< *applySite.getInstruction ());
1096
1109
@@ -1105,7 +1118,7 @@ ApplySite swift::tryDevirtualizeApply(ApplySite applySite,
1105
1118
// TODO: check if we can also de-virtualize partial applies of class methods.
1106
1119
FullApplySite fas = FullApplySite::isa (applySite.getInstruction ());
1107
1120
if (!fas)
1108
- return ApplySite ();
1121
+ return { ApplySite (), false } ;
1109
1122
1110
1123
// / Optimize a class_method and alloc_ref pair into a direct function
1111
1124
// / reference:
@@ -1151,7 +1164,7 @@ ApplySite swift::tryDevirtualizeApply(ApplySite applySite,
1151
1164
return tryDevirtualizeClassMethod (fas, instance, cd, ore);
1152
1165
}
1153
1166
1154
- return ApplySite ();
1167
+ return { ApplySite (), false } ;
1155
1168
}
1156
1169
1157
1170
bool swift::canDevirtualizeApply (FullApplySite applySite,
0 commit comments