Skip to content

Commit e317feb

Browse files
authored
Revert "Allow normal function results of @yield_once coroutines (#69843)"
This reverts commit aa5b505.
1 parent a1062d0 commit e317feb

File tree

71 files changed

+295
-571
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+295
-571
lines changed

docs/SIL.rst

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6067,14 +6067,6 @@ executing the ``begin_apply``) were being "called" by the ``yield``:
60676067
or move the value from that position before ending or aborting the
60686068
coroutine.
60696069

6070-
A coroutine optionally may produce normal results. These do not have
6071-
``@yields`` annotation in the result type tuple.
6072-
::
6073-
(%float, %token) = begin_apply %0() : $@yield_once () -> (@yields Float, Int)
6074-
6075-
Normal results of a coroutine are produced by the corresponding ``end_apply``
6076-
instruction.
6077-
60786070
A ``begin_apply`` must be uniquely either ended or aborted before
60796071
exiting the function or looping to an earlier portion of the function.
60806072

@@ -6104,9 +6096,9 @@ end_apply
61046096
`````````
61056097
::
61066098

6107-
sil-instruction ::= 'end_apply' sil-value 'as' sil-type
6099+
sil-instruction ::= 'end_apply' sil-value
61086100

6109-
end_apply %token as $()
6101+
end_apply %token
61106102

61116103
Ends the given coroutine activation, which is currently suspended at
61126104
a ``yield`` instruction. Transfers control to the coroutine and takes
@@ -6116,8 +6108,8 @@ when the coroutine reaches a ``return`` instruction.
61166108
The operand must always be the token result of a ``begin_apply``
61176109
instruction, which is why it need not specify a type.
61186110

6119-
The result of ``end_apply`` is the normal result of the coroutine function (the
6120-
operand of the ``return`` instruction)."
6111+
``end_apply`` currently has no instruction results. If coroutines were
6112+
allowed to have normal results, they would be producted by ``end_apply``.
61216113

61226114
When throwing coroutines are supported, there will need to be a
61236115
``try_end_apply`` instruction.

include/swift/AST/Types.h

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4726,27 +4726,24 @@ class SILFunctionType final
47264726
using Representation = SILExtInfoBuilder::Representation;
47274727

47284728
private:
4729-
unsigned NumParameters = 0;
4729+
unsigned NumParameters;
47304730

4731-
// These are *normal* results
4732-
unsigned NumAnyResults = 0; // Not including the ErrorResult.
4733-
unsigned NumAnyIndirectFormalResults = 0; // Subset of NumAnyResults.
4734-
unsigned NumPackResults = 0; // Subset of NumAnyIndirectFormalResults.
4735-
// These are *yield* results
4736-
unsigned NumAnyYieldResults = 0; // Not including the ErrorResult.
4737-
unsigned NumAnyIndirectFormalYieldResults = 0; // Subset of NumAnyYieldResults.
4738-
unsigned NumPackYieldResults = 0; // Subset of NumAnyIndirectFormalYieldResults.
4731+
// These are *normal* results if this is not a coroutine and *yield* results
4732+
// otherwise.
4733+
unsigned NumAnyResults; // Not including the ErrorResult.
4734+
unsigned NumAnyIndirectFormalResults; // Subset of NumAnyResults.
4735+
unsigned NumPackResults; // Subset of NumAnyIndirectFormalResults.
47394736

47404737
// [NOTE: SILFunctionType-layout]
47414738
// The layout of a SILFunctionType in memory is:
47424739
// SILFunctionType
47434740
// SILParameterInfo[NumParameters]
4744-
// SILResultInfo[NumAnyResults]
4741+
// SILResultInfo[isCoroutine() ? 0 : NumAnyResults]
47454742
// SILResultInfo? // if hasErrorResult()
4746-
// SILYieldInfo[NumAnyYieldResults]
4743+
// SILYieldInfo[isCoroutine() ? NumAnyResults : 0]
47474744
// SubstitutionMap[HasPatternSubs + HasInvocationSubs]
4748-
// CanType? // if NumAnyResults > 1, formal result cache
4749-
// CanType? // if NumAnyResults > 1, all result cache
4745+
// CanType? // if !isCoro && NumAnyResults > 1, formal result cache
4746+
// CanType? // if !isCoro && NumAnyResults > 1, all result cache
47504747

47514748
CanGenericSignature InvocationGenericSig;
47524749
ProtocolConformanceRef WitnessMethodConformance;
@@ -4785,7 +4782,7 @@ class SILFunctionType final
47854782

47864783
/// Do we have slots for caches of the normal-result tuple type?
47874784
bool hasResultCache() const {
4788-
return NumAnyResults > 1;
4785+
return NumAnyResults > 1 && !isCoroutine();
47894786
}
47904787

47914788
CanType &getMutableFormalResultsCache() const {
@@ -4873,14 +4870,14 @@ class SILFunctionType final
48734870
ArrayRef<SILYieldInfo> getYields() const {
48744871
return const_cast<SILFunctionType *>(this)->getMutableYields();
48754872
}
4876-
unsigned getNumYields() const { return NumAnyYieldResults; }
4873+
unsigned getNumYields() const { return isCoroutine() ? NumAnyResults : 0; }
48774874

48784875
/// Return the array of all result information. This may contain inter-mingled
48794876
/// direct and indirect results.
48804877
ArrayRef<SILResultInfo> getResults() const {
48814878
return const_cast<SILFunctionType *>(this)->getMutableResults();
48824879
}
4883-
unsigned getNumResults() const { return NumAnyResults; }
4880+
unsigned getNumResults() const { return isCoroutine() ? 0 : NumAnyResults; }
48844881

48854882
ArrayRef<SILResultInfo> getResultsWithError() const {
48864883
return const_cast<SILFunctionType *>(this)->getMutableResultsWithError();
@@ -4917,17 +4914,17 @@ class SILFunctionType final
49174914
// indirect property, not the SIL indirect property, should be consulted to
49184915
// determine whether function reabstraction is necessary.
49194916
unsigned getNumIndirectFormalResults() const {
4920-
return NumAnyIndirectFormalResults;
4917+
return isCoroutine() ? 0 : NumAnyIndirectFormalResults;
49214918
}
49224919
/// Does this function have any formally indirect results?
49234920
bool hasIndirectFormalResults() const {
49244921
return getNumIndirectFormalResults() != 0;
49254922
}
49264923
unsigned getNumDirectFormalResults() const {
4927-
return NumAnyResults - NumAnyIndirectFormalResults;
4924+
return isCoroutine() ? 0 : NumAnyResults - NumAnyIndirectFormalResults;
49284925
}
49294926
unsigned getNumPackResults() const {
4930-
return NumPackResults;
4927+
return isCoroutine() ? 0 : NumPackResults;
49314928
}
49324929
bool hasIndirectErrorResult() const {
49334930
return hasErrorResult() && getErrorResult().isFormalIndirect();
@@ -4985,17 +4982,17 @@ class SILFunctionType final
49854982
TypeExpansionContext expansion);
49864983

49874984
unsigned getNumIndirectFormalYields() const {
4988-
return NumAnyIndirectFormalYieldResults;
4985+
return isCoroutine() ? NumAnyIndirectFormalResults : 0;
49894986
}
49904987
/// Does this function have any formally indirect yields?
49914988
bool hasIndirectFormalYields() const {
49924989
return getNumIndirectFormalYields() != 0;
49934990
}
49944991
unsigned getNumDirectFormalYields() const {
4995-
return NumAnyYieldResults - NumAnyIndirectFormalYieldResults;
4992+
return isCoroutine() ? NumAnyResults - NumAnyIndirectFormalResults : 0;
49964993
}
49974994
unsigned getNumPackYields() const {
4998-
return NumPackYieldResults;
4995+
return isCoroutine() ? NumPackResults : 0;
49994996
}
50004997

50014998
struct IndirectFormalYieldFilter {

include/swift/SIL/SILBuilder.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,11 +576,11 @@ class SILBuilder {
576576
beginApply));
577577
}
578578

579-
EndApplyInst *createEndApply(SILLocation loc, SILValue beginApply, SILType ResultType) {
579+
EndApplyInst *createEndApply(SILLocation loc, SILValue beginApply) {
580580
return insert(new (getModule()) EndApplyInst(getSILDebugLocation(loc),
581-
beginApply, ResultType));
581+
beginApply));
582582
}
583-
583+
584584
BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
585585
SubstitutionMap Subs,
586586
ArrayRef<SILValue> Args) {

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,8 +1076,7 @@ SILCloner<ImplClass>::visitEndApplyInst(EndApplyInst *Inst) {
10761076
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
10771077
recordClonedInstruction(
10781078
Inst, getBuilder().createEndApply(getOpLocation(Inst->getLoc()),
1079-
getOpValue(Inst->getOperand()),
1080-
getOpType(Inst->getType())));
1079+
getOpValue(Inst->getOperand())));
10811080
}
10821081

10831082
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,12 +3200,11 @@ class AbortApplyInst
32003200
/// normally.
32013201
class EndApplyInst
32023202
: public UnaryInstructionBase<SILInstructionKind::EndApplyInst,
3203-
SingleValueInstruction> {
3203+
NonValueInstruction> {
32043204
friend SILBuilder;
32053205

3206-
EndApplyInst(SILDebugLocation debugLoc, SILValue beginApplyToken,
3207-
SILType Ty)
3208-
: UnaryInstructionBase(debugLoc, beginApplyToken, Ty) {
3206+
EndApplyInst(SILDebugLocation debugLoc, SILValue beginApplyToken)
3207+
: UnaryInstructionBase(debugLoc, beginApplyToken) {
32093208
assert(isaResultOf<BeginApplyInst>(beginApplyToken) &&
32103209
isaResultOf<BeginApplyInst>(beginApplyToken)->isBeginApplyToken());
32113210
}

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,6 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
568568
SingleValueInstruction, MayHaveSideEffects, MayRelease)
569569
SINGLE_VALUE_INST(PartialApplyInst, partial_apply,
570570
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
571-
SINGLE_VALUE_INST(EndApplyInst, end_apply,
572-
SILInstruction, MayHaveSideEffects, MayRelease)
573571

574572
// Metatypes
575573
SINGLE_VALUE_INST(MetatypeInst, metatype,
@@ -873,6 +871,8 @@ NON_VALUE_INST(UncheckedRefCastAddrInst, unchecked_ref_cast_addr,
873871
SILInstruction, MayHaveSideEffects, DoesNotRelease)
874872
NON_VALUE_INST(AllocGlobalInst, alloc_global,
875873
SILInstruction, MayHaveSideEffects, DoesNotRelease)
874+
NON_VALUE_INST(EndApplyInst, end_apply,
875+
SILInstruction, MayHaveSideEffects, MayRelease)
876876
NON_VALUE_INST(AbortApplyInst, abort_apply,
877877
SILInstruction, MayHaveSideEffects, MayRelease)
878878
NON_VALUE_INST(PackElementSetInst, pack_element_set,

lib/AST/ASTContext.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4611,29 +4611,29 @@ SILFunctionType::SILFunctionType(
46114611
!ext.getLifetimeDependenceInfo().empty();
46124612
Bits.SILFunctionType.CoroutineKind = unsigned(coroutineKind);
46134613
NumParameters = params.size();
4614-
assert((coroutineKind == SILCoroutineKind::None && yields.empty()) ||
4615-
coroutineKind != SILCoroutineKind::None);
4616-
4617-
NumAnyResults = normalResults.size();
4618-
NumAnyIndirectFormalResults = 0;
4619-
NumPackResults = 0;
4620-
for (auto &resultInfo : normalResults) {
4621-
if (resultInfo.isFormalIndirect())
4622-
NumAnyIndirectFormalResults++;
4623-
if (resultInfo.isPack())
4624-
NumPackResults++;
4625-
}
4626-
memcpy(getMutableResults().data(), normalResults.data(),
4627-
normalResults.size() * sizeof(SILResultInfo));
4628-
if (coroutineKind != SILCoroutineKind::None) {
4629-
NumAnyYieldResults = yields.size();
4630-
NumAnyIndirectFormalYieldResults = 0;
4614+
if (coroutineKind == SILCoroutineKind::None) {
4615+
assert(yields.empty());
4616+
NumAnyResults = normalResults.size();
4617+
NumAnyIndirectFormalResults = 0;
4618+
NumPackResults = 0;
4619+
for (auto &resultInfo : normalResults) {
4620+
if (resultInfo.isFormalIndirect())
4621+
NumAnyIndirectFormalResults++;
4622+
if (resultInfo.isPack())
4623+
NumPackResults++;
4624+
}
4625+
memcpy(getMutableResults().data(), normalResults.data(),
4626+
normalResults.size() * sizeof(SILResultInfo));
4627+
} else {
4628+
assert(normalResults.empty());
4629+
NumAnyResults = yields.size();
4630+
NumAnyIndirectFormalResults = 0;
46314631
NumPackResults = 0;
46324632
for (auto &yieldInfo : yields) {
46334633
if (yieldInfo.isFormalIndirect())
4634-
NumAnyIndirectFormalYieldResults++;
4634+
NumAnyIndirectFormalResults++;
46354635
if (yieldInfo.isPack())
4636-
NumPackYieldResults++;
4636+
NumPackResults++;
46374637
}
46384638
memcpy(getMutableYields().data(), yields.data(),
46394639
yields.size() * sizeof(SILYieldInfo));
@@ -4805,6 +4805,7 @@ CanSILFunctionType SILFunctionType::get(
48054805
llvm::Optional<SILResultInfo> errorResult, SubstitutionMap patternSubs,
48064806
SubstitutionMap invocationSubs, const ASTContext &ctx,
48074807
ProtocolConformanceRef witnessMethodConformance) {
4808+
assert(coroutineKind == SILCoroutineKind::None || normalResults.empty());
48084809
assert(coroutineKind != SILCoroutineKind::None || yields.empty());
48094810
assert(!ext.isPseudogeneric() || genericSig ||
48104811
coroutineKind != SILCoroutineKind::None);

lib/IRGen/GenCall.cpp

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -656,34 +656,24 @@ namespace {
656656
}
657657

658658
void SignatureExpansion::expandCoroutineResult(bool forContinuation) {
659+
assert(FnType->getNumResults() == 0 &&
660+
"having both normal and yield results is currently unsupported");
661+
659662
// The return type may be different for the ramp function vs. the
660663
// continuations.
661664
if (forContinuation) {
662665
switch (FnType->getCoroutineKind()) {
663666
case SILCoroutineKind::None:
664667
llvm_unreachable("should have been filtered out before here");
665668

666-
// Yield-once coroutines may optionaly return a value from the continuation.
667-
case SILCoroutineKind::YieldOnce: {
668-
auto fnConv = getSILFuncConventions();
669-
670-
assert(fnConv.getNumIndirectSILResults() == 0);
671-
// Ensure that no parameters were added before to correctly record their ABI
672-
// details.
673-
assert(ParamIRTypes.empty());
674-
675-
// Expand the direct result.
676-
const TypeInfo *directResultTypeInfo;
677-
std::tie(ResultIRType, directResultTypeInfo) = expandDirectResult();
678-
669+
// Yield-once coroutines just return void from the continuation.
670+
case SILCoroutineKind::YieldOnce:
671+
ResultIRType = IGM.VoidTy;
679672
return;
680-
}
681673

682674
// Yield-many coroutines yield the same types from the continuation
683675
// as they do from the ramp function.
684676
case SILCoroutineKind::YieldMany:
685-
assert(FnType->getNumResults() == 0 &&
686-
"having both normal and yield results is currently unsupported");
687677
break;
688678
}
689679
}
@@ -5813,53 +5803,6 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
58135803
emitAsyncReturn(IGF, asyncLayout, fnType, nativeResults);
58145804
}
58155805

5816-
void irgen::emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
5817-
SILType funcResultType, SILType returnResultType) {
5818-
auto &Builder = IGF.Builder;
5819-
auto &IGM = IGF.IGM;
5820-
5821-
// Create coroutine exit block and branch to it.
5822-
auto coroEndBB = IGF.createBasicBlock("coro.end.normal");
5823-
IGF.setCoroutineExitBlock(coroEndBB);
5824-
Builder.CreateBr(coroEndBB);
5825-
5826-
// Emit the block.
5827-
Builder.emitBlock(coroEndBB);
5828-
auto handle = IGF.getCoroutineHandle();
5829-
5830-
llvm::Value *resultToken = nullptr;
5831-
if (result.empty()) {
5832-
assert(IGM.getTypeInfo(returnResultType)
5833-
.nativeReturnValueSchema(IGM)
5834-
.empty() &&
5835-
"Empty explosion must match the native calling convention");
5836-
// No results: just use none token
5837-
resultToken = llvm::ConstantTokenNone::get(Builder.getContext());
5838-
} else {
5839-
// Capture results via `coro_end_results` intrinsic
5840-
result = IGF.coerceValueTo(returnResultType, result, funcResultType);
5841-
auto &nativeSchema =
5842-
IGM.getTypeInfo(funcResultType).nativeReturnValueSchema(IGM);
5843-
assert(!nativeSchema.requiresIndirect());
5844-
5845-
Explosion native = nativeSchema.mapIntoNative(IGM, IGF, result,
5846-
funcResultType,
5847-
false /* isOutlined */);
5848-
SmallVector<llvm::Value *, 1> args;
5849-
for (unsigned i = 0, e = native.size(); i != e; ++i)
5850-
args.push_back(native.claimNext());
5851-
5852-
resultToken =
5853-
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_results, args);
5854-
}
5855-
5856-
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end,
5857-
{handle,
5858-
/*is unwind*/ Builder.getFalse(),
5859-
resultToken});
5860-
Builder.CreateUnreachable();
5861-
}
5862-
58635806
FunctionPointer
58645807
IRGenFunction::getFunctionPointerForResumeIntrinsic(llvm::Value *resume) {
58655808
auto *fnTy = llvm::FunctionType::get(

lib/IRGen/GenCall.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,6 @@ namespace irgen {
266266
SILType funcResultTypeInContext,
267267
CanSILFunctionType fnType, Explosion &result,
268268
Explosion &error);
269-
void emitYieldOnceCoroutineResult(IRGenFunction &IGF, Explosion &result,
270-
SILType funcResultType, SILType returnResultType);
271269

272270
Address emitAutoDiffCreateLinearMapContextWithType(
273271
IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype);

lib/IRGen/IRGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ void IRGenFunction::emitAwaitAsyncContinuation(
709709
// because the continuation result is not available yet. When the
710710
// continuation is later resumed, the task will get scheduled
711711
// starting from the suspension point.
712-
emitCoroutineOrAsyncExit(false);
712+
emitCoroutineOrAsyncExit();
713713
}
714714

715715
Builder.emitBlock(contBB);

lib/IRGen/IRGenFunction.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,6 @@ class IRGenFunction {
155155
CoroutineHandle = handle;
156156
}
157157

158-
llvm::BasicBlock *getCoroutineExitBlock() const {
159-
return CoroutineExitBlock;
160-
}
161-
162-
void setCoroutineExitBlock(llvm::BasicBlock *block) {
163-
assert(CoroutineExitBlock == nullptr && "already set exit BB");
164-
assert(block != nullptr && "setting a null exit BB");
165-
CoroutineExitBlock = block;
166-
}
167-
168158
llvm::Value *getAsyncTask();
169159
llvm::Value *getAsyncContext();
170160
void storeCurrentAsyncContext(llvm::Value *context);
@@ -246,7 +236,7 @@ class IRGenFunction {
246236
bool callsAnyAlwaysInlineThunksWithForeignExceptionTraps = false;
247237

248238
public:
249-
void emitCoroutineOrAsyncExit(bool isUnwind);
239+
void emitCoroutineOrAsyncExit();
250240

251241
//--- Helper methods -----------------------------------------------------------
252242
public:

0 commit comments

Comments
 (0)