From a9ad4d3876c023c5f9849703ef070fab631aa0fa Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Thu, 30 Apr 2026 07:38:19 -0500 Subject: [PATCH] [libc] Move function argument from rpc::dispatch to template (#194953) Summary: This was previous put here for ergnomics as to put it in the template required decltype. However, this has the effect of putting an actual functoin pointer in an escaping context if it is not fully removed or inlined. C++17 has a non-type-template parameter that we can use to keep the interface clean. Use that instead. --- flang-rt/lib/runtime/io-api-gpu.cpp | 65 +++++++++++++++-------------- libc/docs/gpu/rpc.rst | 2 +- libc/shared/rpc_dispatch.h | 8 ++-- offload/test/libc/rpc_callback.cpp | 18 ++++---- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/flang-rt/lib/runtime/io-api-gpu.cpp b/flang-rt/lib/runtime/io-api-gpu.cpp index 0998410034f1..0fd08c924d0e 100644 --- a/flang-rt/lib/runtime/io-api-gpu.cpp +++ b/flang-rt/lib/runtime/io-api-gpu.cpp @@ -28,91 +28,92 @@ RT_EXT_API_GROUP_BEGIN Cookie IODEF(BeginExternalListOutput)( ExternalUnit unitNumber, const char *sourceFile, int sourceLine) { - return rpc::dispatch(client, - IONAME(BeginExternalListOutput), unitNumber, sourceFile, sourceLine); + return rpc::dispatch( + client, unitNumber, sourceFile, sourceLine); } Cookie IODEF(BeginExternalFormattedOutput)(const char *format, std::size_t formatLength, const Descriptor *formatDescriptor, ExternalUnit unitNumber, const char *sourceFile, int sourceLine) { - return rpc::dispatch(client, - IONAME(BeginExternalFormattedOutput), + return rpc::dispatch(client, rpc::span{format, formatLength}, formatLength, formatDescriptor, unitNumber, sourceFile, sourceLine); } void IODEF(EnableHandlers)(Cookie cookie, bool hasIoStat, bool hasErr, bool hasEnd, bool hasEor, bool hasIoMsg) { - return rpc::dispatch(client, IONAME(EnableHandlers), - cookie, hasIoStat, hasErr, hasEnd, hasEor, hasIoMsg); + return rpc::dispatch( + client, cookie, hasIoStat, hasErr, hasEnd, hasEor, hasIoMsg); } enum Iostat IODEF(EndIoStatement)(Cookie cookie) { - return rpc::dispatch( - client, IONAME(EndIoStatement), cookie); + return rpc::dispatch( + client, cookie); } bool IODEF(OutputInteger8)(Cookie cookie, std::int8_t n) { - return rpc::dispatch( - client, IONAME(OutputInteger8), cookie, n); + return rpc::dispatch( + client, cookie, n); } bool IODEF(OutputInteger16)(Cookie cookie, std::int16_t n) { - return rpc::dispatch( - client, IONAME(OutputInteger16), cookie, n); + return rpc::dispatch( + client, cookie, n); } bool IODEF(OutputInteger32)(Cookie cookie, std::int32_t n) { - return rpc::dispatch( - client, IONAME(OutputInteger32), cookie, n); + return rpc::dispatch( + client, cookie, n); } bool IODEF(OutputInteger64)(Cookie cookie, std::int64_t n) { - return rpc::dispatch( - client, IONAME(OutputInteger64), cookie, n); + return rpc::dispatch( + client, cookie, n); } #ifdef __SIZEOF_INT128__ bool IODEF(OutputInteger128)(Cookie cookie, common::int128_t n) { - return rpc::dispatch( - client, IONAME(OutputInteger128), cookie, n); + return rpc::dispatch( + client, cookie, n); } #endif bool IODEF(OutputReal32)(Cookie cookie, float x) { - return rpc::dispatch( - client, IONAME(OutputReal32), cookie, x); + return rpc::dispatch( + client, cookie, x); } bool IODEF(OutputReal64)(Cookie cookie, double x) { - return rpc::dispatch( - client, IONAME(OutputReal64), cookie, x); + return rpc::dispatch( + client, cookie, x); } bool IODEF(OutputComplex32)(Cookie cookie, float re, float im) { - return rpc::dispatch( - client, IONAME(OutputComplex32), cookie, re, im); + return rpc::dispatch( + client, cookie, re, im); } bool IODEF(OutputComplex64)(Cookie cookie, double re, double im) { - return rpc::dispatch( - client, IONAME(OutputComplex64), cookie, re, im); + return rpc::dispatch( + client, cookie, re, im); } bool IODEF(OutputAscii)(Cookie cookie, const char *x, std::size_t length) { - return rpc::dispatch(client, IONAME(OutputAscii), cookie, - rpc::span{x, length}, length); + return rpc::dispatch( + client, cookie, rpc::span{x, length}, length); } bool IODEF(OutputCharacter)( Cookie cookie, const char *x, std::size_t length, int kind) { - return rpc::dispatch(client, IONAME(OutputCharacter), - cookie, rpc::span{x, length * kind}, length, kind); + return rpc::dispatch( + client, cookie, rpc::span{x, length * kind}, length, kind); } bool IODEF(OutputLogical)(Cookie cookie, bool truth) { - return rpc::dispatch( - client, IONAME(OutputLogical), cookie, truth); + return rpc::dispatch( + client, cookie, truth); } RT_EXT_API_GROUP_END diff --git a/libc/docs/gpu/rpc.rst b/libc/docs/gpu/rpc.rst index d5199b39b05e..1caa9e600d27 100644 --- a/libc/docs/gpu/rpc.rst +++ b/libc/docs/gpu/rpc.rst @@ -177,7 +177,7 @@ than submitting asynchronously. // Client-side dispatch. double fn(int x, long y, char c, double d) { - return rpc::dispatch(client, fn, x, y, c, d); + return rpc::dispatch(client, x, y, c, d); } // Server-side handling. diff --git a/libc/shared/rpc_dispatch.h b/libc/shared/rpc_dispatch.h index dcc54852b40b..3e3e568f4823 100644 --- a/libc/shared/rpc_dispatch.h +++ b/libc/shared/rpc_dispatch.h @@ -194,10 +194,10 @@ RPC_ATTRS constexpr void finish_args(rpc::Server::Port &port, State &&state, // Dispatch a function call to the server through the RPC mechanism. Copies the // argument list through the RPC interface. -template -RPC_ATTRS constexpr typename function_traits::return_type -dispatch(rpc::Client &client, FnTy, CallArgs... args) { - using Traits = function_traits; +template +RPC_ATTRS constexpr typename function_traits::return_type +dispatch(rpc::Client &client, CallArgs... args) { + using Traits = function_traits; using RetTy = typename Traits::return_type; using TupleTy = typename Traits::arg_types; using Bytes = tuple_bytes...>; diff --git a/offload/test/libc/rpc_callback.cpp b/offload/test/libc/rpc_callback.cpp index 06a076569aca..e38a1e1a9f86 100644 --- a/offload/test/libc/rpc_callback.cpp +++ b/offload/test/libc/rpc_callback.cpp @@ -98,32 +98,32 @@ int sum_array(const int *arr, int n) { #pragma omp begin declare variant match(device = {kind(gpu)}) int foo(int x, double d, char c) { - return rpc::dispatch(client, foo, x, d, c); + return rpc::dispatch(client, x, d, c); } -void void_fn(int x) { rpc::dispatch(client, void_fn, x); } +void void_fn(int x) { rpc::dispatch(client, x); } void writeback_fn(int *out) { - rpc::dispatch(client, writeback_fn, out); + rpc::dispatch(client, out); } int sum_const(const S *p) { - return rpc::dispatch(client, sum_const, p); + return rpc::dispatch(client, p); } int c_string(const char *s) { - return rpc::dispatch(client, c_string, s); + return rpc::dispatch(client, s); } -int empty() { return rpc::dispatch(client, empty); } +int empty() { return rpc::dispatch(client); } void divergent(int *p) { - rpc::dispatch(client, divergent, p); + rpc::dispatch(client, p); } int sum_array(const int *arr, int n) { - return rpc::dispatch( - client, sum_array, rpc::span{arr, uint64_t(n)}, n); + return rpc::dispatch( + client, rpc::span{arr, uint64_t(n)}, n); } #pragma omp end declare variant