Skip to content

Commit 5aa9d3e

Browse files
asavonicaslaschwaighofer
authored
Add partial_apply support for coroutines (#71653)
The patch adds lowering of partial_apply instructions for coroutines. This pattern seems to trigger a lot of type mismatch errors in IRGen, because coroutine functions are not substituted in the same way as regular functions (see the patch 07f03bd "Use pattern substitutions to consistently abstract yields" for more details). Other than that, lowering of partial_apply for coroutines is straightforward: we generate another coroutine that captures arguments passed to the partial_apply instructions. It calls the original coroutine for yields (first return) and yields the resulting values. Then it calls the original function's continuation for return or unwind, and forwards them to the caller as well. After IRGen, LLVM's Coroutine pass transforms the generated coroutine (along with all other coroutines) and eliminates llvm.coro.* intrinsics. LIT tests check LLVM IR after this transformation. Co-authored-by: Anton Korobeynikov <[email protected]> Co-authored-by: Arnold Schwaighofer <[email protected]>
1 parent 58bd3c4 commit 5aa9d3e

File tree

10 files changed

+2994
-18
lines changed

10 files changed

+2994
-18
lines changed

docs/SIL.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ the ``@yields`` attribute. A yielded value may have a convention attribute,
804804
taken from the set of parameter attributes and interpreted as if the yield
805805
site were calling back to the calling function.
806806

807-
Currently, a coroutine may not have normal results.
807+
In addition to yielded values a coroutine could also have normal results.
808808

809809
Coroutine functions may be used in many of the same ways as normal
810810
function values. However, they cannot be called with the standard
@@ -6330,6 +6330,16 @@ callee function (and thus said signature). Instead:
63306330
``@inout_aliasable`` parameter convention is used when a ``@noescape``
63316331
closure captures an ``inout`` argument.
63326332

6333+
**Coroutines** ``partial_apply`` could be used to create closures over
6334+
coroutines. Overall, the ``partial_apply`` of a coroutine is straightforward: it
6335+
is another coroutine that captures arguments passed to the ``partial_apply``
6336+
instruction. This closure applies the original coroutine (similar to the
6337+
``begin_apply`` instruction) for yields (suspend) and yields the resulting
6338+
values. Then it calls the original coroutine continuation for return or unwind,
6339+
and forwards the results (if any) to the caller as well. Currently only the
6340+
autodiff transformation produces ``partial_apply`` for coroutines while
6341+
differentiating modify accessors.
6342+
63336343
**NOTE:** If the callee is generic, all of its generic parameters must be bound
63346344
by the given substitution list. The arguments are given with these generic
63356345
substitutions applied, and the resulting closure is of concrete function type

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6163,6 +6163,7 @@ IRGenModule::getAddrOfContinuationPrototype(CanSILFunctionType fnType) {
61636163
llvm::Function *&entry = GlobalFuncs[entity];
61646164
if (entry) return entry;
61656165

6166+
GenericContextScope scope(*this, fnType->getInvocationGenericSignature());
61666167
auto signature = Signature::forCoroutineContinuation(*this, fnType);
61676168
LinkInfo link = LinkInfo::get(*this, entity, NotForDefinition);
61686169
entry = createFunction(*this, link, signature);

0 commit comments

Comments
 (0)