@@ -920,45 +920,56 @@ static bool canReplaceCopiedArg(FullApplySite Apply, SILValue Arg,
920
920
return true ;
921
921
}
922
922
923
+ // / Determine if the result type or argument types of the given apply, except
924
+ // / for the argument at \p SkipArgIdx, contain an opened archetype rooted
925
+ // / on \p RootOA.
926
+ static bool applyInvolvesOpenedArchetypeWithRoot (FullApplySite Apply,
927
+ OpenedArchetypeType *RootOA,
928
+ unsigned SkipArgIdx) {
929
+ if (Apply.getType ().getASTType ()->hasOpenedExistentialWithRoot (RootOA)) {
930
+ return true ;
931
+ }
932
+
933
+ const auto NumApplyArgs = Apply.getNumArguments ();
934
+ for (unsigned Idx = 0 ; Idx < NumApplyArgs; ++Idx) {
935
+ if (Idx == SkipArgIdx)
936
+ continue ;
937
+ if (Apply.getArgument (Idx)
938
+ ->getType ()
939
+ .getASTType ()
940
+ ->hasOpenedExistentialWithRoot (RootOA)) {
941
+ return true ;
942
+ }
943
+ }
944
+
945
+ return false ;
946
+ }
947
+
923
948
// Check the legal conditions under which a Arg parameter (specified as ArgIdx)
924
949
// can be replaced with a concrete type. Concrete type info is passed as CEI
925
950
// argument.
926
951
bool SILCombiner::canReplaceArg (FullApplySite Apply,
927
952
const OpenedArchetypeInfo &OAI,
928
953
const ConcreteExistentialInfo &CEI,
929
954
unsigned ArgIdx) {
930
-
931
- // Don't specialize apply instructions that return the callee's Arg type,
932
- // because this optimization does not know how to substitute types in the
933
- // users of this apply. In the function type substitution below, all
934
- // references to OpenedArchetype will be substituted. So walk to type to
935
- // find all possible references, such as returning Optional<Arg>.
936
- if (Apply.getType ().getASTType ().findIf (
937
- [&OAI](Type t) -> bool { return t->isEqual (OAI.OpenedArchetype ); })) {
938
- return false ;
939
- }
940
- // Bail out if any other arguments or indirect result that refer to the
941
- // OpenedArchetype. The following optimization substitutes all occurrences
942
- // of OpenedArchetype in the function signature, but will only rewrite the
943
- // Arg operand.
955
+ // Don't specialize apply instructions if the result type references
956
+ // OpenedArchetype, because this optimization does not know how to substitute
957
+ // types in the users of this apply. In the function type substitution below,
958
+ // all references to OpenedArchetype will be substituted. So walk the type to
959
+ // find all possible references, such as returning Optional<OpenedArchetype>.
960
+ // The same holds for other arguments or indirect result that refer to the
961
+ // OpenedArchetype, because the following optimization will rewrite only the
962
+ // argument at ArgIdx.
944
963
//
945
964
// Note that the language does not allow Self to occur in contravariant
946
965
// position. However, SIL does allow this and it can happen as a result of
947
966
// upstream transformations. Since this is bail-out logic, it must handle
948
967
// all verifiable SIL.
949
-
950
- // This bailout check is also needed for non-Self arguments [including Self].
951
- unsigned NumApplyArgs = Apply.getNumArguments ();
952
- for (unsigned Idx = 0 ; Idx < NumApplyArgs; ++Idx) {
953
- if (Idx == ArgIdx)
954
- continue ;
955
- if (Apply.getArgument (Idx)->getType ().getASTType ().findIf (
956
- [&OAI](Type t) -> bool {
957
- return t->isEqual (OAI.OpenedArchetype );
958
- })) {
959
- return false ;
960
- }
968
+ if (applyInvolvesOpenedArchetypeWithRoot (Apply, OAI.OpenedArchetype ,
969
+ ArgIdx)) {
970
+ return false ;
961
971
}
972
+
962
973
// If the convention is mutating, then the existential must have been
963
974
// initialized by copying the concrete value (regardless of whether
964
975
// CEI.isConcreteValueCopied is true). Replacing the existential address with
@@ -1052,37 +1063,24 @@ SILValue SILCombiner::canCastArg(FullApplySite Apply,
1052
1063
!CEI.ConcreteValue ->getType ().isAddress ())
1053
1064
return SILValue ();
1054
1065
1055
- // Don't specialize apply instructions that return the callee's Arg type,
1056
- // because this optimization does not know how to substitute types in the
1057
- // users of this apply. In the function type substitution below, all
1058
- // references to OpenedArchetype will be substituted. So walk to type to
1059
- // find all possible references, such as returning Optional<Arg>.
1060
- if (Apply.getType ().getASTType ().findIf (
1061
- [&OAI](Type t) -> bool { return t->isEqual (OAI.OpenedArchetype ); })) {
1062
- return SILValue ();
1063
- }
1064
- // Bail out if any other arguments or indirect result that refer to the
1065
- // OpenedArchetype. The following optimization substitutes all occurrences
1066
- // of OpenedArchetype in the function signature, but will only rewrite the
1067
- // Arg operand.
1066
+ // Don't specialize apply instructions if the result type references
1067
+ // OpenedArchetype, because this optimization does not know how to substitute
1068
+ // types in the users of this apply. In the function type substitution below,
1069
+ // all references to OpenedArchetype will be substituted. So walk the type to
1070
+ // find all possible references, such as returning Optional<OpenedArchetype>.
1071
+ // The same holds for other arguments or indirect result that refer to the
1072
+ // OpenedArchetype, because the following optimization will rewrite only the
1073
+ // argument at ArgIdx.
1068
1074
//
1069
1075
// Note that the language does not allow Self to occur in contravariant
1070
1076
// position. However, SIL does allow this and it can happen as a result of
1071
1077
// upstream transformations. Since this is bail-out logic, it must handle
1072
1078
// all verifiable SIL.
1073
-
1074
- // This bailout check is also needed for non-Self arguments [including Self].
1075
- unsigned NumApplyArgs = Apply.getNumArguments ();
1076
- for (unsigned Idx = 0 ; Idx < NumApplyArgs; ++Idx) {
1077
- if (Idx == ArgIdx)
1078
- continue ;
1079
- if (Apply.getArgument (Idx)->getType ().getASTType ().findIf (
1080
- [&OAI](Type t) -> bool {
1081
- return t->isEqual (OAI.OpenedArchetype );
1082
- })) {
1083
- return SILValue ();
1084
- }
1079
+ if (applyInvolvesOpenedArchetypeWithRoot (Apply, OAI.OpenedArchetype ,
1080
+ ArgIdx)) {
1081
+ return SILValue ();
1085
1082
}
1083
+
1086
1084
return Builder.createUncheckedAddrCast (
1087
1085
Apply.getLoc (), Apply.getArgument (ArgIdx), CEI.ConcreteValue ->getType ());
1088
1086
}
@@ -1293,10 +1291,11 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
1293
1291
// / %existential = alloc_stack $Protocol
1294
1292
// / %value = init_existential_addr %existential : $Concrete
1295
1293
// / copy_addr ... to %value
1296
- // / %witness = witness_method $@opened
1297
- // / apply %witness<T : Protocol>(%existential)
1294
+ // / %opened = open_existential_addr %existential
1295
+ // / %witness = witness_method $@opened(...) Protocol
1296
+ // / apply %witness<$@opened(...) Protocol>(%opened)
1298
1297
// /
1299
- // / ==> apply %witness<Concrete : Protocol >(%existential)
1298
+ // / ==> apply %witness<$ Concrete>(%existential)
1300
1299
SILInstruction *
1301
1300
SILCombiner::propagateConcreteTypeOfInitExistential (FullApplySite Apply,
1302
1301
WitnessMethodInst *WMI) {
0 commit comments