Skip to content

Commit 3a754cb

Browse files
committed
[Distributed] IRGen: Find a suitable decoder method to decode argument values
Given a distributed thunk, find and cache a pointer to suitable argument decoder method together with its type. The decoder is a concrete type associated with actor via `InvocationDecoder` associated type on `DistributedActorSystem` which should have a `decodeNextArgument` method.
1 parent 0e03f1e commit 3a754cb

File tree

1 file changed

+56
-4
lines changed

1 file changed

+56
-4
lines changed

lib/IRGen/GenDistributed.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ struct AllocationInfo {
7171
StackAddress Addr;
7272
};
7373

74+
struct ArgumentDecoderInfo {
75+
CanSILFunctionType Type;
76+
FunctionPointer Fn;
77+
78+
/// Given the decoder instance, form a callee to a
79+
/// decode method - `decodeNextArgument`.
80+
Callee getCallee(llvm::Value *decoder) const;
81+
};
82+
7483
class DistributedAccessor {
7584
IRGenModule &IGM;
7685
IRGenFunction &IGF;
@@ -83,6 +92,10 @@ class DistributedAccessor {
8392
/// The asynchronous context associated with this accessor.
8493
AsyncContextLayout AsyncLayout;
8594

95+
/// The argument decoder associated with the distributed actor
96+
/// this accessor belong to.
97+
ArgumentDecoderInfo ArgumentDecoder;
98+
8699
/// The list of all arguments that were allocated on the stack.
87100
SmallVector<AllocationInfo, 4> AllocatedArguments;
88101

@@ -134,20 +147,30 @@ class DistributedAccessor {
134147
FunctionPointer getPointerToTarget() const;
135148

136149
Callee getCalleeForDistributedTarget(llvm::Value *self) const;
150+
151+
/// Given a distributed thunk, find argument coder that should
152+
/// could be used to decode argument values to pass to its invocation.
153+
static ArgumentDecoderInfo findArgumentDecoder(IRGenModule &IGM,
154+
SILFunction *thunk);
137155
};
138156

139157
} // end namespace
140158

159+
static NominalTypeDecl *getDistributedActorOf(SILFunction *thunk) {
160+
assert(thunk->isDistributed() && thunk->isThunk());
161+
return thunk->getDeclContext()
162+
->getInnermostTypeContext()
163+
->getSelfNominalTypeDecl();
164+
}
165+
141166
/// Compute a type of a distributed method accessor function based
142167
/// on the provided distributed method.
143168
static CanSILFunctionType getAccessorType(IRGenModule &IGM,
144169
SILFunction *Target) {
145170
auto &Context = IGM.Context;
146171

147172
auto getInvocationDecoderParameter = [&]() {
148-
auto *actor = Target->getDeclContext()
149-
->getInnermostTypeContext()
150-
->getSelfNominalTypeDecl();
173+
auto *actor = getDistributedActorOf(Target);
151174
auto *decoder = Context.getDistributedActorInvocationDecoder(actor);
152175
auto decoderTy = decoder->getInterfaceType()->getMetatypeInstanceType();
153176
auto paramType = IGM.getLoweredType(decoderTy);
@@ -235,7 +258,8 @@ DistributedAccessor::DistributedAccessor(IRGenFunction &IGF,
235258
IGM, AccessorType, AccessorType, SubstitutionMap(),
236259
/*suppress generics*/ true,
237260
FunctionPointer::Kind(
238-
FunctionPointer::BasicKind::AsyncFunctionPointer))) {}
261+
FunctionPointer::BasicKind::AsyncFunctionPointer))),
262+
ArgumentDecoder(findArgumentDecoder(IGM, target)) {}
239263

240264
void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
241265
llvm::Value *argumentTypes,
@@ -666,3 +690,31 @@ DistributedAccessor::getCalleeForDistributedTarget(llvm::Value *self) const {
666690
CalleeInfo info{fnType, fnType, SubstitutionMap()};
667691
return {std::move(info), getPointerToTarget(), self};
668692
}
693+
694+
ArgumentDecoderInfo
695+
DistributedAccessor::findArgumentDecoder(IRGenModule &IGM, SILFunction *thunk) {
696+
auto *actor = getDistributedActorOf(thunk);
697+
698+
auto *decodeFn = IGM.Context.getDistributedActorArgumentDecodingMethod(actor);
699+
assert(decodeFn && "no suitable decoder?");
700+
701+
auto methodTy = IGM.getSILTypes().getConstantFunctionType(
702+
IGM.getMaximalTypeExpansionContext(), SILDeclRef(decodeFn));
703+
704+
auto *decodeSIL = IGM.getSILModule().lookUpFunction(SILDeclRef(decodeFn));
705+
auto *fnPtr = IGM.getAddrOfSILFunction(decodeSIL, NotForDefinition,
706+
/*isDynamicallyReplacible=*/false);
707+
708+
auto signature = IGM.getSignature(methodTy, /*useSpecialConvention=*/false);
709+
710+
auto methodPtr =
711+
FunctionPointer::forDirect(classifyFunctionPointerKind(decodeSIL), fnPtr,
712+
/*secondaryValue=*/nullptr, signature);
713+
714+
return {.Type = methodTy, .Fn = methodPtr};
715+
}
716+
717+
Callee ArgumentDecoderInfo::getCallee(llvm::Value *decoder) const {
718+
CalleeInfo info(Type, Type, SubstitutionMap());
719+
return {std::move(info), Fn, decoder};
720+
}

0 commit comments

Comments
 (0)