Skip to content

Commit 72ccbad

Browse files
asavonicasl
authored andcommitted
Partial apply for coroutines
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). The odd type conversions in the patch are related to this issue, and these should be checked carefully. Perhaps it is better to enable substitutions for coroutine functions instead (at least for some cases). 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.
1 parent f1c2d90 commit 72ccbad

File tree

5 files changed

+2232
-21
lines changed

5 files changed

+2232
-21
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5868,13 +5868,13 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
58685868
// Capture results via result token
58695869
resultToken =
58705870
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_results, coroResults);
5871-
5872-
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end,
5873-
{handle,
5874-
/*is unwind*/ Builder.getFalse(),
5875-
resultToken});
5876-
Builder.CreateUnreachable();
58775871
}
5872+
5873+
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end,
5874+
{handle,
5875+
/*is unwind*/ Builder.getFalse(),
5876+
resultToken});
5877+
Builder.CreateUnreachable();
58785878
} else {
58795879
if (coroResults.empty()) {
58805880
// No results, we do not need to change anything around existing coro.end

lib/IRGen/GenDecl.cpp

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

6261+
GenericContextScope scope(*this, fnType->getInvocationGenericSignature());
62616262
auto signature = Signature::forCoroutineContinuation(*this, fnType);
62626263
LinkInfo link = LinkInfo::get(*this, entity, NotForDefinition);
62636264
entry = createFunction(*this, link, signature);

0 commit comments

Comments
 (0)