Files
swift-mirror/lib/IRGen/GenDistributed.cpp

136 lines
4.2 KiB
C++

//===--- GenDistributed.cpp - IRGen for distributed features --------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 - 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements IR generation for distributed features.
//
//===----------------------------------------------------------------------===//
#include "GenDistributed.h"
#include "BitPatternBuilder.h"
#include "ClassTypeInfo.h"
#include "ExtraInhabitants.h"
#include "GenDecl.h"
#include "GenProto.h"
#include "GenType.h"
#include "IRGenDebugInfo.h"
#include "IRGenFunction.h"
#include "IRGenModule.h"
#include "LoadableTypeInfo.h"
#include "ScalarPairTypeInfo.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;
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();
auto fn = IGF.IGM.getDistributedActorInitializeRemoteFn();
actorMetatype =
IGF.Builder.CreateBitCast(actorMetatype, IGF.IGM.TypeMetadataPtrTy);
auto call = IGF.Builder.CreateCall(fn, {actorMetatype});
call->setCallingConv(IGF.IGM.SwiftCC);
call->setDoesNotThrow();
auto result = IGF.Builder.CreateBitCast(call, destType);
out.add(result);
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(); }