Skip to content

Commit ce64fe8

Browse files
authored
Merge pull request #41272 from rjmccall/revert-hop-to-generic-executor-5.6
[5.6] Revert the partial SE-0338 implementation
2 parents 1ef7212 + 1b58617 commit ce64fe8

17 files changed

+139
-255
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,7 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
15881588
// A hop is only needed in the thunk if it is global-actor isolated.
15891589
// Native, instance-isolated async methods will hop in the prologue.
15901590
if (isolation && isolation->isGlobalActor()) {
1591-
emitPrologGlobalActorHop(loc, isolation->getGlobalActor());
1591+
emitHopToTargetActor(loc, *isolation, None);
15921592
}
15931593
}
15941594

lib/SILGen/SILGenConstructor.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -672,17 +672,13 @@ static void emitDefaultActorInitialization(
672672
void SILGenFunction::emitConstructorPrologActorHop(
673673
SILLocation loc,
674674
Optional<ActorIsolation> maybeIso) {
675-
loc = loc.asAutoGenerated();
676-
if (maybeIso) {
677-
if (auto executor = emitExecutor(loc, *maybeIso, None)) {
678-
ExpectedExecutor = *executor;
679-
}
680-
}
681-
682-
if (!ExpectedExecutor)
683-
ExpectedExecutor = emitGenericExecutor(loc);
675+
if (!maybeIso)
676+
return;
684677

685-
B.createHopToExecutor(loc, ExpectedExecutor, /*mandatory*/ false);
678+
if (auto executor = emitExecutor(loc, *maybeIso, None)) {
679+
ExpectedExecutor = *executor;
680+
B.createHopToExecutor(loc.asAutoGenerated(), *executor, /*mandatory*/ false);
681+
}
686682
}
687683

688684
// MARK: class constructor

lib/SILGen/SILGenFunction.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,36 @@ void SILGenFunction::emitAsyncMainThreadStart(SILDeclRef entryPoint) {
922922
JobType, {}, {task});
923923
jobResult = wrapCallArgs(jobResult, swiftJobRunFuncDecl, 0);
924924

925-
SILValue mainExecutor = emitMainExecutor(moduleLoc);
925+
// Get main executor
926+
FuncDecl *getMainExecutorFuncDecl = SGM.getGetMainExecutor();
927+
if (!getMainExecutorFuncDecl) {
928+
// If it doesn't exist due to an SDK-compiler mismatch, we can conjure one
929+
// up instead of crashing:
930+
// @available(SwiftStdlib 5.1, *)
931+
// @_silgen_name("swift_task_getMainExecutor")
932+
// internal func _getMainExecutor() -> Builtin.Executor
933+
934+
ParameterList *emptyParams = ParameterList::createEmpty(getASTContext());
935+
getMainExecutorFuncDecl = FuncDecl::createImplicit(
936+
getASTContext(), StaticSpellingKind::None,
937+
DeclName(
938+
getASTContext(),
939+
DeclBaseName(getASTContext().getIdentifier("_getMainExecutor")),
940+
/*Arguments*/ emptyParams),
941+
{}, /*async*/ false, /*throws*/ false, {}, emptyParams,
942+
getASTContext().TheExecutorType,
943+
entryPoint.getDecl()->getModuleContext());
944+
getMainExecutorFuncDecl->getAttrs().add(
945+
new (getASTContext())
946+
SILGenNameAttr("swift_task_getMainExecutor", /*implicit*/ true));
947+
}
948+
949+
SILFunction *getMainExeutorSILFunc = SGM.getFunction(
950+
SILDeclRef(getMainExecutorFuncDecl, SILDeclRef::Kind::Func),
951+
NotForDefinition);
952+
SILValue getMainExeutorFunc =
953+
B.createFunctionRefFor(moduleLoc, getMainExeutorSILFunc);
954+
SILValue mainExecutor = B.createApply(moduleLoc, getMainExeutorFunc, {}, {});
926955
mainExecutor = wrapCallArgs(mainExecutor, swiftJobRunFuncDecl, 1);
927956

928957
// Run first part synchronously

lib/SILGen/SILGenFunction.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -874,22 +874,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
874874
void emitConstructorPrologActorHop(SILLocation loc,
875875
Optional<ActorIsolation> actorIso);
876876

877-
/// Set the given global actor as the isolation for this function
878-
/// (generally a thunk) and hop to it.
879-
void emitPrologGlobalActorHop(SILLocation loc, Type globalActor);
880-
881877
/// Emit the executor for the given actor isolation.
882878
Optional<SILValue> emitExecutor(SILLocation loc,
883879
ActorIsolation isolation,
884880
Optional<ManagedValue> maybeSelf);
885881

886-
/// Emit the executor value that corresponds to the generic (concurrent)
887-
/// executor.
888-
SILValue emitGenericExecutor(SILLocation loc);
889-
890-
/// Emit the executor value that corresponds to the main actor.
891-
SILValue emitMainExecutor(SILLocation loc);
892-
893882
/// Emit a precondition check to ensure that the function is executing in
894883
/// the expected isolation context.
895884
void emitPreconditionCheckExpectedExecutor(

lib/SILGen/SILGenPoly.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2944,10 +2944,11 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
29442944

29452945
// If the input is synchronous and global-actor-qualified, and the
29462946
// output is asynchronous, hop to the executor expected by the input.
2947-
// Treat this thunk as if it were isolated to that global actor.
2947+
ExecutorBreadcrumb prevExecutor;
29482948
if (outputSubstType->isAsync() && !inputSubstType->isAsync()) {
29492949
if (Type globalActor = inputSubstType->getGlobalActor()) {
2950-
SGF.emitPrologGlobalActorHop(loc, globalActor);
2950+
prevExecutor = SGF.emitHopToTargetActor(
2951+
loc, ActorIsolation::forGlobalActor(globalActor, false), None);
29512952
}
29522953
}
29532954

@@ -2994,6 +2995,9 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
29942995
// Reabstract the result.
29952996
SILValue outerResult = resultPlanner.execute(innerResult);
29962997

2998+
// If we hopped to the target's executor, then we need to hop back.
2999+
prevExecutor.emit(SGF, loc);
3000+
29973001
scope.pop();
29983002
SGF.B.createReturn(loc, outerResult);
29993003
}

lib/SILGen/SILGenProlog.cpp

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,6 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
660660
}
661661
}
662662
}
663-
664-
// In async functions, the generic executor is our expected executor
665-
// if we don't have any sort of isolation.
666-
if (!ExpectedExecutor && F.isAsync()) {
667-
ExpectedExecutor = emitGenericExecutor(
668-
RegularLocation::getAutoGeneratedLocation(F.getLocation()));
669-
}
670663

671664
// Jump to the expected executor.
672665
if (ExpectedExecutor) {
@@ -686,54 +679,6 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
686679
}
687680
}
688681

689-
SILValue SILGenFunction::emitMainExecutor(SILLocation loc) {
690-
// Get main executor
691-
FuncDecl *getMainExecutorFuncDecl = SGM.getGetMainExecutor();
692-
if (!getMainExecutorFuncDecl) {
693-
// If it doesn't exist due to an SDK-compiler mismatch, we can conjure one
694-
// up instead of crashing:
695-
// @available(SwiftStdlib 5.1, *)
696-
// @_silgen_name("swift_task_getMainExecutor")
697-
// internal func _getMainExecutor() -> Builtin.Executor
698-
auto &ctx = getASTContext();
699-
700-
ParameterList *emptyParams = ParameterList::createEmpty(ctx);
701-
getMainExecutorFuncDecl = FuncDecl::createImplicit(
702-
ctx, StaticSpellingKind::None,
703-
DeclName(
704-
ctx,
705-
DeclBaseName(ctx.getIdentifier("_getMainExecutor")),
706-
/*Arguments*/ emptyParams),
707-
{}, /*async*/ false, /*throws*/ false, {}, emptyParams,
708-
ctx.TheExecutorType,
709-
getModule().getSwiftModule());
710-
getMainExecutorFuncDecl->getAttrs().add(
711-
new (ctx)
712-
SILGenNameAttr("swift_task_getMainExecutor", /*implicit*/ true));
713-
}
714-
715-
auto fn = SGM.getFunction(
716-
SILDeclRef(getMainExecutorFuncDecl, SILDeclRef::Kind::Func),
717-
NotForDefinition);
718-
SILValue fnRef = B.createFunctionRefFor(loc, fn);
719-
return B.createApply(loc, fnRef, {}, {});
720-
}
721-
722-
SILValue SILGenFunction::emitGenericExecutor(SILLocation loc) {
723-
// The generic executor is encoded as the nil value of
724-
// Optional<Builtin.SerialExecutor>.
725-
auto ty = SILType::getOptionalType(
726-
SILType::getPrimitiveObjectType(
727-
getASTContext().TheExecutorType));
728-
return B.createOptionalNone(loc, ty);
729-
}
730-
731-
void SILGenFunction::emitPrologGlobalActorHop(SILLocation loc,
732-
Type globalActor) {
733-
ExpectedExecutor = emitLoadGlobalActorExecutor(globalActor);
734-
B.createHopToExecutor(loc, ExpectedExecutor, /*mandatory*/ false);
735-
}
736-
737682
SILValue SILGenFunction::emitLoadGlobalActorExecutor(Type globalActor) {
738683
CanType actorType = CanType(globalActor);
739684
NominalTypeDecl *nominal = actorType->getNominalOrBoundGenericNominal();
@@ -873,8 +818,19 @@ void ExecutorBreadcrumb::emit(SILGenFunction &SGF, SILLocation loc) {
873818
}
874819

875820
SILValue SILGenFunction::emitGetCurrentExecutor(SILLocation loc) {
876-
assert(ExpectedExecutor && "prolog failed to set up expected executor?");
877-
return ExpectedExecutor;
821+
// If this is an actor method, then the actor is the only executor we should
822+
// be running on (if we aren't setting up for a cross-actor call).
823+
if (ExpectedExecutor)
824+
return ExpectedExecutor;
825+
826+
// Otherwise, we'll have to ask the current task what executor it's running
827+
// on.
828+
auto &ctx = getASTContext();
829+
return B.createBuiltin(
830+
loc,
831+
ctx.getIdentifier(getBuiltinName(BuiltinValueKind::GetCurrentExecutor)),
832+
getLoweredType(OptionalType::get(ctx.TheExecutorType)),
833+
SubstitutionMap(), { });
878834
}
879835

880836
static void emitIndirectResultParameters(SILGenFunction &SGF,

test/Concurrency/Runtime/class_resilience.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
// REQUIRES: concurrency_runtime
1616
// UNSUPPORTED: back_deployment_runtime
1717

18+
// XFAIL: windows
19+
// XFAIL: openbsd
20+
1821
import StdlibUnittest
1922
import resilient_class
2023

test/Concurrency/Runtime/protocol_resilience.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
// REQUIRES: concurrency_runtime
1616
// UNSUPPORTED: back_deployment_runtime
1717

18+
// XFAIL: windows
19+
// UNSUPPORTED: linux
20+
// UNSUPPORTED: openbsd
21+
1822
import StdlibUnittest
1923
import resilient_protocol
2024

test/Concurrency/cross_module_let_sil.swift

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import OtherActors
77

88
// CHECK-LABEL: sil hidden [ossa] @$s4test6check1ySi11OtherActors0C11ModuleActorCYaF : $@convention(thin) @async (@guaranteed OtherModuleActor) -> Int {
99
// CHECK: bb0([[SELF:%[0-9]+]] : @guaranteed $OtherModuleActor):
10-
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
11-
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
1210
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $OtherModuleActor, #OtherModuleActor.a
11+
// CHECK: [[OLD:%[0-9]+]] = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
1312
// CHECK: hop_to_executor [[SELF]] : $OtherModuleActor
1413
// CHECK-NEXT: load [trivial] [[REF]]
15-
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
14+
// CHECK-NEXT: hop_to_executor [[OLD]] : $Optional<Builtin.Executor>
1615
// CHECK: } // end sil function '$s4test6check1ySi11OtherActors0C11ModuleActorCYaF'
1716
func check1(_ actor: OtherModuleActor) async -> Int {
1817
return await actor.a
@@ -22,25 +21,20 @@ func check2(_ actor: isolated OtherModuleActor) -> Int {
2221
return actor.a
2322
}
2423

25-
// CHECK-LABEL: sil hidden [ossa] @$s4test6check3ySi11OtherActors0C11ModuleActorCYaF : $@convention(thin) @async (@guaranteed OtherModuleActor) -> Int {
26-
// CHECK: bb0([[SELF:%[0-9]+]] : @guaranteed $OtherModuleActor):
27-
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
28-
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
2924
func check3(_ actor: OtherModuleActor) async -> Int {
3025
return actor.b
3126
}
3227

3328
// CHECK-LABEL: sil hidden [ossa] @$s4test6check4y11OtherActors17SomeSendableClassCSgAC0C11ModuleActorCSgYaF : $@convention(thin) @async (@guaranteed Optional<OtherModuleActor>) -> @owned Optional<SomeSendableClass> {
3429
// CHECK: bb0({{%[0-9]+}} : @guaranteed $Optional<OtherModuleActor>):
35-
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
36-
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
3730
// CHECK: switch_enum {{%[0-9]+}} : $Optional<OtherModuleActor>, case #Optional.some!enumelt: [[SOME:bb[0-9]+]], case #Optional.none!enumelt: {{bb[0-9]+}}
3831

3932
// CHECK: [[SOME]]({{%[0-9]+}} : @owned $OtherModuleActor):
4033
// CHECK: [[REF:%[0-9]+]] = ref_element_addr {{%[0-9]+}} : $OtherModuleActor, #OtherModuleActor.d
34+
// CHECK: [[OLD:%[0-9]+]] = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
4135
// CHECK: hop_to_executor {{%[0-9]+}} : $OtherModuleActor
4236
// CHECK-NEXT: load [copy] [[REF]]
43-
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
37+
// CHECK: hop_to_executor [[OLD]] : $Optional<Builtin.Executor>
4438
// CHECK: } // end sil function '$s4test6check4y11OtherActors17SomeSendableClassCSgAC0C11ModuleActorCSgYaF'
4539
func check4(_ actor: OtherModuleActor?) async -> SomeSendableClass? {
4640
return await actor?.d

test/Concurrency/throwing.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
// REQUIRES: concurrency_runtime
77
// UNSUPPORTED: back_deployment_runtime
88

9+
// SR-15252
10+
// XFAIL: OS=windows-msvc
11+
912
import _Concurrency
1013
import StdlibUnittest
1114

0 commit comments

Comments
 (0)