[IRGen] Add skeleton implementation of distributed method accessor

This commit is contained in:
Pavel Yaskevich
2021-11-19 12:23:17 -08:00
committed by Pavel Yaskevich
parent b8358b26fe
commit 9ebdf36ca6
5 changed files with 123 additions and 4 deletions

View File

@@ -481,6 +481,9 @@ class LinkEntity {
/// name is known.
/// The pointer is a const char* of the name.
KnownAsyncFunctionPointer,
/// The pointer is SILFunction*
DistributedMethodAccessor,
};
friend struct llvm::DenseMapInfo<LinkEntity>;
@@ -1263,6 +1266,15 @@ public:
return entity;
}
static LinkEntity forDistributedMethodAccessor(SILFunction *method) {
LinkEntity entity;
entity.Pointer = method;
entity.SecondaryPointer = nullptr;
entity.Data =
LINKENTITY_SET_FIELD(Kind, unsigned(Kind::DistributedMethodAccessor));
return entity;
}
LinkEntity getUnderlyingEntityForAsyncFunctionPointer() const {
LinkEntity entity;
entity.Pointer = Pointer;
@@ -1341,7 +1353,8 @@ public:
return getKind() == Kind::AsyncFunctionPointer ||
getKind() == Kind::DynamicallyReplaceableFunctionVariable ||
getKind() == Kind::DynamicallyReplaceableFunctionKey ||
getKind() == Kind::SILFunction;
getKind() == Kind::SILFunction ||
getKind() == Kind::DistributedMethodAccessor;
}
SILFunction *getSILFunction() const {

View File

@@ -19,6 +19,7 @@
#include "BitPatternBuilder.h"
#include "ClassTypeInfo.h"
#include "ExtraInhabitants.h"
#include "GenDecl.h"
#include "GenProto.h"
#include "GenType.h"
#include "IRGenDebugInfo.h"
@@ -26,8 +27,11 @@
#include "IRGenModule.h"
#include "LoadableTypeInfo.h"
#include "ScalarPairTypeInfo.h"
#include "swift/AST/ProtocolConformanceRef.h"
#include "swift/ABI/MetadataValues.h"
#include "swift/AST/ExtInfo.h"
#include "swift/AST/ProtocolConformanceRef.h"
#include "swift/IRGen/Linking.h"
#include "swift/SIL/SILFunction.h"
using namespace swift;
using namespace irgen;
@@ -53,3 +57,79 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
return result;
}
namespace {
class DistributedAccessor {
IRGenFunction &IGF;
/// Underlying distributed method for this accessor.
SILFunction *Method;
public:
DistributedAccessor(IRGenFunction &IGF, SILFunction *method);
void emit();
};
} // end namespace
llvm::Function *
IRGenModule::getAddrOfDistributedMethodAccessor(SILFunction *F,
ForDefinition_t forDefinition) {
auto entity = LinkEntity::forDistributedMethodAccessor(F);
llvm::Function *&entry = GlobalFuncs[entity];
if (entry) {
if (forDefinition)
updateLinkageForDefinition(*this, entry, entity);
return entry;
}
auto getParamForArguments = [&]() {
auto ptrType = Context.getUnsafeRawPointerType();
return SILParameterInfo(ptrType->getCanonicalType(),
ParameterConvention::Direct_Guaranteed);
};
// `self` of the distributed actor is going to be passed as an argument
// to this accessor function.
auto extInfo = SILExtInfoBuilder()
.withRepresentation(SILFunctionTypeRepresentation::Thick)
.build();
// Accessor gets argument value buffer and a reference to `self` of
// the actor and produces a call to the distributed thunk.
auto accessorType = SILFunctionType::get(
/*genericSignature=*/nullptr, extInfo, SILCoroutineKind::None,
ParameterConvention::Direct_Guaranteed,
{getParamForArguments()},
/*Yields=*/{},
/*Results=*/{},
/*ErrorResult=*/None,
/*patternSubs=*/SubstitutionMap(),
/*invocationSubs=*/SubstitutionMap(), Context);
Signature signature = getSignature(accessorType);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
return createFunction(*this, link, signature);
}
void IRGenModule::emitDistributedMethodAccessor(SILFunction *method) {
assert(method->isDistributed());
auto *f = getAddrOfDistributedMethodAccessor(method, ForDefinition);
if (!f->isDeclaration())
return;
IRGenFunction IGF(*this, f);
DistributedAccessor(IGF, method).emit();
}
DistributedAccessor::DistributedAccessor(IRGenFunction &IGF,
SILFunction *method)
: IGF(IGF), Method(method) {}
void DistributedAccessor::emit() { IGF.Builder.CreateRetVoid(); }

View File

@@ -1631,6 +1631,12 @@ public:
Address getAddrOfObjCISAMask();
llvm::Function *
getAddrOfDistributedMethodAccessor(SILFunction *F,
ForDefinition_t forDefinition);
void emitDistributedMethodAccessor(SILFunction *method);
/// Retrieve the generic signature for the current generic context, or null if no
/// generic environment is active.
CanGenericSignature getCurGenericContext();

View File

@@ -2199,6 +2199,11 @@ void IRGenSILFunction::emitSILFunction() {
IGM.noteSwiftAsyncFunctionDef();
}
// Generate accessor thunk for the `distributed` method.
if (CurSILFn->isDistributed() && !CurSILFn->isThunk()) {
IGM.emitDistributedMethodAccessor(CurSILFn);
}
// Configure the dominance resolver.
// TODO: consider re-using a dom analysis from the PassManager
// TODO: consider using a cheaper analysis at -O0

View File

@@ -492,11 +492,18 @@ std::string LinkEntity::mangleAsString() const {
Result.append("Tu");
return Result;
}
case Kind::PartialApplyForwarder:
case Kind::PartialApplyForwarder: {
std::string Result;
Result = std::string(static_cast<llvm::Function *>(Pointer)->getName());
return Result;
}
case Kind::DistributedMethodAccessor: {
std::string Result(getSILFunction()->getName());
Result.append("TF");
return Result;
}
}
llvm_unreachable("bad entity kind!");
}
@@ -795,6 +802,7 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
case Kind::KnownAsyncFunctionPointer:
return SILLinkage::PublicExternal;
case Kind::PartialApplyForwarder:
case Kind::DistributedMethodAccessor:
return SILLinkage::Private;
}
llvm_unreachable("bad link entity kind");
@@ -885,6 +893,7 @@ bool LinkEntity::isContextDescriptor() const {
case Kind::CanonicalPrespecializedGenericTypeCachingOnceToken:
case Kind::PartialApplyForwarder:
case Kind::KnownAsyncFunctionPointer:
case Kind::DistributedMethodAccessor:
return false;
}
llvm_unreachable("invalid descriptor");
@@ -1092,7 +1101,8 @@ bool LinkEntity::isWeakImported(ModuleDecl *module) const {
return false;
case Kind::DynamicallyReplaceableFunctionKey:
case Kind::DynamicallyReplaceableFunctionVariable:
case Kind::SILFunction: {
case Kind::SILFunction:
case Kind::DistributedMethodAccessor: {
return getSILFunction()->isWeakImported();
}
@@ -1330,6 +1340,11 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
case Kind::PartialApplyForwarderAsyncFunctionPointer:
return getUnderlyingEntityForAsyncFunctionPointer()
.getDeclContextForEmission();
case Kind::DistributedMethodAccessor: {
auto *methodDC = getSILFunction()->getDeclContext();
return methodDC->getParentModule();
}
}
llvm_unreachable("invalid decl kind");
}