Skip to content

Revert "[Distributed] Generate SIL for DistributedActor.resolve" #38994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,

if (Builtin.ID == BuiltinValueKind::InitializeDistributedRemoteActor) {
auto actorMetatype = args.claimNext();
emitDistributedActorInitializeRemote(IGF, resultType, actorMetatype, out);
emitDistributedActorInitializeRemote(IGF, actorMetatype, out);
return;
}

Expand Down
14 changes: 3 additions & 11 deletions lib/IRGen/GenDistributed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "GenDistributed.h"

#include "BitPatternBuilder.h"
#include "ClassTypeInfo.h"
#include "ExtraInhabitants.h"
#include "GenProto.h"
#include "GenType.h"
Expand All @@ -33,12 +32,7 @@ using namespace swift;
using namespace irgen;

llvm::Value *irgen::emitDistributedActorInitializeRemote(
IRGenFunction &IGF, SILType selfType, llvm::Value *actorMetatype, Explosion &out) {
auto &classTI = IGF.getTypeInfo(selfType).as<ClassTypeInfo>();
auto &classLayout = classTI.getClassLayout(IGF.IGM, selfType,
/*forBackwardDeployment=*/false);
llvm::Type *destType = classLayout.getType()->getPointerTo();

IRGenFunction &IGF, llvm::Value *actorMetatype, Explosion &out) {
auto fn = IGF.IGM.getDistributedActorInitializeRemoteFn();
actorMetatype =
IGF.Builder.CreateBitCast(actorMetatype, IGF.IGM.TypeMetadataPtrTy);
Expand All @@ -47,11 +41,9 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
call->setCallingConv(IGF.IGM.SwiftCC);
call->setDoesNotThrow();

auto result = IGF.Builder.CreateBitCast(call, destType);

out.add(result);
out.add(call);

return result;
return call;
}

void irgen::emitDistributedActorDestroy(IRGenFunction &IGF,
Expand Down
1 change: 0 additions & 1 deletion lib/IRGen/GenDistributed.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class IRGenFunction;
/// Emit the '_distributedActorRemoteInitialize' call.
llvm::Value *emitDistributedActorInitializeRemote(
IRGenFunction &IGF,
SILType selfType,
llvm::Value *actorMetatype,
Explosion &out);

Expand Down
216 changes: 20 additions & 196 deletions lib/SILGen/SILGenDistributed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,34 +70,6 @@ static void emitDistributedIfRemoteBranch(SILGenFunction &SGF,
B.createCondBranch(Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB);
}

static AbstractFunctionDecl *lookupActorTransportResolveFunc(ASTContext &C) {
auto transportDecl = C.getActorTransportDecl();

for (auto decl : transportDecl->lookupDirect(DeclName(C.Id_resolve)))
if (auto funcDecl = dyn_cast<AbstractFunctionDecl>(decl))
return funcDecl;

llvm_unreachable("Missing ActorTransport.resolve function");
}

static VarDecl *lookupActorTransportProperty(ASTContext &C, ClassDecl *cd,
SILValue selfValue) {
auto transportVarDeclRefs = cd->lookupDirect(C.Id_actorTransport);
assert(transportVarDeclRefs.size() == 1);
return dyn_cast<VarDecl>(transportVarDeclRefs.front());
}

static EnumElementDecl *lookupEnumCase(ASTContext &C, EnumDecl *target,
Identifier identifier) {
auto elementDecls = target->lookupDirect(DeclName(identifier));
if (elementDecls.empty())
return nullptr;

auto *elementDecl = elementDecls.front();

return dyn_cast<EnumElementDecl>(elementDecl);
}

/******************************************************************************/
/****************** DISTRIBUTED ACTOR STORAGE INITIALIZATION ******************/
/******************************************************************************/
Expand Down Expand Up @@ -148,7 +120,6 @@ static void emitDistributedActorStore_transport(
SILValue actorSelf, AbstractFunctionDecl *func,
SILArgument *transportArg) {
auto &B = SGF.B;

auto &SGM = SGF.SGM;
SILGenFunctionBuilder builder(SGM);

Expand All @@ -164,7 +135,6 @@ static void emitDistributedActorStore_transport(
auto *var = dyn_cast<VarDecl>(vars.front());

// ----

auto fieldAddr = B.createRefElementAddr(
loc, actorSelf, var,
SGF.getLoweredType(var->getInterfaceType()));
Expand Down Expand Up @@ -196,7 +166,6 @@ emitDistributedActor_init_transportStore(
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);

// ----

auto transportFieldAddr = B.createRefElementAddr(
loc, borrowedSelfArg.getValue(), var,
SGF.getLoweredType(var->getInterfaceType()));
Expand All @@ -218,7 +187,6 @@ static void emitDistributedActorStore_id(
SILValue actorSelf, AbstractFunctionDecl *func,
SILArgument *identityArg) {
auto &B = SGF.B;

auto &SGM = SGF.SGM;
SILGenFunctionBuilder builder(SGM);

Expand Down Expand Up @@ -269,9 +237,7 @@ static void emitDistributedActorStore_init_assignIdentity(

// --- Prepare the arguments
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);

ProtocolDecl *distributedActorProto = C.getProtocol(KnownProtocolKind::DistributedActor);

assert(distributedActorProto);
assert(transportProto);

Expand Down Expand Up @@ -416,7 +382,6 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(

void SILGenFunction::emitDistributedActorReady(
ConstructorDecl *ctor, ManagedValue selfArg) {

auto *dc = ctor->getDeclContext();
auto classDecl = dc->getSelfClassDecl();
auto &C = classDecl->getASTContext();
Expand Down Expand Up @@ -497,86 +462,6 @@ void SILGenFunction::emitDistributedActorReady(
/******************* DISTRIBUTED ACTOR RESOLVE FUNCTION ***********************/
/******************************************************************************/

/// Synthesize the distributed actor's identity (`id`) initialization:
///
/// \verbatim
/// transport.resolve(_, as:)
/// \endverbatim
static void createDistributedActorFactory_resolve(
SILGenFunction &SGF, ASTContext &C, FuncDecl *fd, SILValue identityValue,
SILValue transportValue, Type selfTy, SILValue selfMetatypeValue,
SILType resultTy, SILBasicBlock *normalBB, SILBasicBlock *errorBB) {
auto &B = SGF.B;
auto &SGM = SGF.SGM;
auto &F = SGF.F;
SILGenFunctionBuilder builder(SGM);

auto loc = SILLocation(fd);
loc.markAutoGenerated();

ProtocolDecl *distributedActorProto =
C.getProtocol(KnownProtocolKind::DistributedActor);
ProtocolDecl *transportProto =
C.getProtocol(KnownProtocolKind::ActorTransport);
assert(distributedActorProto);
assert(transportProto);

// // --- Open the transport existential
OpenedArchetypeType *Opened;
auto transportASTType = transportValue->getType().getASTType();
auto openedTransportType =
transportASTType->openAnyExistentialType(Opened)->getCanonicalType();
auto openedTransportSILType = F.getLoweredType(openedTransportType);
auto transportArchetypeValue =
B.createOpenExistentialAddr(loc, transportValue, openedTransportSILType,
OpenedExistentialAccess::Immutable);

// --- prepare the witness_method
// Note: it does not matter on what module we perform the lookup,
// it is currently ignored. So the Stdlib module is good enough.
auto *module = SGF.getModule().getSwiftModule();

// the conformance here is just an abstract thing so we can simplify
auto transportConfRef = ProtocolConformanceRef(transportProto);
assert(!transportConfRef.isInvalid() &&
"Missing conformance to `ActorTransport`");

auto distributedActorConfRef =
module->lookupConformance(selfTy, distributedActorProto);
assert(!distributedActorConfRef.isInvalid() &&
"Missing conformance to `DistributedActor`");

auto resolveMethod =
cast<FuncDecl>(transportProto->getSingleRequirement(C.Id_resolve));
auto resolveRef = SILDeclRef(resolveMethod, SILDeclRef::Kind::Func);
auto constantInfo =
SGF.getConstantInfo(SGF.getTypeExpansionContext(), resolveRef);
auto resolveSILTy = constantInfo.getSILType();

auto resolveWitnessMethod =
B.createWitnessMethod(loc,
/*lookupTy*/ openedTransportType,
/*Conformance*/ transportConfRef,
/*member*/ resolveRef,
/*methodTy*/ resolveSILTy);

// // --- prepare conformance subs
auto genericSig = resolveMethod->getGenericSignature();

SubstitutionMap subs =
SubstitutionMap::get(genericSig, {openedTransportType, selfTy},
{transportConfRef, distributedActorConfRef});

// // ---- actually call transport.resolve(id, as: Self.self)

SmallVector<SILValue, 3> params;
params.push_back(identityValue);
params.push_back(selfMetatypeValue);
params.push_back(transportArchetypeValue); // self for the call, as last param

B.createTryApply(loc, resolveWitnessMethod, subs, params, normalBB, errorBB);
}

/// Function body of:
/// \verbatim
/// DistributedActor.resolve(
Expand All @@ -602,66 +487,28 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
assert(
transportArg->getType().getASTType()->isEqual(C.getActorTransportType()));

SILValue selfArgValue = F.getSelfArgument();
ManagedValue selfArg = ManagedValue::forUnmanaged(selfArgValue);

// type: SpecificDistributedActor.Type
auto selfArgType = F.mapTypeIntoContext(selfArg.getType().getASTType());
auto selfMetatype = getLoweredType(selfArgType);
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);

// type: SpecificDistributedActor
// --- Parameter: self
auto *selfTyDecl = fd->getParent()->getSelfNominalTypeDecl();
assert(selfTyDecl->isDistributedActor());
auto selfTy = F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType());
auto returnTy = getLoweredType(selfTy);

// ==== Prepare all the basic blocks
auto returnBB = createBasicBlock();
auto resolvedBB = createBasicBlock();
auto makeProxyBB = createBasicBlock();
auto switchBB = createBasicBlock();
auto errorBB = createBasicBlock();

SILFunctionConventions fnConv = F.getConventions(); // TODO: no idea?

// --- get the uninitialized allocation from the runtime system.
FullExpr scope(Cleanups, CleanupLocation(fd));

auto optionalReturnTy = SILType::getOptionalType(returnTy);

// ==== Call `try transport.resolve(id, as: Self.self)`
{
createDistributedActorFactory_resolve(
*this, C, fd, identityArg, transportArg, selfTy, selfMetatypeValue,
optionalReturnTy, switchBB, errorBB);
}

// ==== switch resolved { ... }
{
B.emitBlock(switchBB);
auto resolve =
switchBB->createPhiArgument(optionalReturnTy, OwnershipKind::Owned);

B.createSwitchEnum(
loc, resolve, nullptr,
{{C.getOptionalSomeDecl(), resolvedBB},
{std::make_pair(C.getOptionalNoneDecl(), makeProxyBB)}});
}
SILValue selfArgValue = F.getSelfArgument();
ManagedValue selfArg = ManagedValue::forUnmanaged(selfArgValue);

// ==== Case 'some') return the resolved instance
// ==== Case 'remote') Create the remote instance
{
B.emitBlock(resolvedBB);

auto local = resolvedBB->createPhiArgument(returnTy, OwnershipKind::Owned);
// ==== Create 'remote' distributed actor instance
// --- Prepare param: Self.self
// type: SpecificDistributedActor
auto returnTy = getLoweredType(
F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()));

B.createBranch(loc, returnBB, {local});
}
// type: SpecificDistributedActor.Type
auto selfMetatype =
getLoweredType(F.mapTypeIntoContext(selfArg.getType().getASTType()));
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);

// ==== Case 'none') Create the remote instance
{
B.emitBlock(makeProxyBB);
// ==== Create 'remote' distributed actor instance
// --- get the uninitialized allocation from the runtime system.
FullExpr scope(Cleanups, CleanupLocation(fd));

// --- Call: _distributedActorRemoteInitialize(Self.self)
auto builtinName = C.getIdentifier(
Expand All @@ -681,32 +528,8 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) {
emitDistributedActorStore_transport(
C, *this, /*actorSelf*/remote, fd, transportArg);

// ==== Branch to return the fully initialized remote instance
B.createBranch(loc, returnBB, {remote});
}

// --- Emit return logic
// return <remote>
{
B.emitBlock(returnBB);

auto local = returnBB->createPhiArgument(returnTy, OwnershipKind::Owned);

Cleanups.emitCleanupsForReturn(CleanupLocation(loc), NotForUnwind);
B.createReturn(loc, local);
}

// --- Emit rethrow logic
// throw error
{
B.emitBlock(errorBB);

auto error = errorBB->createPhiArgument(
fnConv.getSILErrorType(F.getTypeExpansionContext()),
OwnershipKind::Owned);

Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind);
B.createThrow(loc, error);
// ==== Return the fully initialized remote instance
B.createReturn(loc, remote);
}
}

Expand Down Expand Up @@ -740,8 +563,9 @@ void SILGenFunction::emitDistributedActor_resignAddress(
getLoweredType(idVarDeclRef->getType()));

// ==== locate: self.actorTransport
auto transportVarDeclRef = lookupActorTransportProperty(ctx, cd, selfValue);

auto transportVarDeclRefs = cd->lookupDirect(ctx.Id_actorTransport);
assert(transportVarDeclRefs.size() == 1);
auto *transportVarDeclRef = dyn_cast<VarDecl>(transportVarDeclRefs.front());
auto transportRef =
B.createRefElementAddr(Loc, selfValue, transportVarDeclRef,
getLoweredType(transportVarDeclRef->getType()));
Expand Down
7 changes: 3 additions & 4 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,19 +514,18 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
emitProfilerIncrement(fd->getTypecheckedBody());
emitProlog(captureInfo, fd->getParameters(), fd->getImplicitSelfDecl(), fd,
fd->getResultInterfaceType(), fd->hasThrows(), fd->getThrowsLoc());
prepareEpilog(true, fd->hasThrows(), CleanupLocation(fd));

if (fd->isDistributedActorFactory()) {
// Synthesize the factory function body
emitDistributedActorFactory(fd);
} else {
prepareEpilog(true, fd->hasThrows(), CleanupLocation(fd));

// Emit the actual function body as usual
emitStmt(fd->getTypecheckedBody());

emitEpilog(fd);
}

emitEpilog(fd);

mergeCleanupBlocks();
}

Expand Down
8 changes: 7 additions & 1 deletion stdlib/public/Distributed/ActorTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public protocol ActorTransport: Sendable {
///
/// Detecting liveness of such remote actors shall be offered / by transport libraries
/// by other means, such as "watching an actor for termination" or similar.
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type) throws -> Act? // TODO(distributed): make just optional
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type) throws -> ActorResolved<Act> // TODO(distributed): make just optional
where Act: DistributedActor

// ==== ---------------------------------------------------------------------
Expand All @@ -73,3 +73,9 @@ public protocol ActorTransport: Sendable {
func resignIdentity(_ id: AnyActorIdentity)

}

@available(SwiftStdlib 5.5, *)
public enum ActorResolved<Act: DistributedActor> {
case resolved(Act)
case makeProxy
}
Loading