Skip to content

Commit 05711ff

Browse files
aslasavonic
authored andcommitted
Allow normal function results of @yield_once coroutines
1 parent f3189fb commit 05711ff

File tree

72 files changed

+668
-279
lines changed

Some content is hidden

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

72 files changed

+668
-279
lines changed

docs/SIL.rst

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

6063+
A coroutine optionally may produce normal results. These do not have
6064+
``@yields`` annotation in the result type tuple.
6065+
::
6066+
(%float, %token) = begin_apply %0() : $@yield_once () -> (@yields Float, Int)
6067+
6068+
Normal results of a coroutine are produced by the corresponding ``end_apply``
6069+
instruction.
6070+
60636071
A ``begin_apply`` must be uniquely either ended or aborted before
60646072
exiting the function or looping to an earlier portion of the function.
60656073

@@ -6089,9 +6097,9 @@ end_apply
60896097
`````````
60906098
::
60916099

6092-
sil-instruction ::= 'end_apply' sil-value
6100+
sil-instruction ::= 'end_apply' sil-value 'as' sil-type
60936101

6094-
end_apply %token
6102+
end_apply %token as $()
60956103

60966104
Ends the given coroutine activation, which is currently suspended at
60976105
a ``yield`` instruction. Transfers control to the coroutine and takes
@@ -6101,8 +6109,8 @@ when the coroutine reaches a ``return`` instruction.
61016109
The operand must always be the token result of a ``begin_apply``
61026110
instruction, which is why it need not specify a type.
61036111

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

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

include/swift/AST/Types.h

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

47324732
private:
4733-
unsigned NumParameters;
4733+
unsigned NumParameters = 0;
47344734

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

47414744
// [NOTE: SILFunctionType-layout]
47424745
// The layout of a SILFunctionType in memory is:
47434746
// SILFunctionType
47444747
// SILParameterInfo[NumParameters]
4745-
// SILResultInfo[isCoroutine() ? 0 : NumAnyResults]
4748+
// SILResultInfo[NumAnyResults]
47464749
// SILResultInfo? // if hasErrorResult()
4747-
// SILYieldInfo[isCoroutine() ? NumAnyResults : 0]
4750+
// SILYieldInfo[NumAnyYieldResults]
47484751
// SubstitutionMap[HasPatternSubs + HasInvocationSubs]
4749-
// CanType? // if !isCoro && NumAnyResults > 1, formal result cache
4750-
// CanType? // if !isCoro && NumAnyResults > 1, all result cache
4752+
// CanType? // if NumAnyResults > 1, formal result cache
4753+
// CanType? // if NumAnyResults > 1, all result cache
47514754

47524755
CanGenericSignature InvocationGenericSig;
47534756
ProtocolConformanceRef WitnessMethodConformance;
@@ -4786,7 +4789,7 @@ class SILFunctionType final
47864789

47874790
/// Do we have slots for caches of the normal-result tuple type?
47884791
bool hasResultCache() const {
4789-
return NumAnyResults > 1 && !isCoroutine();
4792+
return NumAnyResults > 1;
47904793
}
47914794

47924795
CanType &getMutableFormalResultsCache() const {
@@ -4874,14 +4877,14 @@ class SILFunctionType final
48744877
ArrayRef<SILYieldInfo> getYields() const {
48754878
return const_cast<SILFunctionType *>(this)->getMutableYields();
48764879
}
4877-
unsigned getNumYields() const { return isCoroutine() ? NumAnyResults : 0; }
4880+
unsigned getNumYields() const { return NumAnyYieldResults; }
48784881

48794882
/// Return the array of all result information. This may contain inter-mingled
48804883
/// direct and indirect results.
48814884
ArrayRef<SILResultInfo> getResults() const {
48824885
return const_cast<SILFunctionType *>(this)->getMutableResults();
48834886
}
4884-
unsigned getNumResults() const { return isCoroutine() ? 0 : NumAnyResults; }
4887+
unsigned getNumResults() const { return NumAnyResults; }
48854888

48864889
ArrayRef<SILResultInfo> getResultsWithError() const {
48874890
return const_cast<SILFunctionType *>(this)->getMutableResultsWithError();
@@ -4918,17 +4921,17 @@ class SILFunctionType final
49184921
// indirect property, not the SIL indirect property, should be consulted to
49194922
// determine whether function reabstraction is necessary.
49204923
unsigned getNumIndirectFormalResults() const {
4921-
return isCoroutine() ? 0 : NumAnyIndirectFormalResults;
4924+
return NumAnyIndirectFormalResults;
49224925
}
49234926
/// Does this function have any formally indirect results?
49244927
bool hasIndirectFormalResults() const {
49254928
return getNumIndirectFormalResults() != 0;
49264929
}
49274930
unsigned getNumDirectFormalResults() const {
4928-
return isCoroutine() ? 0 : NumAnyResults - NumAnyIndirectFormalResults;
4931+
return NumAnyResults - NumAnyIndirectFormalResults;
49294932
}
49304933
unsigned getNumPackResults() const {
4931-
return isCoroutine() ? 0 : NumPackResults;
4934+
return NumPackResults;
49324935
}
49334936
bool hasIndirectErrorResult() const {
49344937
return hasErrorResult() && getErrorResult().isFormalIndirect();
@@ -4986,17 +4989,17 @@ class SILFunctionType final
49864989
TypeExpansionContext expansion);
49874990

49884991
unsigned getNumIndirectFormalYields() const {
4989-
return isCoroutine() ? NumAnyIndirectFormalResults : 0;
4992+
return NumAnyIndirectFormalYieldResults;
49904993
}
49914994
/// Does this function have any formally indirect yields?
49924995
bool hasIndirectFormalYields() const {
49934996
return getNumIndirectFormalYields() != 0;
49944997
}
49954998
unsigned getNumDirectFormalYields() const {
4996-
return isCoroutine() ? NumAnyResults - NumAnyIndirectFormalResults : 0;
4999+
return NumAnyYieldResults - NumAnyIndirectFormalYieldResults;
49975000
}
49985001
unsigned getNumPackYields() const {
4999-
return isCoroutine() ? NumPackResults : 0;
5002+
return NumPackYieldResults;
50005003
}
50015004

50025005
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) {
579+
EndApplyInst *createEndApply(SILLocation loc, SILValue beginApply, SILType ResultType) {
580580
return insert(new (getModule()) EndApplyInst(getSILDebugLocation(loc),
581-
beginApply));
581+
beginApply, ResultType));
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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,8 @@ SILCloner<ImplClass>::visitEndApplyInst(EndApplyInst *Inst) {
10761076
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
10771077
recordClonedInstruction(
10781078
Inst, getBuilder().createEndApply(getOpLocation(Inst->getLoc()),
1079-
getOpValue(Inst->getOperand())));
1079+
getOpValue(Inst->getOperand()),
1080+
getOpType(Inst->getType())));
10801081
}
10811082

10821083
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

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

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

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ 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)
571573

572574
// Metatypes
573575
SINGLE_VALUE_INST(MetatypeInst, metatype,
@@ -871,8 +873,6 @@ NON_VALUE_INST(UncheckedRefCastAddrInst, unchecked_ref_cast_addr,
871873
SILInstruction, MayHaveSideEffects, DoesNotRelease)
872874
NON_VALUE_INST(AllocGlobalInst, alloc_global,
873875
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: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4535,29 +4535,29 @@ SILFunctionType::SILFunctionType(
45354535
!ext.getLifetimeDependenceInfo().empty();
45364536
Bits.SILFunctionType.CoroutineKind = unsigned(coroutineKind);
45374537
NumParameters = params.size();
4538-
if (coroutineKind == SILCoroutineKind::None) {
4539-
assert(yields.empty());
4540-
NumAnyResults = normalResults.size();
4541-
NumAnyIndirectFormalResults = 0;
4542-
NumPackResults = 0;
4543-
for (auto &resultInfo : normalResults) {
4544-
if (resultInfo.isFormalIndirect())
4545-
NumAnyIndirectFormalResults++;
4546-
if (resultInfo.isPack())
4547-
NumPackResults++;
4548-
}
4549-
memcpy(getMutableResults().data(), normalResults.data(),
4550-
normalResults.size() * sizeof(SILResultInfo));
4551-
} else {
4552-
assert(normalResults.empty());
4553-
NumAnyResults = yields.size();
4554-
NumAnyIndirectFormalResults = 0;
4538+
assert((coroutineKind == SILCoroutineKind::None && yields.empty()) ||
4539+
coroutineKind != SILCoroutineKind::None);
4540+
4541+
NumAnyResults = normalResults.size();
4542+
NumAnyIndirectFormalResults = 0;
4543+
NumPackResults = 0;
4544+
for (auto &resultInfo : normalResults) {
4545+
if (resultInfo.isFormalIndirect())
4546+
NumAnyIndirectFormalResults++;
4547+
if (resultInfo.isPack())
4548+
NumPackResults++;
4549+
}
4550+
memcpy(getMutableResults().data(), normalResults.data(),
4551+
normalResults.size() * sizeof(SILResultInfo));
4552+
if (coroutineKind != SILCoroutineKind::None) {
4553+
NumAnyYieldResults = yields.size();
4554+
NumAnyIndirectFormalYieldResults = 0;
45554555
NumPackResults = 0;
45564556
for (auto &yieldInfo : yields) {
45574557
if (yieldInfo.isFormalIndirect())
4558-
NumAnyIndirectFormalResults++;
4558+
NumAnyIndirectFormalYieldResults++;
45594559
if (yieldInfo.isPack())
4560-
NumPackResults++;
4560+
NumPackYieldResults++;
45614561
}
45624562
memcpy(getMutableYields().data(), yields.data(),
45634563
yields.size() * sizeof(SILYieldInfo));
@@ -4729,7 +4729,6 @@ CanSILFunctionType SILFunctionType::get(
47294729
llvm::Optional<SILResultInfo> errorResult, SubstitutionMap patternSubs,
47304730
SubstitutionMap invocationSubs, const ASTContext &ctx,
47314731
ProtocolConformanceRef witnessMethodConformance) {
4732-
assert(coroutineKind == SILCoroutineKind::None || normalResults.empty());
47334732
assert(coroutineKind != SILCoroutineKind::None || yields.empty());
47344733
assert(!ext.isPseudogeneric() || genericSig ||
47354734
coroutineKind != SILCoroutineKind::None);

0 commit comments

Comments
 (0)