[compiler-rt] a0a51a8 - [ORC][ORC-RT] Add SimplePackedSerialization support for optionals.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 22 17:39:25 PST 2022


Author: Lang Hames
Date: 2022-12-22T17:37:32-08:00
New Revision: a0a51a805fdbe9d6a0f87d3746c39111d95cfb8b

URL: https://github.com/llvm/llvm-project/commit/a0a51a805fdbe9d6a0f87d3746c39111d95cfb8b
DIFF: https://github.com/llvm/llvm-project/commit/a0a51a805fdbe9d6a0f87d3746c39111d95cfb8b.diff

LOG: [ORC][ORC-RT] Add SimplePackedSerialization support for optionals.

This allows optionals to be serialized and deserialized, and used as arguments
and return values in SPS wrapper functions.

Serialization of optional values is indicated by use of the SPSOptional tag.
SPSOptionals are serialized serialized as a bool (false for no value, true for
value) plus the serialization of the contained value if any. Serialization
to/from std::optional is included in this commit.

This commit includes updates to SimplePackedSerialization in both ORC and the
ORC runtime.

, std::optional serialization.

Added: 
    

Modified: 
    compiler-rt/lib/orc/simple_packed_serialization.h
    compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
    llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
    llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/orc/simple_packed_serialization.h b/compiler-rt/lib/orc/simple_packed_serialization.h
index a5948ec650fd5..9cebbeadee026 100644
--- a/compiler-rt/lib/orc/simple_packed_serialization.h
+++ b/compiler-rt/lib/orc/simple_packed_serialization.h
@@ -39,6 +39,7 @@
 #include "error.h"
 #include "stl_extras.h"
 
+#include <optional>
 #include <string>
 #include <string_view>
 #include <tuple>
@@ -189,6 +190,14 @@ template <typename... SPSTagTs> class SPSTuple {
   typedef SPSArgList<SPSTagTs...> AsArgList;
 };
 
+/// SPS tag type for optionals.
+///
+/// SPSOptionals should be serialized as a bool with true indicating that an
+/// SPSTagT value is present, and false indicating that there is no value.
+/// If the boolean is true then the serialized SPSTagT will follow immediately
+/// after it.
+template <typename SPSTagT> class SPSOptional {};
+
 /// SPS tag type for sequences.
 ///
 /// SPSSequences should be serialized as a uint64_t sequence length,
@@ -396,6 +405,38 @@ class SPSSerializationTraits<SPSTuple<SPSTagT1, SPSTagT2>, std::pair<T1, T2>> {
   }
 };
 
+/// SPSOptional serialization for std::optional.
+template <typename SPSTagT, typename T>
+class SPSSerializationTraits<SPSOptional<SPSTagT>, std::optional<T>> {
+public:
+  static size_t size(const std::optional<T> &Value) {
+    size_t Size = SPSArgList<bool>::size(!!Value);
+    if (Value)
+      Size += SPSArgList<SPSTagT>::size(*Value);
+    return Size;
+  }
+
+  static bool serialize(SPSOutputBuffer &OB, const std::optional<T> &Value) {
+    if (!SPSArgList<bool>::serialize(OB, !!Value))
+      return false;
+    if (Value)
+      return SPSArgList<SPSTagT>::serialize(OB, *Value);
+    return true;
+  }
+
+  static bool deserialize(SPSInputBuffer &IB, std::optional<T> &Value) {
+    bool HasValue;
+    if (!SPSArgList<bool>::deserialize(IB, HasValue))
+      return false;
+    if (HasValue) {
+      Value = T();
+      return SPSArgList<SPSTagT>::deserialize(IB, *Value);
+    } else
+      Value = std::optional<T>();
+    return true;
+  }
+};
+
 /// Serialization for string_views.
 ///
 /// Serialization is as for regular strings. Deserialization points directly

diff  --git a/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp b/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
index 3ecc20f8992b2..5577ef919fc6a 100644
--- a/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
+++ b/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
@@ -160,6 +160,16 @@ TEST(SimplePackedSerializationTest, StdPairSerialization) {
                              std::pair<int32_t, std::string>>(P);
 }
 
+TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {
+  std::optional<int64_t> NoValue;
+  blobSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);
+}
+
+TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
+  std::optional<int64_t> Value(42);
+  blobSerializationRoundTrip<SPSOptional<int64_t>>(Value);
+}
+
 TEST(SimplePackedSerializationTest, ArgListSerialization) {
   using BAL = SPSArgList<bool, int32_t, SPSString>;
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
index c388259482088..8a55d5fb17955 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h
@@ -40,6 +40,7 @@
 #include "llvm/Support/SwapByteOrder.h"
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <type_traits>
@@ -198,6 +199,14 @@ template <typename... SPSTagTs> class SPSTuple {
   typedef SPSArgList<SPSTagTs...> AsArgList;
 };
 
+/// SPS tag type for optionals.
+///
+/// SPSOptionals should be serialized as a bool with true indicating that an
+/// SPSTagT value is present, and false indicating that there is no value.
+/// If the boolean is true then the serialized SPSTagT will follow immediately
+/// after it.
+template <typename SPSTagT> class SPSOptional {};
+
 /// SPS tag type for sequences.
 ///
 /// SPSSequences should be serialized as a uint64_t sequence length,
@@ -465,6 +474,38 @@ class SPSSerializationTraits<SPSTuple<SPSTagT1, SPSTagT2>, std::pair<T1, T2>> {
   }
 };
 
+/// SPSOptional serialization for std::optional.
+template <typename SPSTagT, typename T>
+class SPSSerializationTraits<SPSOptional<SPSTagT>, std::optional<T>> {
+public:
+  static size_t size(const std::optional<T> &Value) {
+    size_t Size = SPSArgList<bool>::size(!!Value);
+    if (Value)
+      Size += SPSArgList<SPSTagT>::size(*Value);
+    return Size;
+  }
+
+  static bool serialize(SPSOutputBuffer &OB, const std::optional<T> &Value) {
+    if (!SPSArgList<bool>::serialize(OB, !!Value))
+      return false;
+    if (Value)
+      return SPSArgList<SPSTagT>::serialize(OB, *Value);
+    return true;
+  }
+
+  static bool deserialize(SPSInputBuffer &IB, std::optional<T> &Value) {
+    bool HasValue;
+    if (!SPSArgList<bool>::deserialize(IB, HasValue))
+      return false;
+    if (HasValue) {
+      Value = T();
+      return SPSArgList<SPSTagT>::deserialize(IB, *Value);
+    } else
+      Value = std::optional<T>();
+    return true;
+  }
+};
+
 /// Serialization for StringRefs.
 ///
 /// Serialization is as for regular strings. Deserialization points directly

diff  --git a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
index 6c441a31882a6..ff37d2368ab38 100644
--- a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp
@@ -137,6 +137,16 @@ TEST(SimplePackedSerializationTest, StdPairSerialization) {
   spsSerializationRoundTrip<SPSTuple<int32_t, SPSString>>(P);
 }
 
+TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {
+  std::optional<int64_t> NoValue;
+  spsSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);
+}
+
+TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
+  std::optional<int64_t> Value(42);
+  spsSerializationRoundTrip<SPSOptional<int64_t>>(Value);
+}
+
 TEST(SimplePackedSerializationTest, ArgListSerialization) {
   using BAL = SPSArgList<bool, int32_t, SPSString>;
 


        


More information about the llvm-commits mailing list