Skip to content

Commit df1c4f6

Browse files
committed
[CoroutineAccessors] Add new SILFnTy CoroKind.
For `modify` and `read` coroutines, produce SILFunctionType's whose coroutineKind is ::YieldOnce2.
1 parent 9e45aa5 commit df1c4f6

30 files changed

+211
-29
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ mangled in to disambiguate.
856856
FUNC-REPRESENTATION ::= 'W' // protocol witness
857857

858858
COROUTINE-KIND ::= 'A' // yield-once coroutine
859+
COROUTINE-KIND ::= 'I' // yield-once-2 coroutine
859860
COROUTINE-KIND ::= 'G' // yield-many coroutine
860861

861862
#if SWIFT_RUNTIME_VERSION >= 5.5

docs/SIL.rst

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -789,13 +789,16 @@ coroutine, where a normal function return would need to transfer ownership of
789789
its return value, since a normal function's context ceases to exist and be able
790790
to maintain ownership of the value after it returns.
791791

792-
To support these concepts, SIL supports two kinds of coroutine:
793-
``@yield_many`` and ``@yield_once``. Either of these attributes may be
792+
To support these concepts, SIL supports two flavors: single-yield and
793+
multi-yield. These two flavors correspond to three kinds. A multi-yield
794+
coroutine is of kind ``@yield_many``. A single-yield coroutine is of kind
795+
either ``@yield_once`` or ``@yield_once_2``. Any of these attributes may be
794796
written before a function type to indicate that it is a coroutine type.
795-
``@yield_many`` and ``@yield_once`` coroutines are allowed to also be
796-
``@async``. (Note that ``@async`` functions are not themselves modeled
797-
explicitly as coroutines in SIL, although the implementation may use a coroutine
798-
lowering strategy.)
797+
798+
Both single-yield and multi-yield coroutines are allowed to also be ``@async``.
799+
(Note that ``@async`` functions are not themselves modeled explicitly as
800+
coroutines in SIL, although the implementation may use a coroutine lowering
801+
strategy.)
799802

800803
A coroutine type may declare any number of *yielded values*, which is to
801804
say, values which are provided to the caller at a yield point. Yielded
@@ -816,9 +819,10 @@ calling a yield-many coroutine of any kind.
816819
Coroutines may contain the special ``yield`` and ``unwind``
817820
instructions.
818821

819-
A ``@yield_many`` coroutine may yield as many times as it desires.
820-
A ``@yield_once`` coroutine may yield exactly once before returning,
821-
although it may also ``throw`` before reaching that point.
822+
A multi-yield (``@yield_many``) coroutine may yield as many times as it desires.
823+
A single-yield (``@yield_once`` or ``@yield_once_2``) coroutine may yield
824+
exactly once before returning, although it may also ``throw`` before reaching
825+
that point.
822826

823827
Variadic Generics
824828
`````````````````
@@ -8376,9 +8380,10 @@ the current function was invoked with a ``try_apply`` instruction, control
83768380
resumes at the normal destination, and the value of the basic block argument
83778381
will be the operand of this ``return`` instruction.
83788382

8379-
If the current function is a ``yield_once`` coroutine, there must not be
8380-
a path from the entry block to a ``return`` which does not pass through
8381-
a ``yield`` instruction. This rule does not apply in the ``raw`` SIL stage.
8383+
If the current function is a single-yield coroutine (``yield_once`` or
8384+
``yield_once_2``), there must not be a path from the entry block to a
8385+
``return`` which does not pass through a ``yield`` instruction. This rule does
8386+
not apply in the ``raw`` SIL stage.
83828387

83838388
``return`` does not retain or release its operand or any other values.
83848389

@@ -8446,9 +8451,10 @@ The ``resume`` and ``unwind`` destination blocks must be uniquely
84468451
referenced by the ``yield`` instruction. This prevents them from becoming
84478452
critical edges.
84488453

8449-
In a ``yield_once`` coroutine, there must not be a control flow path leading
8450-
from the ``resume`` edge to another ``yield`` instruction in this function.
8451-
This rule does not apply in the ``raw`` SIL stage.
8454+
In a single-yield coroutine (``yield_once`` or ``yield_once_2``), there must
8455+
not be a control flow path leading from the ``resume`` edge to another
8456+
``yield`` instruction in this function. This rule does not apply in the ``raw``
8457+
SIL stage.
84528458

84538459
There must not be a control flow path leading from the ``unwind`` edge to
84548460
a ``return`` instruction, to a ``throw`` instruction, or to any block

include/swift/AST/IRGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
165165
/// Resumption functions from yield-once coroutines.
166166
PointerAuthSchema YieldOnceResumeFunctions;
167167

168+
/// Resumption functions from yield-once-2 coroutines.
169+
PointerAuthSchema YieldOnce2ResumeFunctions;
170+
168171
/// Resumption functions from yield-many coroutines.
169172
PointerAuthSchema YieldManyResumeFunctions;
170173

include/swift/AST/TypeAttr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ SIMPLE_SIL_TYPE_ATTR(pseudogeneric, Pseudogeneric)
101101
SIMPLE_SIL_TYPE_ATTR(unimplementable, Unimplementable)
102102
SIMPLE_SIL_TYPE_ATTR(yields, Yields)
103103
SIMPLE_SIL_TYPE_ATTR(yield_once, YieldOnce)
104+
SIMPLE_SIL_TYPE_ATTR(yield_once_2, YieldOnce2)
104105
SIMPLE_SIL_TYPE_ATTR(yield_many, YieldMany)
105106
SIMPLE_SIL_TYPE_ATTR(captures_generics, CapturesGenerics)
106107
// Used at the SIL level to mark a type as moveOnly.

include/swift/AST/Types.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4823,11 +4823,17 @@ enum class SILCoroutineKind : uint8_t {
48234823
/// It must not have normal results and may have arbitrary yield results.
48244824
YieldOnce,
48254825

4826+
/// This function is a yield-once coroutine (used by read and modify
4827+
/// accessors). It has the following differences from YieldOnce:
4828+
/// - it does not observe errors thrown by its caller
4829+
/// - it uses the callee-allocated ABI
4830+
YieldOnce2,
4831+
48264832
/// This function is a yield-many coroutine (used by e.g. generators).
48274833
/// It must not have normal results and may have arbitrary yield results.
48284834
YieldMany,
48294835
};
4830-
4836+
48314837
class SILFunctionConventions;
48324838

48334839

@@ -5039,6 +5045,17 @@ class SILFunctionType final
50395045
SILCoroutineKind getCoroutineKind() const {
50405046
return SILCoroutineKind(Bits.SILFunctionType.CoroutineKind);
50415047
}
5048+
/// Whether this coroutine's ABI is callee-allocated.
5049+
bool isCalleeAllocatedCoroutine() const {
5050+
switch (getCoroutineKind()) {
5051+
case SILCoroutineKind::None:
5052+
case SILCoroutineKind::YieldOnce:
5053+
case SILCoroutineKind::YieldMany:
5054+
return false;
5055+
case SILCoroutineKind::YieldOnce2:
5056+
return true;
5057+
}
5058+
}
50425059

50435060
bool isSendable() const { return getExtInfo().isSendable(); }
50445061
bool isUnimplementable() const { return getExtInfo().isUnimplementable(); }

include/swift/Demangling/TypeDecoder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ enum class ImplMetatypeRepresentation {
5151
enum class ImplCoroutineKind {
5252
None,
5353
YieldOnce,
54+
YieldOnce2,
5455
YieldMany,
5556
};
5657

@@ -1097,6 +1098,8 @@ class TypeDecoder {
10971098
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
10981099
if (child->getText() == "yield_once") {
10991100
coroutineKind = ImplCoroutineKind::YieldOnce;
1101+
} else if (child->getText() == "yield_once_2") {
1102+
coroutineKind = ImplCoroutineKind::YieldOnce2;
11001103
} else if (child->getText() == "yield_many") {
11011104
coroutineKind = ImplCoroutineKind::YieldMany;
11021105
} else

include/swift/SIL/SILInstruction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,6 +3251,10 @@ class BeginApplyInst final
32513251
public:
32523252
using MultipleValueInstructionTrailingObjects::totalSizeToAlloc;
32533253

3254+
bool isCalleeAllocated() const {
3255+
return getSubstCalleeType()->isCalleeAllocatedCoroutine();
3256+
}
3257+
32543258
MultipleValueInstructionResult *getTokenResult() const {
32553259
return const_cast<MultipleValueInstructionResult *>(
32563260
&getAllResultsBuffer().back());

lib/AST/ASTDemangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ getCoroutineKind(ImplCoroutineKind kind) {
582582
return SILCoroutineKind::None;
583583
case ImplCoroutineKind::YieldOnce:
584584
return SILCoroutineKind::YieldOnce;
585+
case ImplCoroutineKind::YieldOnce2:
586+
return SILCoroutineKind::YieldOnce2;
585587
case ImplCoroutineKind::YieldMany:
586588
return SILCoroutineKind::YieldMany;
587589
}

lib/AST/ASTMangler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,9 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
21492149
case SILCoroutineKind::YieldOnce:
21502150
OpArgs.push_back('A');
21512151
break;
2152+
case SILCoroutineKind::YieldOnce2:
2153+
OpArgs.push_back('I');
2154+
break;
21522155
case SILCoroutineKind::YieldMany:
21532156
OpArgs.push_back('G');
21542157
break;

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6748,6 +6748,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
67486748
case SILCoroutineKind::YieldOnce:
67496749
Printer << "@yield_once ";
67506750
return;
6751+
case SILCoroutineKind::YieldOnce2:
6752+
Printer << "@yield_once_2 ";
6753+
return;
67516754
case SILCoroutineKind::YieldMany:
67526755
Printer << "@yield_many ";
67536756
return;

0 commit comments

Comments
 (0)