Skip to content

Commit 80e6f50

Browse files
committed
[Distributed] IRGen: Use direct reference to decodeNextArgument if decoder is final
1 parent aa44c1d commit 80e6f50

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed

lib/IRGen/GenDistributed.cpp

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ClassTypeInfo.h"
2323
#include "ExtraInhabitants.h"
2424
#include "GenCall.h"
25+
#include "GenClass.h"
2526
#include "GenDecl.h"
2627
#include "GenMeta.h"
2728
#include "GenOpaque.h"
@@ -67,12 +68,17 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
6768
namespace {
6869

6970
struct ArgumentDecoderInfo {
70-
CanSILFunctionType Type;
71-
FunctionPointer Fn;
71+
llvm::Value *Decoder;
7272

73-
/// Given the decoder instance, form a callee to a
74-
/// decode method - `decodeNextArgument`.
75-
Callee getCallee(llvm::Value *decoder) const;
73+
struct {
74+
CanSILFunctionType Type;
75+
FunctionPointer Fn;
76+
} DecodeMethod;
77+
78+
CanSILFunctionType getMethodType() const { return DecodeMethod.Type; }
79+
80+
/// Form a callee to a decode method - `decodeNextArgument`.
81+
Callee getCallee() const;
7682
};
7783

7884
class DistributedAccessor {
@@ -87,10 +93,6 @@ class DistributedAccessor {
8793
/// The asynchronous context associated with this accessor.
8894
AsyncContextLayout AsyncLayout;
8995

90-
/// The argument decoder associated with the distributed actor
91-
/// this accessor belong to.
92-
ArgumentDecoderInfo ArgumentDecoder;
93-
9496
/// The list of all arguments that were allocated on the stack.
9597
SmallVector<StackAddress, 4> AllocatedArguments;
9698

@@ -109,7 +111,7 @@ class DistributedAccessor {
109111
/// the type of argument comes from runtime metadata.
110112
///
111113
/// Returns a pair of aligned offset and value size.
112-
void decodeArgument(unsigned argumentIdx, llvm::Value *decoder,
114+
void decodeArgument(unsigned argumentIdx, const ArgumentDecoderInfo &decoder,
113115
llvm::Value *argumentType, const SILParameterInfo &param,
114116
Explosion &arguments);
115117

@@ -131,10 +133,8 @@ class DistributedAccessor {
131133

132134
Callee getCalleeForDistributedTarget(llvm::Value *self) const;
133135

134-
/// Given a distributed thunk, find argument coder that should
135-
/// could be used to decode argument values to pass to its invocation.
136-
static ArgumentDecoderInfo findArgumentDecoder(IRGenModule &IGM,
137-
SILFunction *thunk);
136+
/// Given an instance of argument decoder, find `decodeNextArgument`.
137+
ArgumentDecoderInfo findArgumentDecoder(llvm::Value *decoder);
138138

139139
/// The result type of the accessor.
140140
SILType getResultType() const;
@@ -247,8 +247,7 @@ DistributedAccessor::DistributedAccessor(IRGenFunction &IGF,
247247
IGM, AccessorType, AccessorType, SubstitutionMap(),
248248
/*suppress generics*/ true,
249249
FunctionPointer::Kind(
250-
FunctionPointer::BasicKind::AsyncFunctionPointer))),
251-
ArgumentDecoder(findArgumentDecoder(IGM, target)) {}
250+
FunctionPointer::BasicKind::AsyncFunctionPointer))) {}
252251

253252
void DistributedAccessor::decodeArguments(llvm::Value *decoder,
254253
llvm::Value *argumentTypes,
@@ -266,6 +265,10 @@ void DistributedAccessor::decodeArguments(llvm::Value *decoder,
266265
argumentTypes =
267266
IGF.Builder.CreateBitCast(argumentTypes, IGM.TypeMetadataPtrPtrTy);
268267

268+
/// The argument decoder associated with the distributed actor
269+
/// this accessor belong to.
270+
ArgumentDecoderInfo decoderInfo = findArgumentDecoder(decoder);
271+
269272
for (unsigned i = 0, n = parameters.size(); i != n; ++i) {
270273
const auto &param = parameters[i];
271274
auto paramTy = param.getSILStorageInterfaceType();
@@ -293,12 +296,12 @@ void DistributedAccessor::decodeArguments(llvm::Value *decoder,
293296
auto *argumentTy = IGF.Builder.CreateLoad(typeLoc, "arg_type");
294297

295298
// Decode and load argument value using loaded type metadata.
296-
decodeArgument(i, decoder, argumentTy, param, arguments);
299+
decodeArgument(i, decoderInfo, argumentTy, param, arguments);
297300
}
298301
}
299302

300303
void DistributedAccessor::decodeArgument(unsigned argumentIdx,
301-
llvm::Value *decoder,
304+
const ArgumentDecoderInfo &decoder,
302305
llvm::Value *argumentType,
303306
const SILParameterInfo &param,
304307
Explosion &arguments) {
@@ -308,7 +311,7 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
308311
// deal with value witness tables are currently hidden in GenOpaque.cpp
309312
llvm::Value *valueSize = emitLoadOfSize(IGF, argumentType);
310313

311-
Callee callee = ArgumentDecoder.getCallee(decoder);
314+
Callee callee = decoder.getCallee();
312315

313316
std::unique_ptr<CallEmission> emission =
314317
getCallEmission(IGF, callee.getSwiftContext(), std::move(callee));
@@ -340,7 +343,7 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
340343

341344
// Load error from the slot to emit an early return if necessary.
342345
{
343-
SILFunctionConventions conv(ArgumentDecoder.Type, IGM.getSILModule());
346+
SILFunctionConventions conv(decoder.getMethodType(), IGM.getSILModule());
344347
SILType errorType =
345348
conv.getSILErrorType(IGM.getMaximalTypeExpansionContext());
346349

@@ -631,26 +634,44 @@ DistributedAccessor::getCalleeForDistributedTarget(llvm::Value *self) const {
631634
}
632635

633636
ArgumentDecoderInfo
634-
DistributedAccessor::findArgumentDecoder(IRGenModule &IGM, SILFunction *thunk) {
635-
auto *actor = getDistributedActorOf(thunk);
637+
DistributedAccessor::findArgumentDecoder(llvm::Value *decoder) {
638+
auto *actor = getDistributedActorOf(Target);
639+
auto expansionContext = IGM.getMaximalTypeExpansionContext();
636640

637641
auto *decodeFn = IGM.Context.getDistributedActorArgumentDecodingMethod(actor);
638642
assert(decodeFn && "no suitable decoder?");
639643

644+
auto *decoderDecl = decodeFn->getDeclContext()->getSelfNominalTypeDecl();
640645
auto methodTy = IGM.getSILTypes().getConstantFunctionType(
641-
IGM.getMaximalTypeExpansionContext(), SILDeclRef(decodeFn));
642-
643-
auto *decodeSIL = IGM.getSILModule().lookUpFunction(SILDeclRef(decodeFn));
644-
auto *fnPtr = IGM.getAddrOfSILFunction(decodeSIL, NotForDefinition,
645-
/*isDynamicallyReplacible=*/false);
646+
expansionContext, SILDeclRef(decodeFn));
646647

647648
auto signature = IGM.getSignature(methodTy, /*useSpecialConvention=*/false);
648649

650+
// If the decoder class is `final`, let's emit a direct reference.
651+
if (decoderDecl->isFinal()) {
652+
auto *decodeSIL = IGM.getSILModule().lookUpFunction(SILDeclRef(decodeFn));
653+
auto *fnPtr = IGM.getAddrOfSILFunction(decodeSIL, NotForDefinition,
654+
/*isDynamicallyReplacible=*/false);
655+
656+
auto methodPtr = FunctionPointer::forDirect(
657+
classifyFunctionPointerKind(decodeSIL), fnPtr,
658+
/*secondaryValue=*/nullptr, signature);
659+
660+
return {.Decoder = decoder,
661+
.DecodeMethod = {.Type = methodTy, .Fn = methodPtr}};
662+
}
663+
664+
auto selfTy = methodTy->getSelfParameter().getSILStorageType(
665+
IGM.getSILModule(), methodTy, expansionContext);
666+
667+
auto *metadata = emitHeapMetadataRefForHeapObject(IGF, decoder, selfTy,
668+
/*suppress cast*/ true);
669+
649670
auto methodPtr =
650-
FunctionPointer::forDirect(classifyFunctionPointerKind(decodeSIL), fnPtr,
651-
/*secondaryValue=*/nullptr, signature);
671+
emitVirtualMethodValue(IGF, metadata, SILDeclRef(decodeFn), methodTy);
652672

653-
return {.Type = methodTy, .Fn = methodPtr};
673+
return {.Decoder = decoder,
674+
.DecodeMethod = {.Type = methodTy, .Fn = methodPtr}};
654675
}
655676

656677
SILType DistributedAccessor::getResultType() const {
@@ -663,7 +684,7 @@ SILType DistributedAccessor::getErrorType() const {
663684
return conv.getSILErrorType(IGM.getMaximalTypeExpansionContext());
664685
}
665686

666-
Callee ArgumentDecoderInfo::getCallee(llvm::Value *decoder) const {
667-
CalleeInfo info(Type, Type, SubstitutionMap());
668-
return {std::move(info), Fn, decoder};
687+
Callee ArgumentDecoderInfo::getCallee() const {
688+
CalleeInfo info(DecodeMethod.Type, DecodeMethod.Type, SubstitutionMap());
689+
return {std::move(info), DecodeMethod.Fn, Decoder};
669690
}

0 commit comments

Comments
 (0)