Skip to content

Commit 819a8f2

Browse files
committed
[Distributed] allow hop-to let any: any X where X is DistActor
1 parent 9991d55 commit 819a8f2

File tree

11 files changed

+168
-81
lines changed

11 files changed

+168
-81
lines changed

include/swift/AST/DistributedDecl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class NominalTypeDecl;
3737
Type getConcreteReplacementForProtocolActorSystemType(ValueDecl *member);
3838

3939
/// Determine the `ActorSystem` type for the given actor.
40-
Type getDistributedActorSystemType(NominalTypeDecl *actor);
40+
Type getDistributedActorSystemType(ClassDecl *actor);
4141

4242
/// Determine the `ID` type for the given actor.
4343
Type getDistributedActorIDType(NominalTypeDecl *actor);

lib/AST/ASTContext.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,24 +1258,25 @@ FuncDecl *ASTContext::getEqualIntDecl() const {
12581258
return getBinaryComparisonOperatorIntDecl(*this, "==", getImpl().EqualIntDecl);
12591259
}
12601260

1261-
AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
1262-
NominalTypeDecl *actorOrSystem, bool isVoidReturn) const {
1263-
assert(actorOrSystem && "distributed actor (or system) decl must be provided");
1264-
const NominalTypeDecl *system = actorOrSystem;
1265-
if (actorOrSystem->isDistributedActor()) {
1266-
auto var = actorOrSystem->getDistributedActorSystemProperty();
1267-
system = var->getInterfaceType()->getAnyNominal();
1268-
}
1269-
1270-
if (!system)
1271-
system = getProtocol(KnownProtocolKind::DistributedActorSystem);
1272-
1273-
auto mutableSystem = const_cast<NominalTypeDecl *>(system);
1274-
return evaluateOrDefault(
1275-
system->getASTContext().evaluator,
1276-
GetDistributedActorSystemRemoteCallFunctionRequest{mutableSystem, /*isVoidReturn=*/isVoidReturn},
1277-
nullptr);
1278-
}
1261+
//AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
1262+
// NominalTypeDecl *actorOrSystem, bool isVoidReturn) const {
1263+
// assert(actorOrSystem && "distributed actor (or system) decl must be provided");
1264+
// const NominalTypeDecl *system = actorOrSystem;
1265+
// if (actorOrSystem->isDistributedActor()) {
1266+
//
1267+
// auto var = actorOrSystem->getDistributedActorSystemProperty();
1268+
// system = var->getInterfaceType()->getAnyNominal();
1269+
// }
1270+
//
1271+
// if (!system)
1272+
// system = getProtocol(KnownProtocolKind::DistributedActorSystem);
1273+
//
1274+
// auto mutableSystem = const_cast<NominalTypeDecl *>(system);
1275+
// return evaluateOrDefault(
1276+
// system->getASTContext().evaluator,
1277+
// GetDistributedActorSystemRemoteCallFunctionRequest{mutableSystem, /*isVoidReturn=*/isVoidReturn},
1278+
// nullptr);
1279+
//}
12791280

12801281
FuncDecl *ASTContext::getMakeInvocationEncoderOnDistributedActorSystem(
12811282
AbstractFunctionDecl *thunk) const {

lib/AST/DistributedDecl.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,18 @@ Type swift::getConcreteReplacementForProtocolActorSystemType(ValueDecl *member)
7070
auto *DC = member->getDeclContext();
7171
auto DA = C.getDistributedActorDecl();
7272

73-
if (auto *protocol = DC->getSelfProtocolDecl()) {
73+
// === When declared inside a n actor, we can get the type directly
74+
if (auto classDecl = dyn_cast<ClassDecl>(DC)) {
75+
return getDistributedActorSystemType(classDecl);
76+
}
77+
78+
/// === Maybe the value is declared in a protocol?
79+
ProtocolDecl *protocol = dyn_cast<ProtocolDecl>(member);
80+
if (!protocol) {
81+
protocol = DC->getSelfProtocolDecl();
82+
}
83+
84+
if (protocol) {
7485
GenericSignature signature;
7586
if (auto *genericContext = member->getAsGenericContext()) {
7687
signature = genericContext->getGenericSignature();
@@ -84,30 +95,25 @@ Type swift::getConcreteReplacementForProtocolActorSystemType(ValueDecl *member)
8495
auto systemTy = signature->getConcreteType(ActorSystemAssocType);
8596
assert(systemTy && "couldn't find concrete type for actor system");
8697
return systemTy;
87-
} else if (auto classDecl = dyn_cast<ClassDecl>(DC)) {
88-
if (!classDecl)
89-
return Type();
90-
91-
return getDistributedActorSystemType(classDecl);
9298
}
9399

94100
llvm_unreachable("Unable to fetch ActorSystem type!");
95101
}
96102

97-
Type swift::getDistributedActorSystemType(NominalTypeDecl *nominal) {
98-
assert(!isa<ProtocolDecl>(nominal) && "FIXME: we should deal with it here too or collapse the two impls");
99-
assert(nominal->isDistributedActor());
100-
auto &C = nominal->getASTContext();
101-
auto *DC = nominal->getDeclContext();
103+
Type swift::getDistributedActorSystemType(ClassDecl *actor) {
104+
// assert(!isa<ProtocolDecl>(nominal) && "FIXME: we should deal with it here too or collapse the two impls");
105+
assert(actor->isDistributedActor());
106+
auto &C = actor->getASTContext();
107+
auto *DC = actor->getDeclContext();
102108

103-
auto DAP = C.getDistributedActorDecl();
104-
if (!DAP)
109+
auto DA = C.getDistributedActorDecl();
110+
if (!DA)
105111
return ErrorType::get(C);
106112

107113
// Dig out the actor system type.
108-
auto module = nominal->getParentModule();
109-
Type selfType = nominal->getSelfInterfaceType();
110-
auto conformance = module->lookupConformance(selfType, DAP);
114+
auto module = actor->getParentModule();
115+
Type selfType = actor->getSelfInterfaceType();
116+
auto conformance = module->lookupConformance(selfType, DA);
111117
return conformance.getTypeWitnessByName(selfType, C.Id_ActorSystem);
112118
}
113119

@@ -1055,6 +1061,31 @@ NominalTypeDecl::getDistributedRemoteCallTargetInitFunction() const {
10551061
GetDistributedRemoteCallTargetInitFunctionRequest(mutableThis), nullptr);
10561062
}
10571063

1064+
AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
1065+
NominalTypeDecl *actorOrSystem, bool isVoidReturn) const {
1066+
assert(actorOrSystem && "distributed actor (or system) decl must be provided");
1067+
const NominalTypeDecl *system = actorOrSystem;
1068+
if (actorOrSystem->isDistributedActor()) {
1069+
auto systemTy = getConcreteReplacementForProtocolActorSystemType(actorOrSystem);
1070+
fprintf(stderr, "[%s:%d] (%s) systemTy\n", __FILE__, __LINE__, __FUNCTION__);
1071+
systemTy.dump();
1072+
1073+
system = systemTy->getNominalOrBoundGenericNominal();
1074+
system->dump();
1075+
// auto var = actorOrSystem->getDistributedActorSystemProperty();
1076+
// system = var->getInterfaceType()->getAnyNominal();
1077+
}
1078+
1079+
if (!system)
1080+
system = getProtocol(KnownProtocolKind::DistributedActorSystem);
1081+
1082+
auto mutableSystem = const_cast<NominalTypeDecl *>(system);
1083+
return evaluateOrDefault(
1084+
system->getASTContext().evaluator,
1085+
GetDistributedActorSystemRemoteCallFunctionRequest{mutableSystem, /*isVoidReturn=*/isVoidReturn},
1086+
nullptr);
1087+
}
1088+
10581089
/******************************************************************************/
10591090
/********************** Distributed Actor Properties **************************/
10601091
/******************************************************************************/

lib/SILGen/SILGenDistributed.cpp

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static SILValue emitActorPropertyOrWitnessReference(
7070
SILLocation loc, SILValue base,
7171
NominalTypeDecl *selfTyDecl,
7272
SILType propertyType, Identifier identifier) {
73+
fprintf(stderr, "[%s:%d] (%s) emitActorPropertyOrWitnessReference !!!\n", __FILE__, __LINE__, __FUNCTION__);
7374
/// If we're a class, just get the local property VarDecl and refer to it
7475
if (auto clazz = dyn_cast<ClassDecl>(selfTyDecl)) {
7576
return emitActorPropertyReference(
@@ -127,9 +128,8 @@ static SILValue emitActorPropertyOrWitnessReference(
127128

128129
// === Make a reference to the getter
129130
// --- buffer for the system to be stored
130-
Optional<SILValue> temporaryResultBuffer;
131131
auto buf = B.createAllocStack(loc, propertyType, None);
132-
temporaryResultBuffer = SILValue(buf);
132+
SILValue temporaryResultBuffer = SILValue(buf);
133133

134134
// %5 = witness_method $Self, #DistributedActor.actorSystem!getter : <Self where Self : DistributedActor> (Self) -> () -> Self.ActorSystem : $@convention(witness_method: DistributedActor) <τ_0_0 where τ_0_0 : DistributedActor> (@in_guaranteed τ_0_0) -> @out τ_0_0.ActorSystem
135135
auto witnessMethod = B.createWitnessMethod(
@@ -163,27 +163,35 @@ static SILValue emitActorPropertyOrWitnessReference(
163163
subs = SubstitutionMap::get(genericSig, subTypes, subConformances);
164164
}
165165

166-
SmallVector<SILValue, 2> allArgs;
167-
if (temporaryResultBuffer.hasValue()) {
168-
allArgs.push_back(temporaryResultBuffer.getValue());
169-
}
170-
allArgs.push_back(base); // self
166+
SmallVector<SILValue, 2> allArgs = {
167+
temporaryResultBuffer, // buffer for the property to be read into
168+
base, // self
169+
};
171170

172171
// --- Apply the getter
173172
// %6 = apply %5<Self>(%4, %2) : $@convention(witness_method: DistributedActor) <τ_0_0 where τ_0_0 : DistributedActor> (@in_guaranteed τ_0_0) -> @out τ_0_0.ActorSystem
174173
auto apply = B.createApply( loc, witnessMethod, subs, allArgs);
175174
apply->dump();
176175

176+
177+
178+
auto loadedProperty = B.emitLoadValueOperation(loc, temporaryResultBuffer, LoadOwnershipQualifier::Take);
179+
fprintf(stderr, "[%s:%d] (%s) THE LOAD TAKE\n", __FILE__, __LINE__, __FUNCTION__);
180+
loadedProperty->dump();
181+
182+
// SGF.enterDestroyCleanup(loadedProperty);
183+
SGF.enterDeallocStackCleanup(temporaryResultBuffer);
184+
177185
// --- Cleanup base buffer
178-
if (temporaryResultBuffer) {
179-
auto value = B.emitLoadValueOperation(
180-
loc, *temporaryResultBuffer, LoadOwnershipQualifier::Take);
181-
B.emitDestroyValueOperation(loc, value);
182-
B.createDeallocStack(loc, *temporaryResultBuffer);
183-
}
186+
// if (temporaryResultBuffer) {
187+
// auto value = B.emitLoadValueOperation(
188+
// loc, *temporaryResultBuffer, LoadOwnershipQualifier::Take);
189+
// B.emitDestroyValueOperation(loc, value);
190+
// B.createDeallocStack(loc, *temporaryResultBuffer);
191+
// }
184192

185193
// %7 = load [trivial] %4 : $*SYSTEM_IMPL
186-
return B.emitLoadValueOperation(loc, *temporaryResultBuffer, LoadOwnershipQualifier::Take);
194+
return loadedProperty;
187195
}
188196

189197
llvm_unreachable("Unsupported self type decl!");
@@ -956,29 +964,31 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
956964
// %4 = alloc_stack $SYSTEM_IMPL // users: %9, %7, %6
957965
// %5 = witness_method $Self, #DistributedActor.actorSystem!getter : <Self where Self : DistributedActor> (Self) -> () -> Self.ActorSystem : $@convention(witness_method: DistributedActor) <τ_0_0 where τ_0_0 : DistributedActor> (@in_guaranteed τ_0_0) -> @out τ_0_0.ActorSystem // user: %6
958966
// %6 = apply %5<Self>(%4, %2) : $@convention(witness_method: DistributedActor) <τ_0_0 where τ_0_0 : DistributedActor> (@in_guaranteed τ_0_0) -> @out τ_0_0.ActorSystem
967+
fprintf(stderr, "[%s:%d] (%s) GET PROP FOR MAKE INVOCATIOn\n", __FILE__, __LINE__, __FUNCTION__);
959968
auto systemRef = emitActorPropertyOrWitnessReference(
960969
*this, B, loc,
961970
selfValue.getValue(), selfTyDecl,
962971
systemSILTy, ctx.Id_actorSystem);
963972
assert(systemRef && "Could not find actorSystem property or requirement");
964-
973+
fprintf(stderr, "[%s:%d] (%s) SYSTEM REF\n", __FILE__, __LINE__, __FUNCTION__);
974+
systemRef->dump();
965975
auto actorSystemTy = systemRef->getType();
966976

967977
// FIXME: this is wrong for struct with values, and classes?
968978
// %17 = load %16 : $*FakeActorSystem // users: %21, %20, %18
969-
SILValue systemLoaded;
970-
if (actorSystemTy.isAddressOnly(F)) {
971-
assert(false && "isAddressOnly");
972-
} else {
973-
if (actorSystemTy.isAddress()) {
974-
systemLoaded = B.createTrivialLoadOr(
975-
loc, systemRef, LoadOwnershipQualifier::Copy);
976-
} else {
977-
systemLoaded = B.emitCopyValueOperation(loc, systemRef);
978-
// actorSystemTy.dump();
979-
// llvm_unreachable("Cannot support non address actor system here?");
980-
}
981-
}
979+
// SILValue systemLoaded;
980+
// if (actorSystemTy.isAddressOnly(F)) {
981+
// assert(false && "isAddressOnly");
982+
// } else {
983+
// if (actorSystemTy.isAddress()) {
984+
// systemLoaded = B.createTrivialLoadOr(
985+
// loc, systemRef, LoadOwnershipQualifier::Copy);
986+
// } else {
987+
// systemLoaded = B.emitCopyValueOperation(loc, systemRef);
988+
//// actorSystemTy.dump();
989+
//// llvm_unreachable("Cannot support non address actor system here?");
990+
// }
991+
// }
982992

983993
// function_ref FakeActorSystem.makeInvocationEncoder()
984994
// %19 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV21makeInvocationEncoderAA0aG0VyF : $@convention(method) (@guaranteed FakeActorSystem) -> FakeInvocation // user: %20
@@ -991,11 +1001,18 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
9911001
ApplyInst *invocationEncoderValue = B.createApply(
9921002
loc, makeInvocationEncoderFn,
9931003
/*subs=*/SubstitutionMap(),
994-
/*args=*/{systemLoaded});
1004+
// /*args=*/{systemLoaded});
1005+
/*args=*/{systemRef});
1006+
1007+
// if (!systemLoaded->getType().isTrivial(F) ||
1008+
// ((!actorSystemTy.isAddressOnly(F)) && (!actorSystemTy.isAddress()))) {
1009+
// fprintf(stderr, "[%s:%d] (%s) DESTROY\n", __FILE__, __LINE__, __FUNCTION__);
1010+
// B.createDestroyValue(loc, systemLoaded);
1011+
// // B.createEndLifetime(loc, systemLoaded);
1012+
// }
9951013

996-
if (!systemLoaded->getType().isTrivial(F))
997-
B.createDestroyValue(loc, systemLoaded);
998-
// B.createEndLifetime(loc, systemLoaded);
1014+
B.emitDestroyValueOperation(loc, systemRef);
1015+
// B.createDeallocStack(loc, systemRef);
9991016

10001017
// FIXME(distributed): cannot deal with class yet
10011018
// TODO(distributed): make into "emit apropriate store"
@@ -1529,12 +1546,12 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
15291546
// auto systemRef = emitActorPropertyReference(
15301547
// *this, loc, selfValue.getValue(),
15311548
// lookupProperty(selfTyDecl, ctx.Id_actorSystem));
1549+
fprintf(stderr, "[%s:%d] (%s) GET PROP FOR REMOTE CALL\n", __FILE__, __LINE__, __FUNCTION__);
15321550
systemRef = emitActorPropertyOrWitnessReference(
15331551
*this, B, loc,
15341552
selfValue.getValue(), selfTyDecl,
15351553
systemSILTy, ctx.Id_actorSystem);
15361554
assert(systemRef);
1537-
F.dump();
15381555
// remoteCallSystemSelf = B.createTrivialLoadOr(loc, systemRef, LoadOwnershipQualifier::Copy);
15391556

15401557
// --- Prepare 'throwing' type, Error or Never depending on throws of the target
@@ -1672,6 +1689,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
16721689
// B.createDestroyValue(loc, remoteCallSystemSelf);
16731690
// if (remoteCallSystemSelf->getType().isAddress())
16741691
// B.createEndLifetime(loc, remoteCallSystemSelf);
1692+
B.emitDestroyValueOperation(loc, systemRef);
16751693

16761694
B.createEndAccess(loc, invocationEncoderAccess, /*aborted=*/false);
16771695
Cleanups.emitCleanupsForReturn(CleanupLocation(loc), NotForUnwind);
@@ -1695,6 +1713,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
16951713
// B.createDestroyValue(loc, remoteCallSystemSelf);
16961714
// if (remoteCallSystemSelf->getType().isAddress())
16971715
// B.createEndLifetime(loc, remoteCallSystemSelf);
1716+
B.emitDestroyValueOperation(loc, systemRef);
16981717

16991718
Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind);
17001719

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
522522
fd->getResultInterfaceType(), fd->hasThrows(), fd->getThrowsLoc());
523523

524524
if (fd->isDistributedActorFactory()) {
525+
// TODO(distributed): generalize as "emit body synthesized in SIL" marker
525526
// Synthesize the factory function body
526527
emitDistributedActorFactory(fd);
527528
} else {

lib/SILOptimizer/Mandatory/LowerHopToActor.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,29 @@ static bool isDefaultActorType(CanType actorType, ModuleDecl *M,
145145
return false;
146146
}
147147

148-
static bool isDefaultDistributedActorType(CanType actorType) {
149-
if (auto cls = actorType.getClassOrBoundGenericClass())
150-
return cls->isDistributedActor();
148+
static bool isDefaultDistributedActorType(CanType actorType, SILFunction *F) {
149+
auto *DC = F->getDeclContext();
150+
151+
if (auto classDecl = dyn_cast<ClassDecl>(DC)) {
152+
return classDecl->isDistributedActor();
153+
}
154+
155+
auto selfTy = F->getSelfArgument()->getDecl()->getInterfaceType();
156+
if (auto archetype = dyn_cast<PrimaryArchetypeType>(actorType)) {
157+
GenericSignature signature = DC->getGenericSignatureOfContext();
158+
for (auto req : signature.getRequirements()) {
159+
if (req.getFirstType()->isEqual(selfTy)) {
160+
// It is a Self requirement on the actor where decl,
161+
// check if it requires tha it is a distributed actor:
162+
if (auto proto = req.getProtocolDecl()) {
163+
if (proto->inheritsFromDistributedActor()) {
164+
return true;
165+
}
166+
}
167+
}
168+
}
169+
}
170+
151171
return false;
152172
}
153173

@@ -184,8 +204,9 @@ SILValue LowerHopToActor::emitGetExecutor(SILLocation loc, SILValue actor,
184204
// If the actor type is a default actor, go ahead and devirtualize here.
185205
auto module = F->getModule().getSwiftModule();
186206
SILValue unmarkedExecutor;
207+
fprintf(stderr, "[%s:%d] (%s) isDefaultDistributedActorType(actorType) = %d\n", __FILE__, __LINE__, __FUNCTION__, isDefaultDistributedActorType(actorType, F));
187208
if (isDefaultActorType(actorType, module, F->getResilienceExpansion()) ||
188-
isDefaultDistributedActorType(actorType)) {
209+
isDefaultDistributedActorType(actorType, F)) {
189210
auto builtinName = ctx.getIdentifier(
190211
getBuiltinName(BuiltinValueKind::BuildDefaultActorExecutorRef));
191212
auto builtinDecl = cast<FuncDecl>(getBuiltinValueDecl(ctx, builtinName));

lib/SILOptimizer/Utils/DistributedActor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void emitDistributedActorSystemWitnessCall(
6565
auto &C = F.getASTContext();
6666

6767
// Dig out the conformance to DistributedActorSystem.
68-
ProtocolDecl *DAS = C.getDistributedActorDecl();
68+
ProtocolDecl *DAS = C.getDistributedActorSystemDecl();
6969
assert(DAS);
7070
auto systemASTType = base->getType().getASTType();
7171
auto *module = M.getSwiftModule();
@@ -81,6 +81,8 @@ void emitDistributedActorSystemWitnessCall(
8181
OpenedExistentialAccess::Immutable);
8282
}
8383

84+
fprintf(stderr, "[%s:%d] (%s) systemASTType\n", __FILE__, __LINE__, __FUNCTION__);
85+
systemASTType.dump();
8486
if (systemASTType->isTypeParameter() || systemASTType->is<ArchetypeType>()) {
8587
systemConfRef = ProtocolConformanceRef(DAS);
8688
} else {

0 commit comments

Comments
 (0)