@@ -174,14 +174,19 @@ cleanupAfterCall(FullApplySite apply,
174
174
// that lowers values to storage.
175
175
// ===----------------------------------------------------------------------===//
176
176
177
- // / If \p pseudoResult has multiple results, return the destructure.
178
- static DestructureTupleInst * getCallMultiResult (SILValue pseudoResult) {
179
- if (pseudoResult-> getType (). is <TupleType>() ) {
180
- if (auto *use = pseudoResult-> getSingleUse () )
181
- return cast<DestructureTupleInst>(use-> getUser ()) ;
177
+ // / If \p pseudoResult represents multiple results and at least one result is
178
+ // / used, then return the destructure.
179
+ static DestructureTupleInst * getCallDestructure (FullApplySite apply ) {
180
+ if (apply. getSubstCalleeConv (). getNumDirectSILResults () == 1 )
181
+ return nullptr ;
182
182
183
- assert (pseudoResult->use_empty () && " pseudo result can't be used" );
184
- }
183
+ SILValue pseudoResult = apply.getResult ();
184
+ assert (pseudoResult->getType ().is <TupleType>());
185
+ if (auto *use = pseudoResult->getSingleUse ())
186
+ return cast<DestructureTupleInst>(use->getUser ());
187
+
188
+ assert (pseudoResult->use_empty ()
189
+ && " pseudo result can only be used by a single destructure_tuple" );
185
190
return nullptr ;
186
191
}
187
192
@@ -205,19 +210,18 @@ static bool
205
210
visitCallResults (FullApplySite apply,
206
211
llvm::function_ref<bool (SILValue, SILResultInfo)> visitor) {
207
212
auto fnConv = apply.getSubstCalleeConv ();
208
- SILValue pseudoResult = apply.getPseudoResult ();
209
- if (auto *destructure = getCallMultiResult (pseudoResult)) {
213
+ if (auto *destructure = getCallDestructure (apply)) {
210
214
return visitCallMultiResults (destructure, fnConv, visitor);
211
215
}
212
- return visitor (pseudoResult , *fnConv.getDirectSILResults ().begin ());
216
+ return visitor (apply. getResult () , *fnConv.getDirectSILResults ().begin ());
213
217
}
214
218
215
219
// / Return true if the given value is either a "fake" tuple that represents all
216
220
// / of a call's results or an empty tuple of no results. This may return true
217
221
// / for either tuple_inst or a block argument.
218
222
static bool isPseudoCallResult (SILValue value) {
219
- if (isa <ApplyInst>(value))
220
- return value-> getType (). is <TupleType>() ;
223
+ if (auto *apply = dyn_cast <ApplyInst>(value))
224
+ return ApplySite (apply). getSubstCalleeConv (). getNumDirectSILResults () > 1 ;
221
225
222
226
auto *bbArg = dyn_cast<SILPhiArgument>(value);
223
227
if (!bbArg)
@@ -227,11 +231,18 @@ static bool isPseudoCallResult(SILValue value) {
227
231
if (!term)
228
232
return false ;
229
233
230
- return isa<TryApplyInst>(term) && bbArg->getType ().is <TupleType>();
234
+ auto *tryApply = dyn_cast<TryApplyInst>(term);
235
+ if (!tryApply)
236
+ return false ;
237
+
238
+ return ApplySite (tryApply).getSubstCalleeConv ().getNumDirectSILResults () > 1 ;
231
239
}
232
240
233
241
// / Return true if this is a pseudo-return value.
234
242
static bool isPseudoReturnValue (SILValue value) {
243
+ if (value->getFunction ()->getConventions ().getNumDirectSILResults () < 2 )
244
+ return false ;
245
+
235
246
if (auto *tuple = dyn_cast<TupleInst>(value)) {
236
247
Operand *singleUse = tuple->getSingleUse ();
237
248
return singleUse && isa<ReturnInst>(singleUse->getUser ());
@@ -261,9 +272,12 @@ static SILValue getTupleStorageValue(Operand *operand) {
261
272
if (!singleUse || !isa<ReturnInst>(singleUse->getUser ()))
262
273
return tuple;
263
274
275
+ SILFunction *function = tuple->getFunction ();
276
+ if (function->getConventions ().getNumDirectSILResults () < 2 )
277
+ return tuple;
278
+
264
279
unsigned resultIdx = tuple->getElementIndex (operand);
265
280
266
- SILFunction *function = tuple->getFunction ();
267
281
auto loweredFnConv = getLoweredFnConv (function);
268
282
assert (loweredFnConv.getResults ().size () == tuple->getElements ().size ());
269
283
@@ -279,11 +293,11 @@ static SILValue getTupleStorageValue(Operand *operand) {
279
293
280
294
// / Return the value representing storage for a single return value.
281
295
// /
282
- // / bb0(%loweredIndirectResult : $*T, ...)
296
+ // / bb0(%loweredIndirectResult : $*T, ...) // function entry
283
297
// / return %oper
284
298
// /
285
299
// / For %oper, return %loweredIndirectResult
286
- static SILValue getSingleReturnValue (Operand *operand) {
300
+ static SILValue getSingleReturnAddress (Operand *operand) {
287
301
assert (!isPseudoReturnValue (operand->get ()));
288
302
289
303
auto *function = operand->getParentFunction ();
@@ -612,7 +626,7 @@ void OpaqueValueVisitor::visitValue(SILValue value) {
612
626
613
627
// Canonicalize returned values.
614
628
//
615
- // Given:
629
+ // Given $() -> @out (T, T) :
616
630
// %t = def : $(T, T)
617
631
// use %t : $(T, T)
618
632
// return %t : $(T, T)
@@ -807,7 +821,7 @@ static SILValue getProjectedUseValue(Operand *operand) {
807
821
808
822
// Return instructions can project into the return value.
809
823
case SILInstructionKind::ReturnInst:
810
- return getSingleReturnValue (operand);
824
+ return getSingleReturnAddress (operand);
811
825
}
812
826
return SILValue ();
813
827
}
@@ -1420,9 +1434,7 @@ AddressMaterialization::materializeProjectionIntoUse(Operand *operand,
1420
1434
}
1421
1435
case SILInstructionKind::TupleInst: {
1422
1436
auto *tupleInst = cast<TupleInst>(user);
1423
- // Function return values.
1424
- if (tupleInst->hasOneUse ()
1425
- && isa<ReturnInst>(tupleInst->use_begin ()->getUser ())) {
1437
+ if (isPseudoReturnValue (tupleInst)) {
1426
1438
unsigned resultIdx = tupleInst->getElementIndex (operand);
1427
1439
assert (resultIdx < pass.loweredFnConv .getNumIndirectSILResults ());
1428
1440
// Cannot call getIndirectSILResults here because that API uses the
@@ -1830,9 +1842,8 @@ void ApplyRewriter::convertApplyWithIndirectResults() {
1830
1842
// Populate newCallArgs.
1831
1843
makeIndirectArgs (newCallArgs);
1832
1844
1833
- // Record the original results before potentially removing the apply
1834
- // (try_apply is removed during rewriting).
1835
- auto *destructure = getCallMultiResult (apply.getPseudoResult ());
1845
+ // Record the original result destructure before deleting a try_apply.
1846
+ auto *destructure = getCallDestructure (apply);
1836
1847
1837
1848
switch (apply.getKind ()) {
1838
1849
case FullApplySiteKind::ApplyInst: {
@@ -2071,7 +2082,7 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
2071
2082
tryApply->getNormalBB (), tryApply->getErrorBB (),
2072
2083
tryApply->getApplyOptions (), tryApply->getSpecializationInfo ());
2073
2084
2074
- auto *resultArg = cast<SILArgument>(apply.getPseudoResult ());
2085
+ auto *resultArg = cast<SILArgument>(apply.getResult ());
2075
2086
2076
2087
auto replaceTermResult = [&](SILValue newResultVal) {
2077
2088
SILType resultTy = loweredCalleeConv.getSILResultType (typeCtx);
@@ -2091,8 +2102,6 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
2091
2102
2092
2103
// Handle a single opaque result value.
2093
2104
if (pass.valueStorageMap .contains (resultArg)) {
2094
- assert (!resultArg->getType ().is <TupleType>());
2095
-
2096
2105
// Storage was materialized by materializeIndirectResultAddress.
2097
2106
auto &origStorage = pass.valueStorageMap .getStorage (resultArg);
2098
2107
assert (origStorage.isRewritten );
@@ -2142,7 +2151,7 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
2142
2151
// // no uses of %d1, %d2
2143
2152
//
2144
2153
void ApplyRewriter::replaceDirectResults (DestructureTupleInst *oldDestructure) {
2145
- SILValue newPseudoResult = apply.getPseudoResult ();
2154
+ SILValue newPseudoResult = apply.getResult ();
2146
2155
2147
2156
DestructureTupleInst *newDestructure = nullptr ;
2148
2157
if (loweredCalleeConv.getNumDirectSILResults () > 1 ) {
@@ -2950,7 +2959,7 @@ static void rewriteIndirectApply(FullApplySite apply,
2950
2959
ApplyRewriter (apply, pass).convertApplyWithIndirectResults ();
2951
2960
2952
2961
if (!apply.getInstruction ()->isDeleted ()) {
2953
- assert (!getCallMultiResult (apply. getPseudoResult () )
2962
+ assert (!getCallDestructure (apply)
2954
2963
&& " replaceDirectResults deletes the destructure" );
2955
2964
pass.deleter .forceDelete (apply.getInstruction ());
2956
2965
}
0 commit comments