Skip to content

Commit e6de827

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 35cda47 commit e6de827

File tree

6 files changed

+2235
-22
lines changed

6 files changed

+2235
-22
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5860,13 +5860,13 @@ void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
58605860
// Capture results via result token
58615861
resultToken =
58625862
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_results, coroResults);
5863-
5864-
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end,
5865-
{handle,
5866-
/*is unwind*/ Builder.getFalse(),
5867-
resultToken});
5868-
Builder.CreateUnreachable();
58695863
}
5864+
5865+
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end,
5866+
{handle,
5867+
/*is unwind*/ Builder.getFalse(),
5868+
resultToken});
5869+
Builder.CreateUnreachable();
58705870
} else {
58715871
if (coroResults.empty()) {
58725872
// 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
@@ -6257,6 +6257,7 @@ IRGenModule::getAddrOfContinuationPrototype(CanSILFunctionType fnType) {
62576257
llvm::Function *&entry = GlobalFuncs[entity];
62586258
if (entry) return entry;
62596259

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

0 commit comments

Comments
 (0)