Skip to content

Commit f0f0084

Browse files
committed
[Executors] Clean up how we unwrap the local executor of distributed cusotm actor
1 parent 5c9c059 commit f0f0084

File tree

3 files changed

+32
-41
lines changed

3 files changed

+32
-41
lines changed

include/swift/AST/KnownSDKDecls.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
KNOWN_SDK_FUNC_DECL(Distributed, IsRemoteDistributedActor, "__isRemoteActor")
2323
KNOWN_SDK_FUNC_DECL(Distributed, IsLocalDistributedActor, "__isLocalActor")
24+
KNOWN_SDK_FUNC_DECL(Distributed, GetUnwrapLocalDistributedActorUnownedExecutor, "_getUnwrapLocalDistributedActorUnownedExecutor")
2425

2526
#undef KNOWN_SDK_FUNC_DECL
2627

lib/SILOptimizer/Mandatory/LowerHopToActor.cpp

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "swift/SIL/SILFunction.h"
1616
#include "swift/SIL/Dominance.h"
1717
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
18+
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
1819
#include "swift/SILOptimizer/PassManager/Transforms.h"
1920
#include "llvm/ADT/ScopedHashTable.h"
2021

@@ -49,19 +50,26 @@ namespace {
4950
class LowerHopToActor {
5051
SILFunction *F;
5152
DominanceInfo *Dominance;
53+
SILOptFunctionBuilder &functionBuilder;
5254

5355
/// A map from an actor value to the executor we've derived for it.
5456
llvm::ScopedHashTable<SILValue, SILValue> ExecutorForActor;
5557

5658
bool processHop(HopToExecutorInst *hop);
5759
bool processExtract(ExtractExecutorInst *extract);
5860

59-
SILValue emitGetExecutor(SILBuilderWithScope &B, SILLocation loc,
61+
SILValue emitGetExecutor(SILBuilderWithScope &B,
62+
SILLocation loc,
6063
SILValue actor, bool makeOptional);
6164

6265
public:
63-
LowerHopToActor(SILFunction *f, DominanceInfo *dominance)
64-
: F(f), Dominance(dominance) { }
66+
LowerHopToActor(SILFunction *f,
67+
SILOptFunctionBuilder &FunctionBuilder,
68+
DominanceInfo *dominance)
69+
: F(f),
70+
Dominance(dominance),
71+
functionBuilder(FunctionBuilder)
72+
{ }
6573

6674
/// The entry point to the transformation.
6775
bool run();
@@ -154,28 +162,6 @@ static AccessorDecl *getUnownedExecutorGetter(ASTContext &ctx,
154162
return nullptr;
155163
}
156164

157-
static AccessorDecl *getUnwrapLocalUnownedExecutorGetter(ASTContext &ctx,
158-
ProtocolDecl *actorProtocol) {
159-
for (auto member: actorProtocol->getAllMembers()) { // FIXME: remove this, just go to the extension
160-
if (auto var = dyn_cast<VarDecl>(member)) {
161-
if (var->getName() == ctx.Id__unwrapLocalUnownedExecutor)
162-
return var->getAccessor(AccessorKind::Get);
163-
}
164-
}
165-
166-
for (auto extension: actorProtocol->getExtensions()) {
167-
for (auto member: extension->getAllMembers()) {
168-
if (auto var = dyn_cast<VarDecl>(member)) {
169-
if (var->getName() == ctx.Id__unwrapLocalUnownedExecutor) {
170-
return var->getAccessor(AccessorKind::Get);
171-
}
172-
}
173-
}
174-
}
175-
176-
return nullptr;
177-
}
178-
179165
SILValue LowerHopToActor::emitGetExecutor(SILBuilderWithScope &B,
180166
SILLocation loc, SILValue actor,
181167
bool makeOptional) {
@@ -212,7 +198,7 @@ SILValue LowerHopToActor::emitGetExecutor(SILBuilderWithScope &B,
212198
} else if (actorType->isDistributedActor()) {
213199
auto actorKind = KnownProtocolKind::DistributedActor;
214200
auto actorProtocol = ctx.getProtocol(actorKind);
215-
auto req = getUnwrapLocalUnownedExecutorGetter(ctx, actorProtocol);
201+
auto req = ctx.getGetUnwrapLocalDistributedActorUnownedExecutor();
216202
assert(req && "Distributed library broken");
217203
SILDeclRef fn(req, SILDeclRef::Kind::Func);
218204

@@ -222,12 +208,19 @@ SILValue LowerHopToActor::emitGetExecutor(SILBuilderWithScope &B,
222208

223209
auto subs = SubstitutionMap::get(req->getGenericSignature(),
224210
{actorType}, {actorConf});
225-
auto fnType = F->getModule().Types.getConstantFunctionType(*F, fn);
226211

227-
auto witness =
228-
B.createWitnessMethod(loc, actorType, actorConf, fn,
229-
SILType::getPrimitiveObjectType(fnType));
230-
auto witnessCall = B.createApply(loc, witness, subs, {actor});
212+
// Find the unwrap function
213+
FuncDecl *funcDecl = ctx.getGetUnwrapLocalDistributedActorUnownedExecutor();
214+
assert(funcDecl);
215+
auto funcDeclRef = SILDeclRef(funcDecl, SILDeclRef::Kind::Func);
216+
217+
SILFunction *unwrapExecutorFun =
218+
functionBuilder.getOrCreateFunction(
219+
loc, funcDeclRef, ForDefinition_t::NotForDefinition);
220+
assert(unwrapExecutorFun && "no sil function!");
221+
auto funcRef =
222+
B.createFunctionRef(loc, unwrapExecutorFun);
223+
auto witnessCall = B.createApply(loc, funcRef, subs, {actor});
231224

232225
// The protocol requirement returns an Optional<UnownedSerialExecutor>;
233226
// extract the Builtin.Executor from it.
@@ -286,7 +279,8 @@ class LowerHopToActorPass : public SILFunctionTransform {
286279
void run() override {
287280
auto fn = getFunction();
288281
auto domTree = getAnalysis<DominanceAnalysis>()->get(fn);
289-
LowerHopToActor pass(getFunction(), domTree);
282+
auto functionBuilder = SILOptFunctionBuilder(*this);
283+
LowerHopToActor pass(getFunction(), functionBuilder, domTree);
290284
if (pass.run())
291285
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
292286
}

stdlib/public/Distributed/DistributedActor.swift

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -278,19 +278,15 @@ public protocol DistributedActor: AnyActor, Identifiable, Hashable
278278
/// - Parameter system: `system` which should be used to resolve the `identity`, and be associated with the returned actor
279279
static func resolve(id: ID, using system: ActorSystem) throws -> Self
280280

281-
// FIXME: figure out how to remove this so LowerHopToActor can call the extension method directly on the protocol
282-
@available(SwiftStdlib 5.9, *)
283-
var _unwrapLocalUnownedExecutor: UnownedSerialExecutor { get }
284281
}
285282

286-
287283
@available(SwiftStdlib 5.9, *)
288-
extension DistributedActor {
289-
290-
@available(SwiftStdlib 5.9, *)
291-
public var _unwrapLocalUnownedExecutor: UnownedSerialExecutor {
292-
self.localUnownedExecutor!
284+
public func _getUnwrapLocalDistributedActorUnownedExecutor(_ actor: some DistributedActor) -> UnownedSerialExecutor {
285+
guard let executor = actor.localUnownedExecutor else {
286+
fatalError("Expected distributed actor executor to be not nil!")
293287
}
288+
289+
return executor
294290
}
295291

296292
// ==== Hashable conformance ---------------------------------------------------

0 commit comments

Comments
 (0)