Skip to content

Commit 7a97858

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

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
@@ -4729,27 +4729,24 @@ class SILFunctionType final
47294729
using Representation = SILExtInfoBuilder::Representation;
47304730

47314731
private:
4732-
unsigned NumParameters = 0;
4732+
unsigned NumParameters;
47334733

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

47434740
// [NOTE: SILFunctionType-layout]
47444741
// The layout of a SILFunctionType in memory is:
47454742
// SILFunctionType
47464743
// SILParameterInfo[NumParameters]
4747-
// SILResultInfo[NumAnyResults]
4744+
// SILResultInfo[isCoroutine() ? 0 : NumAnyResults]
47484745
// SILResultInfo? // if hasErrorResult()
4749-
// SILYieldInfo[NumAnyYieldResults]
4746+
// SILYieldInfo[isCoroutine() ? NumAnyResults : 0]
47504747
// SubstitutionMap[HasPatternSubs + HasInvocationSubs]
4751-
// CanType? // if NumAnyResults > 1, formal result cache
4752-
// CanType? // if NumAnyResults > 1, all result cache
4748+
// CanType? // if !isCoro && NumAnyResults > 1, formal result cache
4749+
// CanType? // if !isCoro && NumAnyResults > 1, all result cache
47534750

47544751
CanGenericSignature InvocationGenericSig;
47554752
ProtocolConformanceRef WitnessMethodConformance;
@@ -4788,7 +4785,7 @@ class SILFunctionType final
47884785

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

47944791
CanType &getMutableFormalResultsCache() const {
@@ -4876,14 +4873,14 @@ class SILFunctionType final
48764873
ArrayRef<SILYieldInfo> getYields() const {
48774874
return const_cast<SILFunctionType *>(this)->getMutableYields();
48784875
}
4879-
unsigned getNumYields() const { return NumAnyYieldResults; }
4876+
unsigned getNumYields() const { return isCoroutine() ? NumAnyResults : 0; }
48804877

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

48884885
ArrayRef<SILResultInfo> getResultsWithError() const {
48894886
return const_cast<SILFunctionType *>(this)->getMutableResultsWithError();
@@ -4920,17 +4917,17 @@ class SILFunctionType final
49204917
// indirect property, not the SIL indirect property, should be consulted to
49214918
// determine whether function reabstraction is necessary.
49224919
unsigned getNumIndirectFormalResults() const {
4923-
return NumAnyIndirectFormalResults;
4920+
return isCoroutine() ? 0 : NumAnyIndirectFormalResults;
49244921
}
49254922
/// Does this function have any formally indirect results?
49264923
bool hasIndirectFormalResults() const {
49274924
return getNumIndirectFormalResults() != 0;
49284925
}
49294926
unsigned getNumDirectFormalResults() const {
4930-
return NumAnyResults - NumAnyIndirectFormalResults;
4927+
return isCoroutine() ? 0 : NumAnyResults - NumAnyIndirectFormalResults;
49314928
}
49324929
unsigned getNumPackResults() const {
4933-
return NumPackResults;
4930+
return isCoroutine() ? 0 : NumPackResults;
49344931
}
49354932
bool hasIndirectErrorResult() const {
49364933
return hasErrorResult() && getErrorResult().isFormalIndirect();
@@ -4988,17 +4985,17 @@ class SILFunctionType final
49884985
TypeExpansionContext expansion);
49894986

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

50045001
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)