From a0a51a805fdbe9d6a0f87d3746c39111d95cfb8b Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 22 Dec 2022 17:22:58 -0800 Subject: [PATCH] [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. --- compiler-rt/lib/orc/simple_packed_serialization.h | 41 ++++++++++++++++++++++ .../unit/simple_packed_serialization_test.cpp | 10 ++++++ .../Orc/Shared/SimplePackedSerialization.h | 41 ++++++++++++++++++++++ .../Orc/SimplePackedSerializationTest.cpp | 10 ++++++ 4 files changed, 102 insertions(+) diff --git a/compiler-rt/lib/orc/simple_packed_serialization.h b/compiler-rt/lib/orc/simple_packed_serialization.h index a5948ec..9cebbea 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 #include #include #include @@ -189,6 +190,14 @@ public: typedef SPSArgList 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 class SPSOptional {}; + /// SPS tag type for sequences. /// /// SPSSequences should be serialized as a uint64_t sequence length, @@ -396,6 +405,38 @@ public: } }; +/// SPSOptional serialization for std::optional. +template +class SPSSerializationTraits, std::optional> { +public: + static size_t size(const std::optional &Value) { + size_t Size = SPSArgList::size(!!Value); + if (Value) + Size += SPSArgList::size(*Value); + return Size; + } + + static bool serialize(SPSOutputBuffer &OB, const std::optional &Value) { + if (!SPSArgList::serialize(OB, !!Value)) + return false; + if (Value) + return SPSArgList::serialize(OB, *Value); + return true; + } + + static bool deserialize(SPSInputBuffer &IB, std::optional &Value) { + bool HasValue; + if (!SPSArgList::deserialize(IB, HasValue)) + return false; + if (HasValue) { + Value = T(); + return SPSArgList::deserialize(IB, *Value); + } else + Value = std::optional(); + 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 3ecc20f..5577ef9 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>(P); } +TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) { + std::optional NoValue; + blobSerializationRoundTrip>(NoValue); +} + +TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) { + std::optional Value(42); + blobSerializationRoundTrip>(Value); +} + TEST(SimplePackedSerializationTest, ArgListSerialization) { using BAL = SPSArgList; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h index c388259..8a55d5f 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 +#include #include #include #include @@ -198,6 +199,14 @@ public: typedef SPSArgList 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 class SPSOptional {}; + /// SPS tag type for sequences. /// /// SPSSequences should be serialized as a uint64_t sequence length, @@ -465,6 +474,38 @@ public: } }; +/// SPSOptional serialization for std::optional. +template +class SPSSerializationTraits, std::optional> { +public: + static size_t size(const std::optional &Value) { + size_t Size = SPSArgList::size(!!Value); + if (Value) + Size += SPSArgList::size(*Value); + return Size; + } + + static bool serialize(SPSOutputBuffer &OB, const std::optional &Value) { + if (!SPSArgList::serialize(OB, !!Value)) + return false; + if (Value) + return SPSArgList::serialize(OB, *Value); + return true; + } + + static bool deserialize(SPSInputBuffer &IB, std::optional &Value) { + bool HasValue; + if (!SPSArgList::deserialize(IB, HasValue)) + return false; + if (HasValue) { + Value = T(); + return SPSArgList::deserialize(IB, *Value); + } else + Value = std::optional(); + 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 6c441a3..ff37d23 100644 --- a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp @@ -137,6 +137,16 @@ TEST(SimplePackedSerializationTest, StdPairSerialization) { spsSerializationRoundTrip>(P); } +TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) { + std::optional NoValue; + spsSerializationRoundTrip>(NoValue); +} + +TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) { + std::optional Value(42); + spsSerializationRoundTrip>(Value); +} + TEST(SimplePackedSerializationTest, ArgListSerialization) { using BAL = SPSArgList; -- 2.7.4