Skip to content

Commit 8d3c9b0

Browse files
committed
refactor some of SILGen's distributed actor code
1 parent 38e6303 commit 8d3c9b0

File tree

3 files changed

+78
-130
lines changed

3 files changed

+78
-130
lines changed

lib/SILGen/SILGenDestructor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
8181
/// and can remove it from its (weak) lookup tables.
8282
if (cd->isDistributedActor()) {
8383
SILBasicBlock *continueBB = createBasicBlock();
84-
emitDistributedActor_resignAddress(dd, selfValue, continueBB);
84+
emitDistributedActor_resignIdentity(dd, selfValue, continueBB);
8585
B.emitBlock(continueBB);
8686
}
8787

lib/SILGen/SILGenDistributed.cpp

Lines changed: 76 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@
3232
using namespace swift;
3333
using namespace Lowering;
3434

35+
// MARK: Local utility functions
36+
37+
/// Obtain a nominal type's member by name, as a VarDecl.
38+
/// \returns nullptr if the name lookup doesn't resolve to exactly one member,
39+
/// or the subsequent cast to VarDecl failed.
40+
static VarDecl* lookupProperty(NominalTypeDecl *ty, DeclName name) {
41+
auto refs = ty->lookupDirect(name);
42+
if (refs.size() != 1)
43+
return nullptr;
44+
return dyn_cast<VarDecl>(refs.front());
45+
}
46+
3547
/******************************************************************************/
3648
/******************* COMMON (DISTRIBUTED) SIL PATTERNS ************************/
3749
/******************************************************************************/
@@ -70,13 +82,6 @@ static void emitDistributedIfRemoteBranch(SILGenFunction &SGF,
7082
B.createCondBranch(Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB);
7183
}
7284

73-
static VarDecl *lookupActorTransportProperty(ASTContext &C, ClassDecl *cd,
74-
SILValue selfValue) {
75-
auto transportVarDeclRefs = cd->lookupDirect(C.Id_actorTransport);
76-
assert(transportVarDeclRefs.size() == 1);
77-
return dyn_cast<VarDecl>(transportVarDeclRefs.front());
78-
}
79-
8085
/******************************************************************************/
8186
/****************** DISTRIBUTED ACTOR STORAGE INITIALIZATION ******************/
8287
/******************************************************************************/
@@ -117,34 +122,43 @@ getActorTransportArgument(ASTContext& C, SILFunction& F, ConstructorDecl *ctor)
117122
llvm_unreachable("Missing required ActorTransport argument!");
118123
}
119124

120-
/// Synthesize the actorTransport initialization:
121-
///
122-
/// \verbatim
123-
/// self.actorTransport = <<constructor parameter:ActorTransport>>
124-
/// \endverbatim
125-
static void emitDistributedActorStore_transport(
126-
ASTContext& C, SILGenFunction &SGF,
127-
SILValue actorSelf, AbstractFunctionDecl *func,
128-
SILArgument *transportArg) {
129-
auto &B = SGF.B;
125+
/// Perform an initializing store to the given property using the value
126+
/// \param actorSelf the value representing `self` for the actor instance.
127+
/// \param prop the property to be initialized.
128+
/// \param value the value to use when initializing the property.
129+
static void initializeProperty(SILGenFunction &SGF, SILLocation loc,
130+
SILValue actorSelf,
131+
VarDecl* prop, SILArgument *value) {
132+
auto fieldAddr = SGF.B.createRefElementAddr(loc, actorSelf, prop,
133+
SGF.getLoweredType(prop->getInterfaceType()));
134+
SGF.B.createCopyAddr(loc,
135+
/*src*/value,
136+
/*dest*/fieldAddr,
137+
IsNotTake, IsInitialization);
138+
}
130139

131-
auto *dc = func->getDeclContext();
132-
auto classDecl = dc->getSelfClassDecl();
140+
// TODO(distributed): remove this store impl and reuse Store_transport
141+
static void
142+
emitDistributedActor_init_transportStore(
143+
SILGenFunction &SGF,
144+
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
145+
ConstructorDecl *ctor, VarDecl *var) {
146+
auto &C = selfDecl->getASTContext();
147+
auto &B = SGF.B;
148+
auto &F = SGF.F;
149+
150+
auto *dc = ctor->getDeclContext();
133151

134-
auto loc = SILLocation(func);
152+
auto loc = SILLocation(ctor);
135153
loc.markAutoGenerated();
136154

137-
// ==== Prepare the property reference: self.id
138-
auto vars = classDecl->lookupDirect(C.Id_actorTransport);
139-
assert(vars.size() == 1);
140-
auto *var = dyn_cast<VarDecl>(vars.front());
141-
142-
// ----
155+
// ==== Prepare assignment: get the self.transport address
156+
SILValue transportArg = getActorTransportArgument(C, F, ctor);
143157

144158
auto fieldAddr = B.createRefElementAddr(
145-
loc, actorSelf, var,
159+
loc, borrowedSelfArg.getValue(), var,
146160
SGF.getLoweredType(var->getInterfaceType()));
147-
161+
148162
// If the argument is not existential, it will be a concrete type
149163
// that can be erased to that existential.
150164
SILValue transportValue = transportArg;
@@ -161,13 +175,14 @@ static void emitDistributedActorStore_transport(
161175
auto actorTransportProto = C.getProtocol(KnownProtocolKind::ActorTransport);
162176
ProtocolConformanceRef conformances[] = {
163177
module->lookupConformance(concreteFormalType, actorTransportProto) };
164-
ManagedValue mv = SGF.emitExistentialErasure(loc, concreteFormalType,
165-
concreteTL, existentialTL,
166-
C.AllocateCopy(conformances),
167-
SGFContext(),
168-
[&](SGFContext C) -> ManagedValue {
169-
return ManagedValue::forBorrowedRValue(transportArg);
170-
});
178+
ManagedValue mv =
179+
SGF.emitExistentialErasure(loc, concreteFormalType,
180+
concreteTL, existentialTL,
181+
C.AllocateCopy(conformances),
182+
SGFContext(),
183+
[&](SGFContext C) -> ManagedValue {
184+
return ManagedValue::forBorrowedRValue(transportArg);
185+
});
171186
transportValue = mv.getValue();
172187
}
173188

@@ -178,43 +193,6 @@ static void emitDistributedActorStore_transport(
178193
IsNotTake, IsInitialization);
179194
}
180195

181-
/// Synthesize storing the passed in managed identity to the `id` property:
182-
///
183-
/// \verbatim
184-
/// self.id = <<parameter:identity>>
185-
/// \endverbatim
186-
static void emitDistributedActorStore_id(
187-
ASTContext& C, SILGenFunction &SGF,
188-
SILValue actorSelf, AbstractFunctionDecl *func,
189-
SILArgument *identityArg) {
190-
auto &B = SGF.B;
191-
192-
auto &SGM = SGF.SGM;
193-
SILGenFunctionBuilder builder(SGM);
194-
195-
auto *dc = func->getDeclContext();
196-
auto classDecl = dc->getSelfClassDecl();
197-
198-
auto loc = SILLocation(func);
199-
loc.markAutoGenerated();
200-
201-
// ==== Prepare the property reference: self.id
202-
auto vars = classDecl->lookupDirect(C.Id_id);
203-
assert(vars.size() == 1);
204-
auto *var = dyn_cast<VarDecl>(vars.front());
205-
206-
// ==== Prepare assignment
207-
auto fieldAddr = B.createRefElementAddr(
208-
loc, actorSelf, var,
209-
SGF.getLoweredType(var->getInterfaceType()));
210-
211-
// ==== Store the transport
212-
B.createCopyAddr(loc,
213-
/*src*/identityArg,
214-
/*dest*/fieldAddr,
215-
IsNotTake, IsInitialization);
216-
}
217-
218196
/// Synthesize the distributed actor's identity (`id`) initialization:
219197
///
220198
/// \verbatim
@@ -223,8 +201,7 @@ static void emitDistributedActorStore_id(
223201
static void emitDistributedActorStore_init_assignIdentity(
224202
SILGenFunction &SGF,
225203
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
226-
ConstructorDecl *ctor,
227-
Pattern *pattern, VarDecl *var) {
204+
ConstructorDecl *ctor, VarDecl *var) {
228205
auto &C = selfVarDecl->getASTContext();
229206
auto &B = SGF.B;
230207
auto &F = SGF.F;
@@ -345,46 +322,17 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
345322
SILLocation prologueLoc = RegularLocation(ctor);
346323
prologueLoc.markAsPrologue(); // TODO: no idea if this is necessary or makes sense
347324

348-
auto transportTy = C.getActorTransportType();
349-
auto identityProtoTy = C.getActorIdentityType();
350-
auto anyIdentityTy = C.getAnyActorIdentityType();
351-
352-
// ==== Find the stored properties we will initialize
353-
VarDecl *transportMember = nullptr;
354-
VarDecl *idMember = nullptr;
355-
325+
// ==== Initialize Properties.
356326
auto borrowedSelfArg = selfArg.borrow(*this, prologueLoc);
357-
358-
// TODO(distributed): getStoredProperties might be better here, avoid the `break;`
359-
for (auto member : classDecl->getMembers()) {
360-
PatternBindingDecl *pbd = dyn_cast<PatternBindingDecl>(member);
361-
if (!pbd) continue;
362-
if (pbd->isStatic()) continue;
363-
364-
Pattern *pattern = pbd->getPattern(0);
365-
VarDecl *var = pbd->getSingleVar();
366-
if (!var) continue;
367-
368-
if (var->getName() == C.Id_actorTransport &&
369-
var->getInterfaceType()->isEqual(transportTy)) {
370-
transportMember = var;
371-
emitDistributedActorStore_transport(
372-
C, *this, borrowedSelfArg.getValue(), ctor,
373-
getActorTransportArgument(C, F, ctor));
374-
} else if (var->getName() == C.Id_id &&
375-
(var->getInterfaceType()->isEqual(identityProtoTy) ||
376-
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
377-
idMember = var;
378-
emitDistributedActorStore_init_assignIdentity(
379-
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
380-
}
381-
if (transportMember && idMember) {
382-
break; // we found all properties we care about, break out of the loop early
383-
}
384-
}
385-
386-
assert(transportMember && "Missing DistributedActor.actorTransport member");
387-
assert(idMember && "Missing DistributedActor.id member");
327+
328+
VarDecl *transportVar = lookupProperty(classDecl, C.Id_actorTransport);
329+
emitDistributedActor_init_transportStore(*this, borrowedSelfArg, selfVarDecl,
330+
ctor, transportVar);
331+
332+
VarDecl *identityVar = lookupProperty(classDecl, C.Id_id);
333+
emitDistributedActorStore_init_assignIdentity(*this, borrowedSelfArg,
334+
selfVarDecl,
335+
ctor, identityVar);
388336
}
389337

390338
void SILGenFunction::emitDistributedActorReady(
@@ -647,13 +595,17 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
647595
{selfMetatypeValue});
648596

649597
// ==== Initialize distributed actor properties
650-
// --- Store the identity: self.id = identity
651-
emitDistributedActorStore_id(
652-
C, *this, /*actorSelf*/remote, fd, identityArg);
653-
654-
// --- Store the transport: self.actorTransport = transport
655-
emitDistributedActorStore_transport(
656-
C, *this, /*actorSelf*/remote, fd, transportArg);
598+
loc.markAutoGenerated();
599+
auto *dc = fd->getDeclContext();
600+
auto classDecl = dc->getSelfClassDecl();
601+
602+
initializeProperty(*this, loc, remote,
603+
lookupProperty(classDecl, C.Id_id),
604+
identityArg);
605+
606+
initializeProperty(*this, loc, remote,
607+
lookupProperty(classDecl, C.Id_actorTransport),
608+
transportArg);
657609

658610
// ==== Branch to return the fully initialized remote instance
659611
B.createBranch(loc, returnBB, {remote});
@@ -685,10 +637,10 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
685637
}
686638

687639
/******************************************************************************/
688-
/******************* DISTRIBUTED DEINIT: resignAddress ************************/
640+
/******************* DISTRIBUTED DEINIT: resignIdentity ***********************/
689641
/******************************************************************************/
690642

691-
void SILGenFunction::emitDistributedActor_resignAddress(
643+
void SILGenFunction::emitDistributedActor_resignIdentity(
692644
DestructorDecl *dd, SILValue selfValue, SILBasicBlock *continueBB) {
693645
ASTContext &ctx = getASTContext();
694646

@@ -705,17 +657,13 @@ void SILGenFunction::emitDistributedActor_resignAddress(
705657
auto selfTy = selfDecl->getType();
706658

707659
// ==== locate: self.id
708-
auto idVarDeclRefs = cd->lookupDirect(ctx.Id_id);
709-
assert(idVarDeclRefs.size() == 1);
710-
auto *idVarDeclRef = dyn_cast<VarDecl>(idVarDeclRefs.front());
711-
assert(idVarDeclRef);
660+
auto *idVarDeclRef = lookupProperty(cd, ctx.Id_id);
712661
auto idRef =
713662
B.createRefElementAddr(Loc, selfValue, idVarDeclRef,
714663
getLoweredType(idVarDeclRef->getType()));
715664

716665
// ==== locate: self.actorTransport
717-
auto transportVarDeclRef = lookupActorTransportProperty(ctx, cd, selfValue);
718-
666+
auto transportVarDeclRef = lookupProperty(cd, ctx.Id_actorTransport);
719667
auto transportRef =
720668
B.createRefElementAddr(Loc, selfValue, transportVarDeclRef,
721669
getLoweredType(transportVarDeclRef->getType()));

lib/SILGen/SILGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
20232023
SILLocation loc, ConstructorDecl *ctor, ManagedValue actorSelf);
20242024

20252025
/// Inject distributed actor and transport interaction code into the destructor.
2026-
void emitDistributedActor_resignAddress(
2026+
void emitDistributedActor_resignIdentity(
20272027
DestructorDecl *dd, SILValue selfValue, SILBasicBlock *continueBB);
20282028

20292029
void emitDistributedActorClassMemberDestruction(

0 commit comments

Comments
 (0)