@@ -36,220 +36,19 @@ namespace autodiff {
36
36
// moved to a shared location.
37
37
// ===----------------------------------------------------------------------===//
38
38
39
- CanGenericSignature buildThunkSignature (SILFunction *fn, bool inheritGenericSig,
40
- OpenedArchetypeType *openedExistential,
41
- GenericEnvironment *&genericEnv,
42
- SubstitutionMap &contextSubs,
43
- SubstitutionMap &interfaceSubs,
44
- ArchetypeType *&newArchetype) {
45
- // If there's no opened existential, we just inherit the generic environment
46
- // from the parent function.
47
- if (openedExistential == nullptr ) {
48
- auto genericSig = fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
49
- genericEnv = fn->getGenericEnvironment ();
50
- interfaceSubs = fn->getForwardingSubstitutionMap ();
51
- contextSubs = interfaceSubs;
52
- return genericSig;
53
- }
54
-
55
- auto &ctx = fn->getASTContext ();
56
-
57
- // Add the existing generic signature.
58
- GenericSignature baseGenericSig;
59
- int depth = 0 ;
60
- if (inheritGenericSig) {
61
- baseGenericSig = fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
62
- if (baseGenericSig)
63
- depth = baseGenericSig.getGenericParams ().back ()->getDepth () + 1 ;
64
- }
65
-
66
- // Add a new generic parameter to replace the opened existential.
67
- auto *newGenericParam =
68
- GenericTypeParamType::get (/* type sequence*/ false , depth, 0 , ctx);
69
-
70
- assert (openedExistential->isRoot ());
71
- auto constraint = openedExistential->getExistentialType ();
72
- if (auto existential = constraint->getAs <ExistentialType>())
73
- constraint = existential->getConstraintType ();
74
-
75
- Requirement newRequirement (RequirementKind::Conformance, newGenericParam,
76
- constraint);
77
-
78
- auto genericSig = buildGenericSignature (ctx, baseGenericSig,
79
- { newGenericParam },
80
- { newRequirement });
81
- genericEnv = genericSig.getGenericEnvironment ();
82
-
83
- newArchetype =
84
- genericEnv->mapTypeIntoContext (newGenericParam)->castTo <ArchetypeType>();
85
-
86
- // Calculate substitutions to map the caller's archetypes to the thunk's
87
- // archetypes.
88
- if (auto calleeGenericSig =
89
- fn->getLoweredFunctionType ()->getSubstGenericSignature ()) {
90
- contextSubs = SubstitutionMap::get (
91
- calleeGenericSig,
92
- [&](SubstitutableType *type) -> Type {
93
- return genericEnv->mapTypeIntoContext (type);
94
- },
95
- MakeAbstractConformanceForGenericType ());
96
- }
97
-
98
- // Calculate substitutions to map interface types to the caller's archetypes.
99
- interfaceSubs = SubstitutionMap::get (
100
- genericSig,
101
- [&](SubstitutableType *type) -> Type {
102
- if (type->isEqual (newGenericParam))
103
- return openedExistential;
104
- return fn->mapTypeIntoContext (type);
105
- },
106
- MakeAbstractConformanceForGenericType ());
107
-
108
- return genericSig.getCanonicalSignature ();
109
- }
110
-
111
39
CanSILFunctionType buildThunkType (SILFunction *fn,
112
40
CanSILFunctionType &sourceType,
113
41
CanSILFunctionType &expectedType,
114
42
GenericEnvironment *&genericEnv,
115
43
SubstitutionMap &interfaceSubs,
116
44
bool withoutActuallyEscaping,
117
45
DifferentiationThunkKind thunkKind) {
118
- assert (!expectedType->isPolymorphic () &&
119
- !expectedType->getCombinedSubstitutions ());
120
- assert (!sourceType->isPolymorphic () &&
121
- !sourceType->getCombinedSubstitutions ());
122
-
123
- // Cannot build a reabstraction thunk without context. Ownership semantics
124
- // on the result type are required.
125
- if (thunkKind == DifferentiationThunkKind::Reabstraction)
126
- assert (expectedType->getExtInfo ().hasContext ());
127
-
128
- // This may inherit @noescape from the expected type. The `@noescape`
129
- // attribute is only stripped when using this type to materialize a new decl.
130
- // Use `@convention(thin)` if:
131
- // - Building a reabstraction thunk type.
132
- // - Building an index subset thunk type, where the expected type has context
133
- // (i.e. is `@convention(thick)`).
134
- auto extInfoBuilder = expectedType->getExtInfo ().intoBuilder ();
135
- if (thunkKind == DifferentiationThunkKind::Reabstraction ||
136
- extInfoBuilder.hasContext ()) {
137
- extInfoBuilder = extInfoBuilder.withRepresentation (
138
- SILFunctionType::Representation::Thin);
139
- }
140
- if (withoutActuallyEscaping)
141
- extInfoBuilder = extInfoBuilder.withNoEscape (false );
142
-
143
- // Does the thunk type involve archetypes other than opened existentials?
144
- bool hasArchetypes = false ;
145
- // Does the thunk type involve an open existential type?
146
- CanOpenedArchetypeType openedExistential;
147
- auto archetypeVisitor = [&](CanType t) {
148
- if (auto archetypeTy = dyn_cast<ArchetypeType>(t)) {
149
- if (auto opened = dyn_cast<OpenedArchetypeType>(archetypeTy)) {
150
- const auto root = cast<OpenedArchetypeType>(CanType (opened->getRoot ()));
151
- assert ((openedExistential == CanArchetypeType () ||
152
- openedExistential == root) &&
153
- " one too many open existentials" );
154
- openedExistential = root;
155
- } else {
156
- hasArchetypes = true ;
157
- }
158
- }
159
- };
160
-
161
- // Use the generic signature from the context if the thunk involves
162
- // generic parameters.
163
- CanGenericSignature genericSig;
164
- SubstitutionMap contextSubs;
165
- ArchetypeType *newArchetype = nullptr ;
166
-
167
- if (expectedType->hasArchetype () || sourceType->hasArchetype ()) {
168
- expectedType.visit (archetypeVisitor);
169
- sourceType.visit (archetypeVisitor);
170
- genericSig =
171
- buildThunkSignature (fn, hasArchetypes, openedExistential, genericEnv,
172
- contextSubs, interfaceSubs, newArchetype);
173
- }
174
-
175
- auto substTypeHelper = [&](SubstitutableType *type) -> Type {
176
- if (CanType (type) == openedExistential)
177
- return newArchetype;
178
- return Type (type).subst (contextSubs);
179
- };
180
- auto substConformanceHelper = LookUpConformanceInSubstitutionMap (contextSubs);
181
-
182
- // Utility function to apply contextSubs, and also replace the
183
- // opened existential with the new archetype.
184
- auto substLoweredTypeIntoThunkContext =
185
- [&](CanSILFunctionType t) -> CanSILFunctionType {
186
- return SILType::getPrimitiveObjectType (t)
187
- .subst (fn->getModule (), substTypeHelper, substConformanceHelper)
188
- .castTo <SILFunctionType>();
189
- };
190
-
191
- sourceType = substLoweredTypeIntoThunkContext (sourceType);
192
- expectedType = substLoweredTypeIntoThunkContext (expectedType);
193
-
194
- // If our parent function was pseudogeneric, this thunk must also be
195
- // pseudogeneric, since we have no way to pass generic parameters.
196
- if (genericSig)
197
- if (fn->getLoweredFunctionType ()->isPseudogeneric ())
198
- extInfoBuilder = extInfoBuilder.withIsPseudogeneric ();
199
-
200
- // Add the function type as the parameter.
201
- auto contextConvention =
202
- SILType::getPrimitiveObjectType (sourceType).isTrivial (*fn)
203
- ? ParameterConvention::Direct_Unowned
204
- : ParameterConvention::Direct_Guaranteed;
205
- SmallVector<SILParameterInfo, 4 > params;
206
- params.append (expectedType->getParameters ().begin (),
207
- expectedType->getParameters ().end ());
208
- // Add reabstraction function parameter only if building a reabstraction thunk
209
- // type.
210
- if (thunkKind == DifferentiationThunkKind::Reabstraction)
211
- params.push_back ({sourceType, sourceType->getExtInfo ().hasContext ()
212
- ? contextConvention
213
- : ParameterConvention::Direct_Unowned});
214
-
215
- auto mapTypeOutOfContext = [&](CanType type) -> CanType {
216
- return type->mapTypeOutOfContext ()->getCanonicalType (genericSig);
217
- };
218
-
219
- // Map the parameter and expected types out of context to get the interface
220
- // type of the thunk.
221
- SmallVector<SILParameterInfo, 4 > interfaceParams;
222
- interfaceParams.reserve (params.size ());
223
- for (auto ¶m : params) {
224
- auto interfaceParam = param.map (mapTypeOutOfContext);
225
- interfaceParams.push_back (interfaceParam);
226
- }
227
-
228
- SmallVector<SILYieldInfo, 4 > interfaceYields;
229
- for (auto &yield : expectedType->getYields ()) {
230
- auto interfaceYield = yield.map (mapTypeOutOfContext);
231
- interfaceYields.push_back (interfaceYield);
232
- }
233
-
234
- SmallVector<SILResultInfo, 4 > interfaceResults;
235
- for (auto &result : expectedType->getResults ()) {
236
- auto interfaceResult = result.map (mapTypeOutOfContext);
237
- interfaceResults.push_back (interfaceResult);
238
- }
239
-
240
- Optional<SILResultInfo> interfaceErrorResult;
241
- if (expectedType->hasErrorResult ()) {
242
- auto errorResult = expectedType->getErrorResult ();
243
- interfaceErrorResult = errorResult.map (mapTypeOutOfContext);
244
- }
245
-
246
- // The type of the thunk function.
247
- return SILFunctionType::get (
248
- genericSig, extInfoBuilder.build (), expectedType->getCoroutineKind (),
249
- ParameterConvention::Direct_Unowned, interfaceParams, interfaceYields,
250
- interfaceResults, interfaceErrorResult,
251
- expectedType->getPatternSubstitutions (), SubstitutionMap (),
252
- fn->getASTContext ());
46
+ CanType inputSubstType;
47
+ CanType outputSubstType;
48
+ CanType dynamicSelfType;
49
+ return buildSILFunctionThunkType (
50
+ fn, sourceType, expectedType, inputSubstType, outputSubstType, genericEnv,
51
+ interfaceSubs, dynamicSelfType, withoutActuallyEscaping, thunkKind);
253
52
}
254
53
255
54
// / Forward function arguments, handling ownership convention mismatches.
0 commit comments