@@ -174,14 +174,19 @@ cleanupAfterCall(FullApplySite apply,
174174// that lowers values to storage.
175175// ===----------------------------------------------------------------------===//
176176
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 ;
182182
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" );
185190 return nullptr ;
186191}
187192
@@ -205,19 +210,18 @@ static bool
205210visitCallResults (FullApplySite apply,
206211 llvm::function_ref<bool (SILValue, SILResultInfo)> visitor) {
207212 auto fnConv = apply.getSubstCalleeConv ();
208- SILValue pseudoResult = apply.getPseudoResult ();
209- if (auto *destructure = getCallMultiResult (pseudoResult)) {
213+ if (auto *destructure = getCallDestructure (apply)) {
210214 return visitCallMultiResults (destructure, fnConv, visitor);
211215 }
212- return visitor (pseudoResult , *fnConv.getDirectSILResults ().begin ());
216+ return visitor (apply. getResult () , *fnConv.getDirectSILResults ().begin ());
213217}
214218
215219// / Return true if the given value is either a "fake" tuple that represents all
216220// / of a call's results or an empty tuple of no results. This may return true
217221// / for either tuple_inst or a block argument.
218222static 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 ;
221225
222226 auto *bbArg = dyn_cast<SILPhiArgument>(value);
223227 if (!bbArg)
@@ -227,11 +231,18 @@ static bool isPseudoCallResult(SILValue value) {
227231 if (!term)
228232 return false ;
229233
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 ;
231239}
232240
233241// / Return true if this is a pseudo-return value.
234242static bool isPseudoReturnValue (SILValue value) {
243+ if (value->getFunction ()->getConventions ().getNumDirectSILResults () < 2 )
244+ return false ;
245+
235246 if (auto *tuple = dyn_cast<TupleInst>(value)) {
236247 Operand *singleUse = tuple->getSingleUse ();
237248 return singleUse && isa<ReturnInst>(singleUse->getUser ());
@@ -261,9 +272,12 @@ static SILValue getTupleStorageValue(Operand *operand) {
261272 if (!singleUse || !isa<ReturnInst>(singleUse->getUser ()))
262273 return tuple;
263274
275+ SILFunction *function = tuple->getFunction ();
276+ if (function->getConventions ().getNumDirectSILResults () < 2 )
277+ return tuple;
278+
264279 unsigned resultIdx = tuple->getElementIndex (operand);
265280
266- SILFunction *function = tuple->getFunction ();
267281 auto loweredFnConv = getLoweredFnConv (function);
268282 assert (loweredFnConv.getResults ().size () == tuple->getElements ().size ());
269283
@@ -279,11 +293,11 @@ static SILValue getTupleStorageValue(Operand *operand) {
279293
280294// / Return the value representing storage for a single return value.
281295// /
282- // / bb0(%loweredIndirectResult : $*T, ...)
296+ // / bb0(%loweredIndirectResult : $*T, ...) // function entry
283297// / return %oper
284298// /
285299// / For %oper, return %loweredIndirectResult
286- static SILValue getSingleReturnValue (Operand *operand) {
300+ static SILValue getSingleReturnAddress (Operand *operand) {
287301 assert (!isPseudoReturnValue (operand->get ()));
288302
289303 auto *function = operand->getParentFunction ();
@@ -612,7 +626,7 @@ void OpaqueValueVisitor::visitValue(SILValue value) {
612626
613627// Canonicalize returned values.
614628//
615- // Given:
629+ // Given $() -> @out (T, T) :
616630// %t = def : $(T, T)
617631// use %t : $(T, T)
618632// return %t : $(T, T)
@@ -807,7 +821,7 @@ static SILValue getProjectedUseValue(Operand *operand) {
807821
808822 // Return instructions can project into the return value.
809823 case SILInstructionKind::ReturnInst:
810- return getSingleReturnValue (operand);
824+ return getSingleReturnAddress (operand);
811825 }
812826 return SILValue ();
813827}
@@ -1420,9 +1434,7 @@ AddressMaterialization::materializeProjectionIntoUse(Operand *operand,
14201434 }
14211435 case SILInstructionKind::TupleInst: {
14221436 auto *tupleInst = cast<TupleInst>(user);
1423- // Function return values.
1424- if (tupleInst->hasOneUse ()
1425- && isa<ReturnInst>(tupleInst->use_begin ()->getUser ())) {
1437+ if (isPseudoReturnValue (tupleInst)) {
14261438 unsigned resultIdx = tupleInst->getElementIndex (operand);
14271439 assert (resultIdx < pass.loweredFnConv .getNumIndirectSILResults ());
14281440 // Cannot call getIndirectSILResults here because that API uses the
@@ -1830,9 +1842,8 @@ void ApplyRewriter::convertApplyWithIndirectResults() {
18301842 // Populate newCallArgs.
18311843 makeIndirectArgs (newCallArgs);
18321844
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);
18361847
18371848 switch (apply.getKind ()) {
18381849 case FullApplySiteKind::ApplyInst: {
@@ -2071,7 +2082,7 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
20712082 tryApply->getNormalBB (), tryApply->getErrorBB (),
20722083 tryApply->getApplyOptions (), tryApply->getSpecializationInfo ());
20732084
2074- auto *resultArg = cast<SILArgument>(apply.getPseudoResult ());
2085+ auto *resultArg = cast<SILArgument>(apply.getResult ());
20752086
20762087 auto replaceTermResult = [&](SILValue newResultVal) {
20772088 SILType resultTy = loweredCalleeConv.getSILResultType (typeCtx);
@@ -2091,8 +2102,6 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
20912102
20922103 // Handle a single opaque result value.
20932104 if (pass.valueStorageMap .contains (resultArg)) {
2094- assert (!resultArg->getType ().is <TupleType>());
2095-
20962105 // Storage was materialized by materializeIndirectResultAddress.
20972106 auto &origStorage = pass.valueStorageMap .getStorage (resultArg);
20982107 assert (origStorage.isRewritten );
@@ -2142,7 +2151,7 @@ void ApplyRewriter::rewriteTryApply(ArrayRef<SILValue> newCallArgs) {
21422151// // no uses of %d1, %d2
21432152//
21442153void ApplyRewriter::replaceDirectResults (DestructureTupleInst *oldDestructure) {
2145- SILValue newPseudoResult = apply.getPseudoResult ();
2154+ SILValue newPseudoResult = apply.getResult ();
21462155
21472156 DestructureTupleInst *newDestructure = nullptr ;
21482157 if (loweredCalleeConv.getNumDirectSILResults () > 1 ) {
@@ -2950,7 +2959,7 @@ static void rewriteIndirectApply(FullApplySite apply,
29502959 ApplyRewriter (apply, pass).convertApplyWithIndirectResults ();
29512960
29522961 if (!apply.getInstruction ()->isDeleted ()) {
2953- assert (!getCallMultiResult (apply. getPseudoResult () )
2962+ assert (!getCallDestructure (apply)
29542963 && " replaceDirectResults deletes the destructure" );
29552964 pass.deleter .forceDelete (apply.getInstruction ());
29562965 }
0 commit comments