[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