[llvm] [orc-rt] Add SPSExecutorAddr <-> T* serialization. (PR #162992)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 11 04:06:28 PDT 2025
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/162992
This replaces SPS transparent conversion for pointers. Transparent conversion only applies to argument/return types, not nested types. We want to be able to serialize / deserialize structs containing pointers.
We may need to replace this in the near future with a new SPSPointer tag type, since SPSExecutorAddr is meant to be serialization for pure addresses, and pointers may carry other information (e.g. tag bits), but we can do that in a follow-up commit.
>From a58e9831ccdbd44427cc254048685de35da46d5e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Sat, 11 Oct 2025 21:04:16 +1100
Subject: [PATCH] [orc-rt] Add SPSExecutorAddr <-> T* serialization.
This replaces SPS transparent conversion for pointers. Transparent conversion
only applies to argument/return types, not nested types. We want to be able to
serialize / deserialize structs containing pointers.
We may need to replace this in the near future with a new SPSPointer tag type,
since SPSExecutorAddr is meant to be serialization for pure addresses, and
pointers may carry other information (e.g. tag bits), but we can do that in a
follow-up commit.
---
orc-rt/include/orc-rt/SPSWrapperFunction.h | 21 -------
.../orc-rt/SimplePackedSerialization.h | 20 +++++++
orc-rt/unittests/SPSWrapperFunctionTest.cpp | 56 -------------------
.../SimplePackedSerializationTest.cpp | 6 ++
4 files changed, 26 insertions(+), 77 deletions(-)
diff --git a/orc-rt/include/orc-rt/SPSWrapperFunction.h b/orc-rt/include/orc-rt/SPSWrapperFunction.h
index dc688223d9924..46c08a0c688d0 100644
--- a/orc-rt/include/orc-rt/SPSWrapperFunction.h
+++ b/orc-rt/include/orc-rt/SPSWrapperFunction.h
@@ -42,12 +42,6 @@ template <typename... SPSArgTs> struct WFSPSHelper {
static T &&from(T &&Arg) noexcept { return std::forward<T>(Arg); }
};
- template <typename T> struct Serializable<T *> {
- typedef ExecutorAddr serializable_type;
- static ExecutorAddr to(T *Arg) { return ExecutorAddr::fromPtr(Arg); }
- static T *from(ExecutorAddr A) { return A.toPtr<T *>(); }
- };
-
template <> struct Serializable<Error> {
typedef SPSSerializableError serializable_type;
static SPSSerializableError to(Error Err) {
@@ -66,21 +60,6 @@ template <typename... SPSArgTs> struct WFSPSHelper {
}
};
- template <typename T> struct Serializable<Expected<T *>> {
- typedef SPSSerializableExpected<ExecutorAddr> serializable_type;
- static SPSSerializableExpected<ExecutorAddr> to(Expected<T *> Val) {
- return SPSSerializableExpected<ExecutorAddr>(
- Val ? Expected<ExecutorAddr>(ExecutorAddr::fromPtr(*Val))
- : Expected<ExecutorAddr>(Val.takeError()));
- }
- static Expected<T *> from(SPSSerializableExpected<ExecutorAddr> Val) {
- if (auto Tmp = Val.toExpected())
- return Tmp->toPtr<T *>();
- else
- return Tmp.takeError();
- }
- };
-
template <typename... Ts> struct DeserializableTuple;
template <typename... Ts> struct DeserializableTuple<std::tuple<Ts...>> {
diff --git a/orc-rt/include/orc-rt/SimplePackedSerialization.h b/orc-rt/include/orc-rt/SimplePackedSerialization.h
index f60ccad666ab1..0f291c40a8b5e 100644
--- a/orc-rt/include/orc-rt/SimplePackedSerialization.h
+++ b/orc-rt/include/orc-rt/SimplePackedSerialization.h
@@ -556,6 +556,26 @@ template <> class SPSSerializationTraits<SPSExecutorAddr, ExecutorAddr> {
}
};
+/// Allow SPSExectorAddr serialization to/from T*.
+template <typename T> class SPSSerializationTraits<SPSExecutorAddr, T *> {
+public:
+ static size_t size(T *const &P) {
+ return SPSArgList<SPSExecutorAddr>::size(ExecutorAddr::fromPtr(P));
+ }
+
+ static bool serialize(SPSOutputBuffer &OB, T *const &P) {
+ return SPSArgList<SPSExecutorAddr>::serialize(OB, ExecutorAddr::fromPtr(P));
+ }
+
+ static bool deserialize(SPSInputBuffer &IB, T *&P) {
+ ExecutorAddr Value;
+ if (!SPSArgList<SPSExecutorAddr>::deserialize(IB, Value))
+ return false;
+ P = Value.toPtr<T *>();
+ return true;
+ }
+};
+
/// Helper type for serializing Errors.
///
/// llvm::Errors are move-only, and not inspectable except by consuming them.
diff --git a/orc-rt/unittests/SPSWrapperFunctionTest.cpp b/orc-rt/unittests/SPSWrapperFunctionTest.cpp
index ed085f2fef76c..81e5755e821f3 100644
--- a/orc-rt/unittests/SPSWrapperFunctionTest.cpp
+++ b/orc-rt/unittests/SPSWrapperFunctionTest.cpp
@@ -192,62 +192,6 @@ TEST(SPSWrapperFunctionUtilsTest, TransparentConversionExpectedFailureCase) {
EXPECT_EQ(ErrMsg, "N is not a multiple of 2");
}
-static void
-round_trip_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
- orc_rt_WrapperFunctionReturn Return,
- orc_rt_WrapperFunctionBuffer ArgBytes) {
- SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::handle(
- Session, CallCtx, Return, ArgBytes,
- [](move_only_function<void(int32_t *)> Return, int32_t *P) {
- Return(P);
- });
-}
-
-TEST(SPSWrapperFunctionUtilsTest, TransparentConversionPointers) {
- int X = 42;
- int *P = nullptr;
- SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::call(
- DirectCaller(nullptr, round_trip_int_pointer_sps_wrapper),
- [&](Expected<int32_t *> R) { P = cantFail(std::move(R)); }, &X);
-
- EXPECT_EQ(P, &X);
-}
-
-TEST(SPSWrapperFunctionUtilsTest, TransparentConversionReferenceArguments) {
- int X = 42;
- int *P = nullptr;
- SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::call(
- DirectCaller(nullptr, round_trip_int_pointer_sps_wrapper),
- [&](Expected<int32_t *> R) { P = cantFail(std::move(R)); },
- static_cast<int *const &>(&X));
-
- EXPECT_EQ(P, &X);
-}
-
-static void
-expected_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
- orc_rt_WrapperFunctionReturn Return,
- orc_rt_WrapperFunctionBuffer ArgBytes) {
- SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::handle(
- Session, CallCtx, Return, ArgBytes,
- [](move_only_function<void(Expected<int32_t *>)> Return, int32_t *P) {
- Return(P);
- });
-}
-
-TEST(SPSWrapperFunctionUtilsTest, TransparentConversionExpectedPointers) {
- int X = 42;
- int *P = nullptr;
- SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::call(
- DirectCaller(nullptr, expected_int_pointer_sps_wrapper),
- [&](Expected<Expected<int32_t *>> R) {
- P = cantFail(cantFail(std::move(R)));
- },
- &X);
-
- EXPECT_EQ(P, &X);
-}
-
template <size_t N> struct SPSOpCounter {};
namespace orc_rt {
diff --git a/orc-rt/unittests/SimplePackedSerializationTest.cpp b/orc-rt/unittests/SimplePackedSerializationTest.cpp
index c3df499da510f..17f0e9c17e19e 100644
--- a/orc-rt/unittests/SimplePackedSerializationTest.cpp
+++ b/orc-rt/unittests/SimplePackedSerializationTest.cpp
@@ -169,6 +169,12 @@ TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
blobSerializationRoundTrip<SPSOptional<int64_t>>(Value);
}
+TEST(SimplePackedSerializationTest, Pointers) {
+ int X = 42;
+ int *P = &X;
+ blobSerializationRoundTrip<SPSExecutorAddr>(P);
+}
+
TEST(SimplePackedSerializationTest, ArgListSerialization) {
using BAL = SPSArgList<bool, int32_t, SPSString>;
More information about the llvm-commits
mailing list