Skip to content

Commit a3d6079

Browse files
committed
[CoroutineAccessors] Fix begin_apply for protos.
When the CoroutineAccessors feature is enabled, `begin_apply` instructions produce an additional result representing the allocation done by the callee. Fix a couple of cases where this additional result was not being handled.
1 parent df20d0f commit a3d6079

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6000,7 +6000,8 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
60006000
return normalBB->createPhiArgument(resultType, OwnershipKind::Owned);
60016001
}
60026002

6003-
std::pair<MultipleValueInstructionResult *, CleanupHandle>
6003+
std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
6004+
CleanupHandle>
60046005
SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
60056006
SILType substFnType,
60066007
SubstitutionMap subs,
@@ -6021,19 +6022,29 @@ SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
60216022

60226023
auto *token = beginApply->getTokenResult();
60236024

6025+
CleanupHandle deallocCleanup;
6026+
auto *allocation = beginApply->getCalleeAllocationResult();
6027+
if (allocation) {
6028+
deallocCleanup = enterDeallocStackCleanup(allocation);
6029+
}
6030+
60246031
Cleanups.pushCleanup<EndCoroutineApply>(token);
60256032
auto abortCleanup = Cleanups.getTopCleanup();
60266033

6027-
return { token, abortCleanup };
6034+
return {token, abortCleanup, allocation, deallocCleanup};
60286035
}
60296036

6030-
void SILGenFunction::emitEndApplyWithRethrow(SILLocation loc,
6031-
MultipleValueInstructionResult *token) {
6037+
void SILGenFunction::emitEndApplyWithRethrow(
6038+
SILLocation loc, MultipleValueInstructionResult *token,
6039+
SILValue allocation) {
60326040
// TODO: adjust this to handle results of TryBeginApplyInst.
60336041
assert(token->isBeginApplyToken());
60346042

60356043
B.createEndApply(loc, token,
60366044
SILType::getEmptyTupleType(getASTContext()));
6045+
if (allocation) {
6046+
B.createDeallocStack(loc, allocation);
6047+
}
60376048
}
60386049

60396050
void SILGenFunction::emitYield(SILLocation loc,

lib/SILGen/SILGenFunction.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,12 +2185,14 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
21852185
SubstitutionMap subs,
21862186
ArrayRef<SILValue> args);
21872187

2188-
std::pair<MultipleValueInstructionResult *, CleanupHandle>
2188+
std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
2189+
CleanupHandle>
21892190
emitBeginApplyWithRethrow(SILLocation loc, SILValue fn, SILType substFnType,
21902191
SubstitutionMap subs, ArrayRef<SILValue> args,
21912192
SmallVectorImpl<SILValue> &yields);
21922193
void emitEndApplyWithRethrow(SILLocation loc,
2193-
MultipleValueInstructionResult *token);
2194+
MultipleValueInstructionResult *token,
2195+
SILValue allocation);
21942196

21952197
ManagedValue emitExtractFunctionIsolation(SILLocation loc,
21962198
ArgumentSource &&fnValue);

lib/SILGen/SILGenPoly.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6824,10 +6824,13 @@ SILGenFunction::emitVTableThunk(SILDeclRef base,
68246824
case SILCoroutineKind::YieldOnce:
68256825
case SILCoroutineKind::YieldOnce2: {
68266826
SmallVector<SILValue, 4> derivedYields;
6827-
auto tokenAndCleanup =
6828-
emitBeginApplyWithRethrow(loc, derivedRef,
6829-
SILType::getPrimitiveObjectType(derivedFTy),
6830-
subs, args, derivedYields);
6827+
auto tokenAndCleanups = emitBeginApplyWithRethrow(
6828+
loc, derivedRef, SILType::getPrimitiveObjectType(derivedFTy), subs,
6829+
args, derivedYields);
6830+
auto token = std::get<0>(tokenAndCleanups);
6831+
auto abortCleanup = std::get<1>(tokenAndCleanups);
6832+
auto allocation = std::get<2>(tokenAndCleanups);
6833+
auto deallocCleanup = std::get<3>(tokenAndCleanups);
68316834
auto overrideSubs = SubstitutionMap::getOverrideSubstitutions(
68326835
base.getDecl(), derived.getDecl()).subst(subs);
68336836

@@ -6837,10 +6840,13 @@ SILGenFunction::emitVTableThunk(SILDeclRef base,
68376840
translateYields(*this, loc, derivedYields, derivedYieldInfo, baseYieldInfo);
68386841

68396842
// Kill the abort cleanup without emitting it.
6840-
Cleanups.setCleanupState(tokenAndCleanup.second, CleanupState::Dead);
6843+
Cleanups.setCleanupState(abortCleanup, CleanupState::Dead);
6844+
if (allocation) {
6845+
Cleanups.setCleanupState(deallocCleanup, CleanupState::Dead);
6846+
}
68416847

68426848
// End the inner coroutine normally.
6843-
emitEndApplyWithRethrow(loc, tokenAndCleanup.first);
6849+
emitEndApplyWithRethrow(loc, token, allocation);
68446850

68456851
result = B.createTuple(loc, {});
68466852
break;
@@ -7213,9 +7219,12 @@ void SILGenFunction::emitProtocolWitness(
72137219
case SILCoroutineKind::YieldOnce:
72147220
case SILCoroutineKind::YieldOnce2: {
72157221
SmallVector<SILValue, 4> witnessYields;
7216-
auto tokenAndCleanup =
7217-
emitBeginApplyWithRethrow(loc, witnessFnRef, witnessSILTy, witnessSubs,
7218-
args, witnessYields);
7222+
auto tokenAndCleanups = emitBeginApplyWithRethrow(
7223+
loc, witnessFnRef, witnessSILTy, witnessSubs, args, witnessYields);
7224+
auto token = std::get<0>(tokenAndCleanups);
7225+
auto abortCleanup = std::get<1>(tokenAndCleanups);
7226+
auto allocation = std::get<2>(tokenAndCleanups);
7227+
auto deallocCleanup = std::get<3>(tokenAndCleanups);
72197228

72207229
YieldInfo witnessYieldInfo(SGM, witness, witnessFTy, witnessSubs);
72217230
YieldInfo reqtYieldInfo(SGM, requirement, thunkTy,
@@ -7224,10 +7233,13 @@ void SILGenFunction::emitProtocolWitness(
72247233
translateYields(*this, loc, witnessYields, witnessYieldInfo, reqtYieldInfo);
72257234

72267235
// Kill the abort cleanup without emitting it.
7227-
Cleanups.setCleanupState(tokenAndCleanup.second, CleanupState::Dead);
7236+
Cleanups.setCleanupState(abortCleanup, CleanupState::Dead);
7237+
if (allocation) {
7238+
Cleanups.setCleanupState(deallocCleanup, CleanupState::Dead);
7239+
}
72287240

72297241
// End the inner coroutine normally.
7230-
emitEndApplyWithRethrow(loc, tokenAndCleanup.first);
7242+
emitEndApplyWithRethrow(loc, token, allocation);
72317243

72327244
reqtResultValue = B.createTuple(loc, {});
72337245
break;

0 commit comments

Comments
 (0)