@@ -920,45 +920,56 @@ static bool canReplaceCopiedArg(FullApplySite Apply, SILValue Arg,
920920 return true ;
921921}
922922
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+
923948// Check the legal conditions under which a Arg parameter (specified as ArgIdx)
924949// can be replaced with a concrete type. Concrete type info is passed as CEI
925950// argument.
926951bool SILCombiner::canReplaceArg (FullApplySite Apply,
927952 const OpenedArchetypeInfo &OAI,
928953 const ConcreteExistentialInfo &CEI,
929954 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.
944963 //
945964 // Note that the language does not allow Self to occur in contravariant
946965 // position. However, SIL does allow this and it can happen as a result of
947966 // upstream transformations. Since this is bail-out logic, it must handle
948967 // 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 ;
961971 }
972+
962973 // If the convention is mutating, then the existential must have been
963974 // initialized by copying the concrete value (regardless of whether
964975 // CEI.isConcreteValueCopied is true). Replacing the existential address with
@@ -1052,37 +1063,24 @@ SILValue SILCombiner::canCastArg(FullApplySite Apply,
10521063 !CEI.ConcreteValue ->getType ().isAddress ())
10531064 return SILValue ();
10541065
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.
10681074 //
10691075 // Note that the language does not allow Self to occur in contravariant
10701076 // position. However, SIL does allow this and it can happen as a result of
10711077 // upstream transformations. Since this is bail-out logic, it must handle
10721078 // 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 ();
10851082 }
1083+
10861084 return Builder.createUncheckedAddrCast (
10871085 Apply.getLoc (), Apply.getArgument (ArgIdx), CEI.ConcreteValue ->getType ());
10881086}
@@ -1293,10 +1291,11 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
12931291// / %existential = alloc_stack $Protocol
12941292// / %value = init_existential_addr %existential : $Concrete
12951293// / 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)
12981297// /
1299- // / ==> apply %witness<Concrete : Protocol >(%existential)
1298+ // / ==> apply %witness<$ Concrete>(%existential)
13001299SILInstruction *
13011300SILCombiner::propagateConcreteTypeOfInitExistential (FullApplySite Apply,
13021301 WitnessMethodInst *WMI) {
0 commit comments