mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[IRGen] Add skeleton implementation of distributed method accessor
This commit is contained in:
committed by
Pavel Yaskevich
parent
b8358b26fe
commit
9ebdf36ca6
@@ -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 {
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user