Skip to content

Commit 08e3a98

Browse files
Merge pull request #80741 from nate-chandler/cherrypick/release/6.2/rdar148941214
6.2: [CoroutineAccessors] Use yield_once_2 on Darwin and Linux.
2 parents 0b995da + 9690397 commit 08e3a98

26 files changed

+195
-38
lines changed

include/swift/AST/SILOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ class SILOptions {
338338
// Whether to allow merging traps and cond_fails.
339339
bool MergeableTraps = false;
340340

341+
/// Whether the @yield_once_2 convention is used by accessors added with the
342+
/// CoroutineAccessors feature (i.e. read2/modify2).
343+
bool CoroutineAccessorsUseYieldOnce2 = false;
344+
341345
SILOptions() {}
342346

343347
/// Return a hash code of any components from these options that should

include/swift/Option/FrontendOptions.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,12 @@ def enable_arm64_corocc : Flag<["-"], "enable-arm64-corocc">,
11751175
def disable_arm64_corocc : Flag<["-"], "disable-arm64-corocc">,
11761176
HelpText<"Don't use swiftcorocc for yield_once_2 routines on arm64 variants.">;
11771177

1178+
def enable_callee_allocated_coro_abi : Flag<["-"], "enable-callee-allocated-coro-abi">,
1179+
HelpText<"Override per-platform settings and use yield_once_2.">;
1180+
1181+
def disable_callee_allocated_coro_abi : Flag<["-"], "disable-callee-allocated-coro-abi">,
1182+
HelpText<"Override per-platform settings and don't use yield_once_2.">;
1183+
11781184
def enable_cond_fail_message_annotation : Flag<["-"], "enable-cond-fail-message-annotation">,
11791185
HelpText<"Enable cond_fail message annotation. Will serialize a .o.yaml file per .o file.">;
11801186

lib/DriverTool/sil_opt_main.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,16 @@ struct SILOptOptions {
597597
"enable-address-dependencies",
598598
llvm::cl::desc("Enable enforcement of lifetime dependencies on addressable values."));
599599

600+
llvm::cl::opt<bool> EnableCalleeAllocatedCoroAbi = llvm::cl::opt<bool>(
601+
"enable-callee-allocated-coro-abi",
602+
llvm::cl::desc("Override per-platform settings and use yield_once_2."),
603+
llvm::cl::init(false));
604+
llvm::cl::opt<bool> DisableCalleeAllocatedCoroAbi = llvm::cl::opt<bool>(
605+
"disable-callee-allocated-coro-abi",
606+
llvm::cl::desc(
607+
"Override per-platform settings and don't use yield_once_2."),
608+
llvm::cl::init(false));
609+
600610
llvm::cl::opt<bool> MergeableTraps = llvm::cl::opt<bool>(
601611
"mergeable-traps",
602612
llvm::cl::desc("Enable cond_fail merging."));
@@ -918,6 +928,10 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
918928
options.EnablePackMetadataStackPromotion;
919929

920930
SILOpts.EnableAddressDependencies = options.EnableAddressDependencies;
931+
if (options.EnableCalleeAllocatedCoroAbi)
932+
SILOpts.CoroutineAccessorsUseYieldOnce2 = true;
933+
if (options.DisableCalleeAllocatedCoroAbi)
934+
SILOpts.CoroutineAccessorsUseYieldOnce2 = false;
921935
SILOpts.MergeableTraps = options.MergeableTraps;
922936

923937
if (options.OptModeFlag == OptimizationMode::NotSet) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,6 +3130,16 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
31303130
Opts.EnableAddressDependencies = Args.hasFlag(
31313131
OPT_enable_address_dependencies, OPT_disable_address_dependencies,
31323132
Opts.EnableAddressDependencies);
3133+
3134+
if (LangOpts.Target.isOSDarwin() || LangOpts.Target.isOSLinux()) {
3135+
// On Darwin and Linux, use yield_once_2 by default.
3136+
Opts.CoroutineAccessorsUseYieldOnce2 = true;
3137+
}
3138+
Opts.CoroutineAccessorsUseYieldOnce2 =
3139+
Args.hasFlag(OPT_enable_callee_allocated_coro_abi,
3140+
OPT_disable_callee_allocated_coro_abi,
3141+
Opts.CoroutineAccessorsUseYieldOnce2);
3142+
31333143
Opts.MergeableTraps = Args.hasArg(OPT_mergeable_traps);
31343144

31353145
return false;

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,5 +1855,8 @@ bool SILDeclRef::isCalleeAllocatedCoroutine() const {
18551855
if (!accessor)
18561856
return false;
18571857

1858-
return requiresFeatureCoroutineAccessors(accessor->getAccessorKind());
1858+
if (!requiresFeatureCoroutineAccessors(accessor->getAccessorKind()))
1859+
return false;
1860+
1861+
return getASTContext().SILOpts.CoroutineAccessorsUseYieldOnce2;
18591862
}

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2481,8 +2481,10 @@ static CanSILFunctionType getSILFunctionType(
24812481

24822482
if (auto accessor = getAsCoroutineAccessor(constant)) {
24832483
auto origAccessor = cast<AccessorDecl>(origConstant->getDecl());
2484+
auto &ctx = origAccessor->getASTContext();
24842485
coroutineKind =
2485-
requiresFeatureCoroutineAccessors(accessor->getAccessorKind())
2486+
(requiresFeatureCoroutineAccessors(accessor->getAccessorKind()) &&
2487+
ctx.SILOpts.CoroutineAccessorsUseYieldOnce2)
24862488
? SILCoroutineKind::YieldOnce2
24872489
: SILCoroutineKind::YieldOnce;
24882490

lib/SILGen/SILGenApply.cpp

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5000,14 +5000,16 @@ class CallEmission {
50005000
FormalEvaluationScope initialWritebackScope;
50015001
std::optional<ActorIsolation> implicitActorHopTarget;
50025002
bool implicitlyThrows;
5003+
bool canUnwind;
50035004

50045005
public:
50055006
/// Create an emission for a call of the given callee.
50065007
CallEmission(SILGenFunction &SGF, Callee &&callee,
50075008
FormalEvaluationScope &&writebackScope)
50085009
: SGF(SGF), callee(std::move(callee)),
50095010
initialWritebackScope(std::move(writebackScope)),
5010-
implicitActorHopTarget(std::nullopt), implicitlyThrows(false) {}
5011+
implicitActorHopTarget(std::nullopt), implicitlyThrows(false),
5012+
canUnwind(false) {}
50115013

50125014
/// A factory method for decomposing the apply expr \p e into a call
50135015
/// emission.
@@ -5058,6 +5060,8 @@ class CallEmission {
50585060
/// function can throw or not.
50595061
void setImplicitlyThrows(bool flag) { implicitlyThrows = flag; }
50605062

5063+
void setCanUnwind(bool flag) { canUnwind = flag; }
5064+
50615065
CleanupHandle applyCoroutine(SmallVectorImpl<ManagedValue> &yields);
50625066

50635067
RValue apply(SGFContext C = SGFContext()) {
@@ -5115,9 +5119,11 @@ namespace {
51155119
/// Cleanup to end a coroutine application.
51165120
class EndCoroutineApply : public Cleanup {
51175121
SILValue ApplyToken;
5122+
bool CanUnwind;
51185123
std::vector<BeginBorrowInst *> BorrowedMoveOnlyValues;
51195124
public:
5120-
EndCoroutineApply(SILValue applyToken) : ApplyToken(applyToken) {}
5125+
EndCoroutineApply(SILValue applyToken, bool CanUnwind)
5126+
: ApplyToken(applyToken), CanUnwind(CanUnwind) {}
51215127

51225128
void setBorrowedMoveOnlyValues(ArrayRef<BeginBorrowInst *> values) {
51235129
BorrowedMoveOnlyValues.insert(BorrowedMoveOnlyValues.end(),
@@ -5130,14 +5136,7 @@ class EndCoroutineApply : public Cleanup {
51305136
SGF.B.createEndBorrow(l, *i);
51315137
SGF.B.createDestroyValue(l, (*i)->getOperand());
51325138
}
5133-
auto *beginApply =
5134-
cast<BeginApplyInst>(ApplyToken->getDefiningInstruction());
5135-
auto isCalleeAllocated = beginApply->isCalleeAllocated();
5136-
auto unwindOnCallerError =
5137-
!isCalleeAllocated ||
5138-
SGF.SGM.getASTContext().LangOpts.hasFeature(
5139-
Feature::CoroutineAccessorsUnwindOnCallerError);
5140-
if (forUnwind && unwindOnCallerError) {
5139+
if (forUnwind && CanUnwind) {
51415140
SGF.B.createAbortApply(l, ApplyToken);
51425141
} else {
51435142
SGF.B.createEndApply(l, ApplyToken,
@@ -5180,18 +5179,15 @@ CallEmission::applyCoroutine(SmallVectorImpl<ManagedValue> &yields) {
51805179

51815180
auto fnValue = callee.getFnValue(SGF, borrowedSelf);
51825181

5183-
return SGF.emitBeginApply(uncurriedLoc.value(), fnValue,
5182+
return SGF.emitBeginApply(uncurriedLoc.value(), fnValue, canUnwind,
51845183
callee.getSubstitutions(), uncurriedArgs,
51855184
calleeTypeInfo.substFnType, options, yields);
51865185
}
51875186

5188-
CleanupHandle
5189-
SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
5190-
SubstitutionMap subs,
5191-
ArrayRef<ManagedValue> args,
5192-
CanSILFunctionType substFnType,
5193-
ApplyOptions options,
5194-
SmallVectorImpl<ManagedValue> &yields) {
5187+
CleanupHandle SILGenFunction::emitBeginApply(
5188+
SILLocation loc, ManagedValue fn, bool canUnwind, SubstitutionMap subs,
5189+
ArrayRef<ManagedValue> args, CanSILFunctionType substFnType,
5190+
ApplyOptions options, SmallVectorImpl<ManagedValue> &yields) {
51955191
// Emit the call.
51965192
SmallVector<SILValue, 4> rawResults;
51975193
emitRawApply(*this, loc, fn, subs, args, substFnType, options,
@@ -5207,7 +5203,7 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
52075203

52085204
// Push a cleanup to end the application.
52095205
// TODO: destroy all the arguments at exactly this point?
5210-
Cleanups.pushCleanup<EndCoroutineApply>(token);
5206+
Cleanups.pushCleanup<EndCoroutineApply>(token, canUnwind);
52115207
auto endApplyHandle = getTopCleanup();
52125208

52135209
// Manage all the yielded values.
@@ -6184,7 +6180,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
61846180
std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
61856181
CleanupHandle>
61866182
SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
6187-
SILType substFnType,
6183+
SILType substFnType, bool canUnwind,
61886184
SubstitutionMap subs,
61896185
ArrayRef<SILValue> args,
61906186
SmallVectorImpl<SILValue> &yields) {
@@ -6209,7 +6205,7 @@ SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
62096205
deallocCleanup = enterDeallocStackCleanup(allocation);
62106206
}
62116207

6212-
Cleanups.pushCleanup<EndCoroutineApply>(token);
6208+
Cleanups.pushCleanup<EndCoroutineApply>(token, canUnwind);
62136209
auto abortCleanup = Cleanups.getTopCleanup();
62146210

62156211
return {token, abortCleanup, allocation, deallocCleanup};
@@ -7562,6 +7558,21 @@ ManagedValue SILGenFunction::emitAddressorAccessor(
75627558
return ManagedValue::forLValue(address);
75637559
}
75647560

7561+
bool SILGenFunction::canUnwindAccessorDeclRef(SILDeclRef accessorRef) {
7562+
auto *accessor =
7563+
dyn_cast_or_null<AccessorDecl>(accessorRef.getAbstractFunctionDecl());
7564+
ASSERT(accessor && "only accessors can unwind");
7565+
auto kind = accessor->getAccessorKind();
7566+
ASSERT(isYieldingAccessor(kind) && "only yielding accessors can unwind");
7567+
if (!requiresFeatureCoroutineAccessors(kind)) {
7568+
// _read and _modify can unwind
7569+
return true;
7570+
}
7571+
// Coroutine accessors can only unwind with the experimental feature.
7572+
return getASTContext().LangOpts.hasFeature(
7573+
Feature::CoroutineAccessorsUnwindOnCallerError);
7574+
}
7575+
75657576
CleanupHandle
75667577
SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
75677578
SubstitutionMap substitutions,
@@ -7597,6 +7608,8 @@ SILGenFunction::emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
75977608

75987609
emission.addCallSite(loc, std::move(subscriptIndices));
75997610

7611+
emission.setCanUnwind(canUnwindAccessorDeclRef(accessor));
7612+
76007613
auto endApplyHandle = emission.applyCoroutine(yields);
76017614

76027615
return endApplyHandle;

lib/SILGen/SILGenFunction.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
20342034
PreparedArguments &&optionalSubscripts,
20352035
SILType addressType, bool isOnSelfParameter);
20362036

2037+
bool canUnwindAccessorDeclRef(SILDeclRef accessorRef);
20372038
CleanupHandle emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
20382039
SubstitutionMap substitutions,
20392040
ArgumentSource &&optionalSelfValue,
@@ -2301,8 +2302,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
23012302
PreparedArguments &&args, Type overriddenSelfType,
23022303
SGFContext ctx);
23032304

2304-
CleanupHandle emitBeginApply(SILLocation loc, ManagedValue fn,
2305-
SubstitutionMap subs, ArrayRef<ManagedValue> args,
2305+
CleanupHandle emitBeginApply(SILLocation loc, ManagedValue fn, bool canUnwind,
2306+
SubstitutionMap subs,
2307+
ArrayRef<ManagedValue> args,
23062308
CanSILFunctionType substFnType,
23072309
ApplyOptions options,
23082310
SmallVectorImpl<ManagedValue> &yields);
@@ -2315,7 +2317,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
23152317
std::tuple<MultipleValueInstructionResult *, CleanupHandle, SILValue,
23162318
CleanupHandle>
23172319
emitBeginApplyWithRethrow(SILLocation loc, SILValue fn, SILType substFnType,
2318-
SubstitutionMap subs, ArrayRef<SILValue> args,
2320+
bool canUnwind, SubstitutionMap subs,
2321+
ArrayRef<SILValue> args,
23192322
SmallVectorImpl<SILValue> &yields);
23202323
void emitEndApplyWithRethrow(SILLocation loc,
23212324
MultipleValueInstructionResult *token,

lib/SILGen/SILGenLValue.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,9 +2535,9 @@ namespace {
25352535

25362536
// Perform the begin_apply.
25372537
SmallVector<ManagedValue, 1> yields;
2538-
auto cleanup =
2539-
SGF.emitBeginApply(loc, projectFnRef, subs, { base, keyPathValue },
2540-
substFnType, ApplyOptions(), yields);
2538+
auto cleanup = SGF.emitBeginApply(loc, projectFnRef, /*canUnwind=*/true,
2539+
subs, {base, keyPathValue}, substFnType,
2540+
ApplyOptions(), yields);
25412541

25422542
// Push an operation to do the end_apply.
25432543
pushEndApplyWriteback(SGF, loc, cleanup, getTypeData());

lib/SILGen/SILGenPoly.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7046,8 +7046,8 @@ SILGenFunction::emitVTableThunk(SILDeclRef base,
70467046
case SILCoroutineKind::YieldOnce2: {
70477047
SmallVector<SILValue, 4> derivedYields;
70487048
auto tokenAndCleanups = emitBeginApplyWithRethrow(
7049-
loc, derivedRef, SILType::getPrimitiveObjectType(derivedFTy), subs,
7050-
args, derivedYields);
7049+
loc, derivedRef, SILType::getPrimitiveObjectType(derivedFTy),
7050+
canUnwindAccessorDeclRef(base), subs, args, derivedYields);
70517051
auto token = std::get<0>(tokenAndCleanups);
70527052
auto abortCleanup = std::get<1>(tokenAndCleanups);
70537053
auto allocation = std::get<2>(tokenAndCleanups);
@@ -7441,7 +7441,8 @@ void SILGenFunction::emitProtocolWitness(
74417441
case SILCoroutineKind::YieldOnce2: {
74427442
SmallVector<SILValue, 4> witnessYields;
74437443
auto tokenAndCleanups = emitBeginApplyWithRethrow(
7444-
loc, witnessFnRef, witnessSILTy, witnessSubs, args, witnessYields);
7444+
loc, witnessFnRef, witnessSILTy, canUnwindAccessorDeclRef(requirement),
7445+
witnessSubs, args, witnessYields);
74457446
auto token = std::get<0>(tokenAndCleanups);
74467447
auto abortCleanup = std::get<1>(tokenAndCleanups);
74477448
auto allocation = std::get<2>(tokenAndCleanups);

test/IRGen/coroutine_accessors.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-emit-irgen \
22
// RUN: %s \
3+
// RUN: -enable-callee-allocated-coro-abi \
34
// RUN: -enable-experimental-feature CoroutineAccessors \
45
// RUN: | %IRGenFileCheck %s
56

test/IRGen/coroutine_accessors_backdeploy_async_56.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-emit-irgen \
22
// RUN: %s \
3+
// RUN: -enable-callee-allocated-coro-abi \
34
// RUN: -module-name backdep \
45
// RUN: -target %target-swift-5.6-abi-triple \
56
// RUN: -Onone \

test/IRGen/coroutine_accessors_backdeploy_async_57.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-emit-irgen \
22
// RUN: %s \
3+
// RUN: -enable-callee-allocated-coro-abi \
34
// RUN: -module-name backdep \
45
// RUN: -target %target-swift-5.7-abi-triple \
56
// RUN: -Onone \

test/IRGen/coroutine_accessors_popless.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-swift-emit-irgen \
22
// RUN: %s \
33
// RUN: -Onone \
4+
// RUN: -enable-callee-allocated-coro-abi \
45
// RUN: -enable-experimental-feature CoroutineAccessors \
56
// RUN: -enable-arm64-corocc \
67
// RUN: -enable-x86_64-corocc \

test/IRGen/default_override.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-frontend \
22
// RUN: %s \
3+
// RUN: -enable-callee-allocated-coro-abi \
34
// RUN: -module-name Library \
45
// RUN: -emit-ir \
56
// RUN: -enable-experimental-feature CoroutineAccessors \

test/IRGen/run-coroutine_accessors.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@
9494
// UNSUPPORTED: wasm
9595
// UNSUPPORTED: OS=wasi
9696
// UNSUPPORTED: CPU=wasm32
97-
// TODO: CoroutineAccessors: Enable on Windows.
98-
// UNSUPPORTED: OS=windows-msvc
9997

10098
// REQUIRES: swift_feature_CoroutineAccessors
10199

test/Interpreter/coroutine_accessors_default_implementations.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// RUN: %target-swift-frontend \
66
// RUN: %t/Library.swift \
77
// RUN: %t/LibImpl.underscored.swift \
8+
// RUN: -enable-callee-allocated-coro-abi \
89
// RUN: -emit-module \
910
// RUN: -module-name Library \
1011
// RUN: -parse-as-library \
@@ -13,6 +14,7 @@
1314

1415
// RUN: %target-swift-frontend \
1516
// RUN: %t/Executable.swift \
17+
// RUN: -enable-callee-allocated-coro-abi \
1618
// RUN: -c \
1719
// RUN: -parse-as-library \
1820
// RUN: -module-name Executable \
@@ -22,6 +24,7 @@
2224
// RUN: %target-build-swift-dylib(%t/%target-library-name(Library)) \
2325
// RUN: %t/Library.swift \
2426
// RUN: %t/LibImpl.nonunderscored.swift \
27+
// RUN: -Xfrontend -enable-callee-allocated-coro-abi \
2528
// RUN: -emit-module \
2629
// RUN: -enable-library-evolution \
2730
// RUN: -enable-experimental-feature CoroutineAccessors \

0 commit comments

Comments
 (0)