Skip to content

Commit 1d93818

Browse files
authored
Merge pull request #39787 from ktoso/distributed-func-in-actor-extension
2 parents 668fe4e + e1ae0be commit 1d93818

17 files changed

+92
-61
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ types where the metadata itself has unknown layout.)
217217
global ::= global 'To' // swift-as-ObjC thunk
218218
global ::= global 'TD' // dynamic dispatch thunk
219219
global ::= global 'Td' // direct method reference thunk
220+
global ::= global 'TE' // distributed actor thunk
220221
global ::= global 'TI' // implementation of a dynamic_replaceable function
221222
global ::= global 'Tu' // async function pointer of a function
222223
global ::= global 'TX' // function pointer of a dynamic_replaceable function

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ NODE(DependentProtocolConformanceAssociated)
7070
CONTEXT_NODE(Destructor)
7171
CONTEXT_NODE(DidSet)
7272
NODE(Directness)
73+
NODE(DistributedThunk)
7374
NODE(DynamicAttribute)
7475
NODE(DirectMethodReferenceAttribute)
7576
NODE(DynamicSelf)

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ void ASTMangler::appendSymbolKind(SymbolKind SKind) {
842842
case SymbolKind::DynamicThunk: return appendOperator("TD");
843843
case SymbolKind::SwiftAsObjCThunk: return appendOperator("To");
844844
case SymbolKind::ObjCAsSwiftThunk: return appendOperator("TO");
845-
case SymbolKind::DistributedThunk: return appendOperator("Td");
845+
case SymbolKind::DistributedThunk: return appendOperator("TE");
846846
}
847847
}
848848

lib/Demangling/Demangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ bool swift::Demangle::isFunctionAttr(Node::Kind kind) {
130130
case Node::Kind::OutlinedVariable:
131131
case Node::Kind::OutlinedBridgedMethod:
132132
case Node::Kind::MergedFunction:
133+
case Node::Kind::DistributedThunk:
133134
case Node::Kind::DynamicallyReplaceableFunctionImpl:
134135
case Node::Kind::DynamicallyReplaceableFunctionKey:
135136
case Node::Kind::DynamicallyReplaceableFunctionVar:
@@ -2359,6 +2360,7 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
23592360
case 'O': return createNode(Node::Kind::NonObjCAttribute);
23602361
case 'D': return createNode(Node::Kind::DynamicAttribute);
23612362
case 'd': return createNode(Node::Kind::DirectMethodReferenceAttribute);
2363+
case 'E': return createNode(Node::Kind::DistributedThunk);
23622364
case 'a': return createNode(Node::Kind::PartialApplyObjCForwarder);
23632365
case 'A': return createNode(Node::Kind::PartialApplyForwarder);
23642366
case 'm': return createNode(Node::Kind::MergedFunction);

lib/Demangling/NodePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ class NodePrinter {
558558
case Node::Kind::ProtocolConformanceRefInTypeModule:
559559
case Node::Kind::ProtocolConformanceRefInProtocolModule:
560560
case Node::Kind::ProtocolConformanceRefInOtherModule:
561+
case Node::Kind::DistributedThunk:
561562
case Node::Kind::DynamicallyReplaceableFunctionKey:
562563
case Node::Kind::DynamicallyReplaceableFunctionImpl:
563564
case Node::Kind::DynamicallyReplaceableFunctionVar:
@@ -1986,6 +1987,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
19861987
Printer << "opaque type symbolic reference 0x";
19871988
Printer.writeHex(Node->getIndex());
19881989
return nullptr;
1990+
case Node::Kind::DistributedThunk:
1991+
if (!Options.ShortenThunk) {
1992+
Printer << "distributed thunk for ";
1993+
}
1994+
return nullptr;
19891995
case Node::Kind::DynamicallyReplaceableFunctionKey:
19901996
if (!Options.ShortenThunk) {
19911997
Printer << "dynamically replaceable key for ";

lib/Demangling/OldRemangler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,12 @@ ManglingError Remangler::mangleMergedFunction(Node *node, unsigned depth) {
729729
return ManglingError::Success;
730730
}
731731

732+
ManglingError
733+
Remangler::mangleDistributedThunk(Node *node, unsigned depth) {
734+
Buffer << "TE";
735+
return ManglingError::Success;
736+
}
737+
732738
ManglingError
733739
Remangler::mangleDynamicallyReplaceableFunctionImpl(Node *node,
734740
unsigned depth) {

lib/Demangling/Remangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,7 @@ ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) {
16101610
case Node::Kind::VTableAttribute:
16111611
case Node::Kind::DirectMethodReferenceAttribute:
16121612
case Node::Kind::MergedFunction:
1613+
case Node::Kind::DistributedThunk:
16131614
case Node::Kind::DynamicallyReplaceableFunctionKey:
16141615
case Node::Kind::DynamicallyReplaceableFunctionImpl:
16151616
case Node::Kind::DynamicallyReplaceableFunctionVar:
@@ -2241,6 +2242,12 @@ ManglingError Remangler::mangleMergedFunction(Node *node, unsigned depth) {
22412242
return ManglingError::Success;
22422243
}
22432244

2245+
ManglingError
2246+
Remangler::mangleDistributedThunk(Node *node, unsigned depth) {
2247+
Buffer << "TE";
2248+
return ManglingError::Success;
2249+
}
2250+
22442251
ManglingError
22452252
Remangler::mangleDynamicallyReplaceableFunctionImpl(Node *node,
22462253
unsigned depth) {

lib/IRGen/Linking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ std::string LinkEntity::mangleAsString() const {
477477
}
478478
case Kind::DistributedThunkAsyncFunctionPointer: {
479479
std::string Result = getSILDeclRef().mangle();
480-
Result.append("Td");
480+
Result.append("TE");
481481
Result.append("Tu");
482482
return Result;
483483
}

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,7 @@ static void emitOrDelayFunction(SILGenModule &SGM,
11441144
auto linkage = constant.getLinkage(ForDefinition);
11451145
bool mayDelay = !forceEmission &&
11461146
(constant.isImplicit() &&
1147+
!constant.isDynamicallyReplaceable() &&
11471148
!isPossiblyUsedExternally(linkage, SGM.M.isWholeModule()));
11481149

11491150
// Avoid emitting a delayable definition if it hasn't already been referenced.

lib/SILGen/SILGenDistributed.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,20 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
951951
auto nativeFnSILTy = SILType::getPrimitiveObjectType(nativeMethodTy);
952952
auto nativeSilFnType = nativeFnSILTy.castTo<SILFunctionType>();
953953

954-
SILValue nativeFn = emitClassMethodRef(
954+
bool isClassMethod = false;
955+
if (auto classDecl = dyn_cast<ClassDecl>(fd->getDeclContext())) {
956+
if (!classDecl->isFinal() && !fd->isFinal() &&
957+
!fd->hasForcedStaticDispatch())
958+
isClassMethod = true;
959+
}
960+
961+
SILValue nativeFn;
962+
if (isClassMethod) {
963+
nativeFn = emitClassMethodRef(
955964
loc, params[params.size() - 1], native, nativeMethodTy);
965+
} else {
966+
nativeFn = emitGlobalFunctionRef(loc, native);
967+
}
956968
auto subs = F.getForwardingSubstitutionMap();
957969

958970
if (nativeSilFnType->hasErrorResult()) {

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,24 +137,23 @@ static Identifier makeRemoteFuncIdentifier(FuncDecl* distributedFunc) {
137137
///
138138
/// and is intended to be replaced by a transport library by providing an
139139
/// appropriate @_dynamicReplacement function.
140-
AbstractFunctionDecl *TypeChecker::addImplicitDistributedActorRemoteFunction(
141-
ClassDecl *decl, AbstractFunctionDecl *AFD) {
142-
if (!decl->isDistributedActor())
140+
static AbstractFunctionDecl *addImplicitDistributedActorRemoteFunction(
141+
DeclContext *parentDC, AbstractFunctionDecl *AFD) {
142+
auto nominal = parentDC->getSelfNominalTypeDecl();
143+
if (!nominal || !nominal->isDistributedActor())
143144
return nullptr;
144145

145146
auto func = dyn_cast<FuncDecl>(AFD);
146147
if (!func || !func->isDistributed())
147148
return nullptr;
148149

149150
// ==== if the remote func already exists, return it
150-
if (auto existing = decl->lookupDirectRemoteFunc(func))
151+
if (auto existing = nominal->lookupDirectRemoteFunc(func))
151152
return existing;
152153

153154
// ==== Synthesize and add 'remote' func to the actor decl
154155

155-
auto &C = decl->getASTContext();
156-
auto parentDC = decl;
157-
156+
auto &C = func->getASTContext();
158157
auto remoteFuncIdent = makeRemoteFuncIdentifier(func);
159158

160159
auto params = ParameterList::clone(C, func->getParameters());
@@ -189,7 +188,24 @@ AbstractFunctionDecl *TypeChecker::addImplicitDistributedActorRemoteFunction(
189188
// same access control as the original function is fine
190189
remoteFuncDecl->copyFormalAccessFrom(func, /*sourceIsParentContext=*/false);
191190

192-
decl->addMember(remoteFuncDecl);
191+
cast<IterableDeclContext>(parentDC->getAsDecl())->addMember(remoteFuncDecl);
193192

194193
return remoteFuncDecl;
195194
}
195+
196+
AbstractFunctionDecl *GetDistributedRemoteFuncRequest::evaluate(
197+
Evaluator &evaluator, AbstractFunctionDecl *func) const {
198+
199+
if (!func->isDistributed())
200+
return nullptr;
201+
202+
auto &C = func->getASTContext();
203+
DeclContext *DC = func->getDeclContext();
204+
205+
// not via `ensureDistributedModuleLoaded` to avoid generating a warning,
206+
// we won't be emitting the offending decl after all.
207+
if (!C.getLoadedModule(C.Id_Distributed))
208+
return nullptr;
209+
210+
return addImplicitDistributedActorRemoteFunction(DC, func);
211+
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2820,10 +2820,11 @@ static ArrayRef<Decl *> evaluateMembersRequest(
28202820
(void) var->getPropertyWrapperAuxiliaryVariables();
28212821
(void) var->getPropertyWrapperInitializerInfo();
28222822
}
2823+
}
28232824

2824-
if (auto *func = dyn_cast<FuncDecl>(member)) {
2825-
(void) func->getDistributedActorRemoteFuncDecl();
2826-
}
2825+
// For a distributed function, add the remote function.
2826+
if (auto *func = dyn_cast<FuncDecl>(member)) {
2827+
(void) func->getDistributedActorRemoteFuncDecl();
28272828
}
28282829
}
28292830

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,36 +71,6 @@ bool IsDistributedActorRequest::evaluate(
7171
return classDecl->isExplicitDistributedActor();
7272
}
7373

74-
AbstractFunctionDecl *GetDistributedRemoteFuncRequest::evaluate(
75-
Evaluator &evaluator, AbstractFunctionDecl *func) const {
76-
77-
if (!func->isDistributed())
78-
return nullptr;
79-
80-
auto &C = func->getASTContext();
81-
DeclContext *DC = func->getDeclContext();
82-
83-
// not via `ensureDistributedModuleLoaded` to avoid generating a warning,
84-
// we won't be emitting the offending decl after all.
85-
if (!C.getLoadedModule(C.Id_Distributed))
86-
return nullptr;
87-
88-
// Locate the actor decl that the member must be synthesized to.
89-
// TODO(distributed): should this just be added to the extension instead when we're in one?
90-
ClassDecl *decl = dyn_cast<ClassDecl>(DC);
91-
if (!decl) {
92-
if (auto ED = dyn_cast<ExtensionDecl>(DC)) {
93-
decl = dyn_cast<ClassDecl>(ED->getExtendedNominal());
94-
}
95-
}
96-
97-
/// A distributed func cannot be added to a non-distributed actor;
98-
/// If the 'decl' was not a distributed actor we must have declared and
99-
/// requested it from a illegal context, let's just ignore the synthesis.
100-
assert(decl && "Can't find actor detect to add implicit _remote function to");
101-
return TypeChecker::addImplicitDistributedActorRemoteFunction(decl, func);
102-
}
103-
10474
// ==== ------------------------------------------------------------------------
10575

10676
/// Check whether the function is a proper distributed function
@@ -150,7 +120,7 @@ bool swift::checkDistributedFunction(FuncDecl *func, bool diagnose) {
150120
}
151121

152122
// === Check _remote functions
153-
ClassDecl *actorDecl = dyn_cast<ClassDecl>(func->getParent());
123+
auto actorDecl = func->getParent()->getSelfNominalTypeDecl();
154124
assert(actorDecl && actorDecl->isDistributedActor());
155125

156126
// _remote function for a distributed function must not be implemented by end-users,
@@ -252,10 +222,6 @@ void TypeChecker::checkDistributedActor(ClassDecl *decl) {
252222
// --- Check all constructors
253223
if (auto ctor = dyn_cast<ConstructorDecl>(member))
254224
checkDistributedActorConstructor(decl, ctor);
255-
256-
// --- synthesize _remote functions for distributed functions
257-
if (auto func = dyn_cast<FuncDecl>(member))
258-
(void)addImplicitDistributedActorRemoteFunction(decl, func);
259225
}
260226

261227
// ==== Properties

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -499,14 +499,6 @@ bool checkContextualRequirements(GenericTypeDecl *decl,
499499
/// struct, class or actor.
500500
void addImplicitConstructors(NominalTypeDecl *typeDecl);
501501

502-
/// Synthesize and add a '_remote' counterpart of the passed in `func` to `decl`.
503-
///
504-
/// \param decl the actor type to add the '_remote' definition to
505-
/// \param func the 'distributed func' that the '_remote' func should mirror
506-
/// \return the synthesized function
507-
AbstractFunctionDecl *addImplicitDistributedActorRemoteFunction(
508-
ClassDecl* decl, AbstractFunctionDecl *func);
509-
510502
/// Fold the given sequence expression into an (unchecked) expression
511503
/// tree.
512504
Expr *foldSequence(SequenceExpr *expr, DeclContext *dc);

test/Demangle/Inputs/manglings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,4 @@ $sSIxip6foobarP ---> foobar in Swift.DefaultIndices.subscript : A
420420
$s13__lldb_expr_110$10016c2d8yXZ1B10$10016c2e0LLC ---> __lldb_expr_1.(unknown context at $10016c2d8).(B in $10016c2e0)
421421
$s__TJO ---> $s__TJO
422422
$s6Foobar7Vector2VAASdRszlE10simdMatrix5scale6rotate9translateSo0C10_double3x3aACySdG_SdAJtFZ0D4TypeL_aySd__GD ---> MatrixType #1 in static (extension in Foobar):Foobar.Vector2<Swift.Double><A where A == Swift.Double>.simdMatrix(scale: Foobar.Vector2<Swift.Double>, rotate: Swift.Double, translate: Foobar.Vector2<Swift.Double>) -> __C.simd_double3x3
423+
$s17distributed_thunk2DAC1fyyFTE ---> distributed thunk for distributed_thunk.DA.f() -> ()

test/SILGen/distributed_thunk.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-emit-silgen %s -enable-experimental-distributed -disable-availability-checking | %FileCheck %s --dump-input=fail
2+
// REQUIRES: concurrency
3+
// REQUIRES: distributed
4+
5+
import _Distributed
6+
7+
distributed actor DA { }
8+
9+
extension DA {
10+
// CHECK-LABEL: sil hidden [thunk] [ossa] @$s17distributed_thunk2DAC1fyyFTE : $@convention(method) @async (@guaranteed DA) -> @error Error
11+
// CHECK: function_ref @swift_distributed_actor_is_remote
12+
13+
// Call the actor function
14+
// CHECK: function_ref @$s17distributed_thunk2DAC1fyyF : $@convention(method) (@guaranteed DA) -> ()
15+
16+
// ... or the remote thunk
17+
// CHECK: dynamic_function_ref @$s17distributed_thunk2DAC9_remote_fyyYaKF : $@convention(method) @async (@guaranteed DA) -> @error Error
18+
distributed func f() { }
19+
}

test/TBD/distributed.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
import _Distributed
1010

11-
// CHECK: @"$s4test1AC13_remote_helloyyYaKFTd" = hidden global %swift.async_func_pointer
12-
// CHECK: @"$s4test1AC13_remote_helloyyYaKFTdTu" = hidden global %swift.async_func_pointer
11+
// CHECK: @"$s4test1AC13_remote_helloyyYaKFTE" = hidden global %swift.async_func_pointer
12+
// CHECK: @"$s4test1AC13_remote_helloyyYaKFTETu" = hidden global %swift.async_func_pointer
1313
distributed actor SomeDistributedActor {
1414
distributed func hello(name: String) -> String {
1515
"Hello, \(name)!"
@@ -21,6 +21,6 @@ distributed actor SomeDistributedActor {
2121
// function method descriptor
2222
// IR unmangledName = $s4test20SomeDistributedActorC5hello4nameS2S_tFTq
2323
// thunk, method reference
24-
// IR unmangledName = $s4test20SomeDistributedActorC5hello4nameS2S_tFTd
24+
// IR unmangledName = $s4test20SomeDistributedActorC5hello4nameS2S_tFTE
2525
// thunk, method reference + async function pointer
26-
// IR unmangledName = $s4test20SomeDistributedActorC5hello4nameS2S_tFTdTu
26+
// IR unmangledName = $s4test20SomeDistributedActorC5hello4nameS2S_tFTETu

0 commit comments

Comments
 (0)