|
11 | 11 |
|
12 | 12 | #include <cstdint> |
13 | 13 | #include <memory> |
| 14 | +#include <variant> |
14 | 15 |
|
15 | 16 | #include "llvm/ADT/StringMap.h" |
16 | 17 | #include "llvm/ADT/StringRef.h" |
@@ -159,6 +160,107 @@ namespace intel { |
159 | 160 | /// the Intel runtime offload plugin. |
160 | 161 | Error containerizeOpenMPSPIRVImage(std::unique_ptr<MemoryBuffer> &Binary); |
161 | 162 | } // namespace intel |
| 163 | + |
| 164 | +namespace sycl { |
| 165 | +class PropertySetRegistry; |
| 166 | + |
| 167 | +// A property value. It can be either a 32-bit unsigned integer or a byte array. |
| 168 | +class PropertyValue { |
| 169 | +public: |
| 170 | + using ByteArrayTy = SmallVector<char, 8>; |
| 171 | + |
| 172 | + PropertyValue() = default; |
| 173 | + PropertyValue(uint32_t Val) : Value(Val) {} |
| 174 | + PropertyValue(StringRef Data) |
| 175 | + : Value(ByteArrayTy(Data.begin(), Data.end())) {} |
| 176 | + |
| 177 | + template <typename C, typename T = typename C::value_type> |
| 178 | + PropertyValue(const C &Data) |
| 179 | + : PropertyValue({reinterpret_cast<const char *>(Data.data()), |
| 180 | + Data.size() * sizeof(T)}) {} |
| 181 | + |
| 182 | + uint32_t asUint32() const { |
| 183 | + assert(getType() == PV_UInt32 && "must be UINT32 value"); |
| 184 | + return std::get<uint32_t>(Value); |
| 185 | + } |
| 186 | + |
| 187 | + StringRef asByteArray() const { |
| 188 | + assert(getType() == PV_ByteArray && "must be BYTE_ARRAY value"); |
| 189 | + const auto &ByteArrayRef = std::get<ByteArrayTy>(Value); |
| 190 | + return {ByteArrayRef.data(), ByteArrayRef.size()}; |
| 191 | + } |
| 192 | + |
| 193 | + // Note: each enumeration value corresponds one-to-one to the |
| 194 | + // index of the std::variant. |
| 195 | + enum Type { PV_None = 0, PV_UInt32 = 1, PV_ByteArray = 2 }; |
| 196 | + Type getType() const { return static_cast<Type>(Value.index()); } |
| 197 | + |
| 198 | + bool operator==(const PropertyValue &Rhs) const { return Value == Rhs.Value; } |
| 199 | + |
| 200 | +private: |
| 201 | + std::variant<std::monostate, std::uint32_t, ByteArrayTy> Value = {}; |
| 202 | +}; |
| 203 | + |
| 204 | +/// A property set is a collection of PropertyValues, each identified by a name. |
| 205 | +/// A property set registry is a collection of property sets, each identified by |
| 206 | +/// a category name. The registry allows for the addition, removal, and |
| 207 | +/// retrieval of property sets and their properties. |
| 208 | +class PropertySetRegistry { |
| 209 | + using PropertyMapTy = StringMap<unsigned>; |
| 210 | + /// A property set. Preserves insertion order when iterating elements. |
| 211 | + using PropertySet = MapVector<SmallString<16>, PropertyValue, PropertyMapTy>; |
| 212 | + using MapTy = MapVector<SmallString<16>, PropertySet, PropertyMapTy>; |
| 213 | + |
| 214 | +public: |
| 215 | + /// Function for bulk addition of an entire property set in the given |
| 216 | + /// \p Category . |
| 217 | + template <typename MapTy> void add(StringRef Category, const MapTy &Props) { |
| 218 | + assert(PropSetMap.find(Category) == PropSetMap.end() && |
| 219 | + "category already added"); |
| 220 | + auto &PropSet = PropSetMap[Category]; |
| 221 | + |
| 222 | + for (const auto &Prop : Props) |
| 223 | + PropSet.insert_or_assign(Prop.first, PropertyValue(Prop.second)); |
| 224 | + } |
| 225 | + |
| 226 | + /// Adds the given \p PropVal with the given \p PropName into the given \p |
| 227 | + /// Category . |
| 228 | + template <typename T> |
| 229 | + void add(StringRef Category, StringRef PropName, const T &PropVal) { |
| 230 | + auto &PropSet = PropSetMap[Category]; |
| 231 | + PropSet.insert({PropName, PropertyValue(PropVal)}); |
| 232 | + } |
| 233 | + |
| 234 | + void remove(StringRef Category, StringRef PropName) { |
| 235 | + auto PropertySetIt = PropSetMap.find(Category); |
| 236 | + if (PropertySetIt == PropSetMap.end()) |
| 237 | + return; |
| 238 | + auto &PropertySet = PropertySetIt->second; |
| 239 | + auto PropIt = PropertySet.find(PropName); |
| 240 | + if (PropIt == PropertySet.end()) |
| 241 | + return; |
| 242 | + PropertySet.erase(PropIt); |
| 243 | + } |
| 244 | + |
| 245 | + static Expected<PropertySetRegistry> readJSON(MemoryBufferRef Buf); |
| 246 | + |
| 247 | + /// Dumps the property set registry to the given \p Out stream. |
| 248 | + void writeJSON(raw_ostream &Out) const; |
| 249 | + SmallString<0> writeJSON() const; |
| 250 | + |
| 251 | + MapTy::const_iterator begin() const { return PropSetMap.begin(); } |
| 252 | + MapTy::const_iterator end() const { return PropSetMap.end(); } |
| 253 | + |
| 254 | + /// Retrieves a property set with given \p Name . |
| 255 | + PropertySet &operator[](StringRef Name) { return PropSetMap[Name]; } |
| 256 | + /// Constant access to the underlying map. |
| 257 | + const MapTy &getPropSets() const { return PropSetMap; } |
| 258 | + |
| 259 | +private: |
| 260 | + MapTy PropSetMap; |
| 261 | +}; |
| 262 | + |
| 263 | +} // namespace sycl |
162 | 264 | } // namespace offloading |
163 | 265 | } // namespace llvm |
164 | 266 |
|
|
0 commit comments