Skip to content

Commit ddcceb3

Browse files
authored
Merge pull request #76880 from rjmccall/actor-delegating-init-isolation
Hop to the current isolation properly in delegating async actor initializers
2 parents 93c647a + af8115f commit ddcceb3

18 files changed

+524
-226
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ ERROR(exclusivity_access_required_unknown_decl_moveonly,none,
111111
NOTE(exclusivity_conflicting_access,none,
112112
"conflicting access is here", ())
113113

114+
ERROR(unsupported_sil_builtin,none,
115+
"builtin '%0' is not supported by SIL generation", (StringRef))
116+
114117
ERROR(unsupported_c_function_pointer_conversion,none,
115118
"C function pointer signature %0 is not compatible with expected type %1",
116119
(Type, Type))

include/swift/SIL/AddressWalker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) && {
276276
case BuiltinValueKind::GetEnumTag:
277277
case BuiltinValueKind::InjectEnumTag:
278278
case BuiltinValueKind::AddressOfRawLayout:
279+
case BuiltinValueKind::FlowSensitiveSelfIsolation:
280+
case BuiltinValueKind::FlowSensitiveDistributedSelfIsolation:
279281
callVisitUse(op);
280282
continue;
281283
default:

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -914,14 +914,33 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, EndAsyncLetLifetime)
914914
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, CreateTaskGroup)
915915
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, CreateTaskGroupWithFlags)
916916
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, DestroyTaskGroup)
917-
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, FlowSensitiveSelfIsolation)
918-
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, FlowSensitiveDistributedSelfIsolation)
919917

920918
BUILTIN_OPERAND_OWNERSHIP(ForwardingConsume, COWBufferForReading)
921919

922920
// This should actually never be seen in SIL
923921
BUILTIN_OPERAND_OWNERSHIP(GuaranteedForwarding, ExtractFunctionIsolation)
924922

923+
static OperandOwnership
924+
visitAnyFlowSensitiveSelfIsolation(BuiltinInst *bi) {
925+
// In potentially-delegating initializers, the operand will be the
926+
// address of the box instead of the actor instance.
927+
auto operand = bi->getOperand(0);
928+
if (operand->getType().isAddress())
929+
return OperandOwnership::TrivialUse;
930+
return OperandOwnership::InstantaneousUse;
931+
}
932+
933+
OperandOwnership
934+
OperandOwnershipBuiltinClassifier
935+
::visitFlowSensitiveSelfIsolation(BuiltinInst *bi, StringRef attr) {
936+
return visitAnyFlowSensitiveSelfIsolation(bi);
937+
}
938+
OperandOwnership
939+
OperandOwnershipBuiltinClassifier
940+
::visitFlowSensitiveDistributedSelfIsolation(BuiltinInst *bi, StringRef attr) {
941+
return visitAnyFlowSensitiveSelfIsolation(bi);
942+
}
943+
925944
OperandOwnership
926945
OperandOwnershipBuiltinClassifier
927946
::visitStartAsyncLetWithLocalBuffer(BuiltinInst *bi, StringRef attr) {

lib/SILGen/SILGenApply.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5709,8 +5709,10 @@ RValue SILGenFunction::emitApply(
57095709
}
57105710

57115711
breadcrumb = emitHopToTargetExecutor(loc, executor);
5712-
} else if (ExpectedExecutor &&
5713-
(substFnType->isAsync() || calleeTypeInfo.foreign.async)) {
5712+
} else if ((substFnType->isAsync() || calleeTypeInfo.foreign.async) &&
5713+
ExpectedExecutor.isNecessary()) {
5714+
assert(F.isAsync());
5715+
57145716
// Otherwise, if we're in an actor method ourselves, and we're calling into
57155717
// any sort of async function, we'll want to make sure to hop back to our
57165718
// own executor afterward, since the callee could have made arbitrary hops

lib/SILGen/SILGenBridging.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,11 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
20902090
if (nativeFnTy->isAsync()) {
20912091
foreignAsync = fd->getForeignAsyncConvention();
20922092
assert(foreignAsync && "couldn't find foreign async convention?!");
2093+
2094+
// We might switch to to the callee's actor as part of making the call,
2095+
// but we don't need to switch back afterwards because we're going to
2096+
// immediately return.
2097+
ExpectedExecutor.setUnnecessary();
20932098
}
20942099
std::optional<ForeignErrorConvention> foreignError;
20952100
if (nativeFnTy->hasErrorResult()) {

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,8 +1493,16 @@ static ManagedValue emitBuiltinEndAsyncLet(
14931493
static ManagedValue emitBuiltinGetCurrentExecutor(
14941494
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
14951495
PreparedArguments &&preparedArgs, SGFContext C) {
1496-
return ManagedValue::forObjectRValueWithoutOwnership(
1497-
SGF.emitGetCurrentExecutor(loc));
1496+
1497+
// We don't support this builtin anymore in SILGen.
1498+
// TODO: just remove it?
1499+
SGF.SGM.diagnose(loc, diag::unsupported_sil_builtin,
1500+
getBuiltinName(BuiltinValueKind::GetCurrentExecutor));
1501+
1502+
auto &ctx = SGF.getASTContext();
1503+
auto executorType = SILType::getPrimitiveObjectType(ctx.TheExecutorType);
1504+
auto optionalExecutorType = SILType::getOptionalType(executorType);
1505+
return SGF.emitUndef(optionalExecutorType);
14981506
}
14991507

15001508
// Emit SIL for sizeof/strideof/alignof.

0 commit comments

Comments
 (0)