@@ -146,42 +146,20 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
146
146
if (SubstCalleeTy->hasArchetype () || ConvertCalleeTy->hasArchetype ())
147
147
return nullptr ;
148
148
149
- // Indirect results are not currently handled.
150
- if (AI.hasIndirectSILResults ())
151
- return nullptr ;
152
-
153
- // Bail if the result type of the converted callee is different from the callee's
154
- // result type of the apply instruction.
155
- if (SubstCalleeTy->getAllResultsSubstType (
156
- AI.getModule (), AI.getFunction ()->getTypeExpansionContext ()) !=
157
- ConvertCalleeTy->getAllResultsSubstType (
158
- AI.getModule (), AI.getFunction ()->getTypeExpansionContext ())) {
159
- return nullptr ;
160
- }
161
-
162
149
// Ok, we can now perform our transformation. Grab AI's operands and the
163
150
// relevant types from the ConvertFunction function type and AI.
164
151
Builder.setCurrentDebugScope (AI.getDebugScope ());
165
- OperandValueArrayRef Ops = AI.getArgumentsWithoutIndirectResults ();
152
+ OperandValueArrayRef Ops = AI.getArguments ();
166
153
SILFunctionConventions substConventions (SubstCalleeTy, FRI->getModule ());
167
154
SILFunctionConventions convertConventions (ConvertCalleeTy, FRI->getModule ());
168
155
auto context = AI.getFunction ()->getTypeExpansionContext ();
169
- auto oldOpTypes = substConventions.getParameterSILTypes (context);
170
- auto newOpTypes = convertConventions.getParameterSILTypes (context);
171
-
172
- assert (Ops.size () == SubstCalleeTy->getNumParameters ()
173
- && " Ops and op types must have same size." );
174
- assert (Ops.size () == ConvertCalleeTy->getNumParameters ()
175
- && " Ops and op types must have same size." );
156
+ auto oldOpRetTypes = substConventions.getIndirectSILResultTypes (context);
157
+ auto newOpRetTypes = convertConventions.getIndirectSILResultTypes (context);
158
+ auto oldOpParamTypes = substConventions.getParameterSILTypes (context);
159
+ auto newOpParamTypes = convertConventions.getParameterSILTypes (context);
176
160
177
161
llvm::SmallVector<SILValue, 8 > Args;
178
- auto newOpI = newOpTypes.begin ();
179
- auto oldOpI = oldOpTypes.begin ();
180
- for (unsigned i = 0 , e = Ops.size (); i != e; ++i, ++newOpI, ++oldOpI) {
181
- SILValue Op = Ops[i];
182
- SILType OldOpType = *oldOpI;
183
- SILType NewOpType = *newOpI;
184
-
162
+ auto convertOp = [&](SILValue Op, SILType OldOpType, SILType NewOpType) {
185
163
// Convert function takes refs to refs, address to addresses, and leaves
186
164
// other types alone.
187
165
if (OldOpType.isAddress ()) {
@@ -190,17 +168,68 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
190
168
Args.push_back (UAC);
191
169
} else if (OldOpType.getASTType () != NewOpType.getASTType ()) {
192
170
auto URC =
193
- Builder.createUncheckedReinterpretCast (AI.getLoc (), Op, NewOpType);
171
+ Builder.createUncheckedBitCast (AI.getLoc (), Op, NewOpType);
194
172
Args.push_back (URC);
195
173
} else {
196
174
Args.push_back (Op);
197
175
}
176
+ };
177
+
178
+ unsigned OpI = 0 ;
179
+
180
+ auto newRetI = newOpRetTypes.begin ();
181
+ auto oldRetI = oldOpRetTypes.begin ();
182
+
183
+ for (auto e = newOpRetTypes.end (); newRetI != e;
184
+ ++OpI, ++newRetI, ++oldRetI) {
185
+ convertOp (Ops[OpI], *oldRetI, *newRetI);
186
+ }
187
+
188
+ auto newParamI = newOpParamTypes.begin ();
189
+ auto oldParamI = oldOpParamTypes.begin ();
190
+ for (auto e = newOpParamTypes.end (); newParamI != e;
191
+ ++OpI, ++newParamI, ++oldParamI) {
192
+ convertOp (Ops[OpI], *oldParamI, *newParamI);
198
193
}
199
194
195
+ // Convert the direct results if they changed.
196
+ auto oldResultTy = SubstCalleeTy
197
+ ->getDirectFormalResultsType (AI.getModule (),
198
+ AI.getFunction ()->getTypeExpansionContext ());
199
+ auto newResultTy = ConvertCalleeTy
200
+ ->getDirectFormalResultsType (AI.getModule (),
201
+ AI.getFunction ()->getTypeExpansionContext ());
202
+
200
203
// Create the new apply inst.
201
204
if (auto *TAI = dyn_cast<TryApplyInst>(AI)) {
205
+ // If the results need to change, create a new landing block to do that
206
+ // conversion.
207
+ auto normalBB = TAI->getNormalBB ();
208
+ if (oldResultTy != newResultTy) {
209
+ normalBB = AI.getFunction ()->createBasicBlockBefore (TAI->getNormalBB ());
210
+ Builder.setInsertionPoint (normalBB);
211
+ SmallVector<SILValue, 4 > branchArgs;
212
+
213
+ auto oldOpResultTypes = substConventions.getDirectSILResultTypes (context);
214
+ auto newOpResultTypes = convertConventions.getDirectSILResultTypes (context);
215
+
216
+ auto oldRetI = oldOpResultTypes.begin ();
217
+ auto newRetI = newOpResultTypes.begin ();
218
+ auto origArgs = TAI->getNormalBB ()->getArguments ();
219
+ auto origArgI = origArgs.begin ();
220
+ for (auto e = newOpResultTypes.end (); newRetI != e;
221
+ ++oldRetI, ++newRetI, ++origArgI) {
222
+ auto arg = normalBB->createPhiArgument (*newRetI, (*origArgI)->getOwnershipKind ());
223
+ auto converted = Builder.createUncheckedBitCast (AI.getLoc (),
224
+ arg, *oldRetI);
225
+ branchArgs.push_back (converted);
226
+ }
227
+
228
+ Builder.createBranch (AI.getLoc (), TAI->getNormalBB (), branchArgs);
229
+ }
230
+
202
231
return Builder.createTryApply (AI.getLoc (), FRI, SubstitutionMap (), Args,
203
- TAI-> getNormalBB () , TAI->getErrorBB (),
232
+ normalBB , TAI->getErrorBB (),
204
233
TAI->getApplyOptions ());
205
234
}
206
235
@@ -213,12 +242,13 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
213
242
Options |= ApplyFlags::DoesNotThrow;
214
243
ApplyInst *NAI = Builder.createApply (AI.getLoc (), FRI, SubstitutionMap (),
215
244
Args, Options);
216
- assert (FullApplySite (NAI).getSubstCalleeType ()->getAllResultsSubstType (
217
- AI.getModule (), AI.getFunction ()->getTypeExpansionContext ()) ==
218
- AI.getSubstCalleeType ()->getAllResultsSubstType (
219
- AI.getModule (), AI.getFunction ()->getTypeExpansionContext ()) &&
220
- " Function types should be the same" );
221
- return NAI;
245
+ SILInstruction *result = NAI;
246
+
247
+ if (oldResultTy != newResultTy) {
248
+ result = Builder.createUncheckedBitCast (AI.getLoc (), NAI, oldResultTy);
249
+ }
250
+
251
+ return result;
222
252
}
223
253
224
254
// / Try to optimize a keypath application with an apply instruction.
0 commit comments