diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-09-17 16:47:57 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-17 13:47:57 -0700 |
| commit | b9cddcb9c718f986ee5e4f7c6189ee2ebea4ace1 (patch) | |
| tree | d4537f98e8ec93459f13d2d271d621b80f797a59 /source/slang/slang-serialize-types.h | |
| parent | bbf492a0b78ce8b96372a736b7d591cdc71d5b65 (diff) | |
Share debug information between AST and IR (#1547)
* Test if blob is returned.
* Rename serialize files so can be grouped.
* StringRepresentationCache -> SerialStringTable
* Split out SerialStringTable from slang-serialize-ir
* First pass at reorganizing serialization/containers. Remain some issues about debug info.
* Fix bug in calculating sourceloc.
* Improve calcFixSourceLoc
* Make allocations for payload RiffContainer align to at least 8 bytes. This is important for read, if the payload can contain 8 byte aligned data. Note this has no effect on Riff file format alignment rules.
* Improve comments around RiffContainer and alignment.
* Remove SerialStringTable, can just use StringSlicePool instead.
* Typo fix for Clang/Linux.
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-serialize-types.h')
| -rw-r--r-- | source/slang/slang-serialize-types.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/source/slang/slang-serialize-types.h b/source/slang/slang-serialize-types.h new file mode 100644 index 000000000..f799dd607 --- /dev/null +++ b/source/slang/slang-serialize-types.h @@ -0,0 +1,230 @@ +// slang-serialize-types.h +#ifndef SLANG_SERIALIZE_TYPES_H +#define SLANG_SERIALIZE_TYPES_H + +#include "../core/slang-riff.h" +#include "../core/slang-string-slice-pool.h" +#include "../core/slang-array-view.h" + +#include "slang-name.h" +#include "slang-source-loc.h" + +namespace Slang { + +// Options for IR/AST/Debug serialization + +struct SerialOptionFlag +{ + typedef uint32_t Type; + enum Enum : Type + { + RawSourceLocation = 0x01, + DebugInfo = 0x02, + }; +}; +typedef SerialOptionFlag::Type SerialOptionFlags; + + +// Compression styles + +enum class SerialCompressionType : uint8_t +{ + None, + VariableByteLite, +}; + + +struct SerialStringData +{ + enum class StringIndex : uint32_t; + + ///enum class StringOffset : uint32_t; ///< Offset into the m_stringsBuffer + + typedef uint32_t SizeType; + + static const StringIndex kNullStringIndex = StringIndex(StringSlicePool::kNullHandle); + static const StringIndex kEmptyStringIndex = StringIndex(StringSlicePool::kEmptyHandle); +}; + +struct SerialStringTableUtil +{ + /// Convert a pool into a string table + static void encodeStringTable(const StringSlicePool& pool, List<char>& stringTable); + static void encodeStringTable(const ConstArrayView<UnownedStringSlice>& slices, List<char>& stringTable); + + /// Appends the decoded strings into slicesOut + static void appendDecodedStringTable(const char* table, size_t tableSize, List<UnownedStringSlice>& slicesOut); + + /// Decodes a string table (and does so such that the indices are compatible with StringSlicePool) + static void decodeStringTable(const char* table, size_t tableSize, List<UnownedStringSlice>& slicesOut); + + /// Decodes a string table + static void decodeStringTable(const char* table, size_t tableSize, StringSlicePool& outPool); + + /// Produces an index map, from slices to indices in pool + static void calcStringSlicePoolMap(const List<UnownedStringSlice>& slices, StringSlicePool& pool, List<StringSlicePool::Handle>& indexMap); +}; + +struct SerialParseUtil +{ + /// Given text, finds the compression type + static SlangResult parseCompressionType(const UnownedStringSlice& text, SerialCompressionType& outType); + /// Given a compression type, return text + static UnownedStringSlice getText(SerialCompressionType type); +}; + +struct SerialListUtil +{ + template <typename T> + static size_t calcArraySize(const List<T>& list) + { + return list.getCount() * sizeof(T); + } + + template <typename T> + static bool isEqual(const List<T>& aIn, const List<T>& bIn) + { + if (&aIn == &bIn) + { + return true; + } + const Index size = aIn.getCount(); + + if (size != bIn.getCount()) + { + return false; + } + + const T* a = aIn.begin(); + const T* b = bIn.begin(); + + if (a != b) + { + for (Index i = 0; i < size; ++i) + { + if (a[i] != b[i]) + { + return false; + } + } + } + + return true; + } +}; + +// For types/FourCC that work for serializing in general (not just IR). +struct SerialBinary +{ + static const FourCC kRiffFourCc = RiffFourCC::kRiff; + + /// Container + static const FourCC kContainerFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'c'); + + /// A string table + static const FourCC kStringTableFourCc = SLANG_FOUR_CC('S', 'L', 's', 't'); + + /// TranslationUnitList + static const FourCC kTranslationUnitListFourCc = SLANG_FOUR_CC('S', 'L', 'm', 'l'); + + /// An entry point + static const FourCC kEntryPointFourCc = SLANG_FOUR_CC('E', 'P', 'n', 't'); + + /// Container + static const FourCC kContainerHeaderFourCc = SLANG_FOUR_CC('S', 'c', 'h', 'd'); + + struct ContainerHeader + { + uint32_t compressionType; ///< Holds the compression type used (if used at all) + }; + + struct ArrayHeader + { + uint32_t numEntries; + }; + struct CompressedArrayHeader + { + uint32_t numEntries; ///< The number of entries + uint32_t numCompressedEntries; ///< The amount of compressed entries + }; +}; + +// Replace first char with 's' +#define SLANG_MAKE_COMPRESSED_FOUR_CC(fourCc) SLANG_FOUR_CC_REPLACE_FIRST_CHAR(fourCc, 's') + +struct SerialRiffUtil +{ + class ListResizer + { + public: + virtual void* setSize(size_t newSize) = 0; + SLANG_FORCE_INLINE size_t getTypeSize() const { return m_typeSize; } + ListResizer(size_t typeSize) :m_typeSize(typeSize) {} + + protected: + size_t m_typeSize; + }; + + template <typename T> + class ListResizerForType : public ListResizer + { + public: + typedef ListResizer Parent; + + SLANG_FORCE_INLINE ListResizerForType(List<T>& list) : + Parent(sizeof(T)), + m_list(list) + {} + + virtual void* setSize(size_t newSize) SLANG_OVERRIDE + { + m_list.setCount(UInt(newSize)); + return (void*)m_list.begin(); + } + + protected: + List<T>& m_list; + }; + + static Result writeArrayChunk(SerialCompressionType compressionType, FourCC chunkId, const void* data, size_t numEntries, size_t typeSize, RiffContainer* container); + + template <typename T> + static Result writeArrayChunk(SerialCompressionType compressionType, FourCC chunkId, const List<T>& array, RiffContainer* container) + { + return writeArrayChunk(compressionType, chunkId, array.begin(), size_t(array.getCount()), sizeof(T), container); + } + + template <typename T> + static Result writeArrayUncompressedChunk(FourCC chunkId, const List<T>& array, RiffContainer* container) + { + return writeArrayChunk(SerialCompressionType::None, chunkId, array.begin(), size_t(array.getCount()), sizeof(T), container); + } + + static Result readArrayChunk(SerialCompressionType compressionType, RiffContainer::DataChunk* dataChunk, ListResizer& listOut); + + template <typename T> + static Result readArrayChunk(SerialCompressionType moduleCompressionType, RiffContainer::DataChunk* dataChunk, List<T>& arrayOut) + { + SerialCompressionType compressionType = SerialCompressionType::None; + if (dataChunk->m_fourCC == SLANG_MAKE_COMPRESSED_FOUR_CC(dataChunk->m_fourCC)) + { + // If it has compression, use the compression type set in the header + compressionType = moduleCompressionType; + } + ListResizerForType<T> resizer(arrayOut); + return readArrayChunk(compressionType, dataChunk, resizer); + } + + template <typename T> + static Result readArrayUncompressedChunk(RiffContainer::DataChunk* chunk, List<T>& arrayOut) + { + ListResizerForType<T> resizer(arrayOut); + return readArrayChunk(SerialCompressionType::None, chunk, resizer); + } + + +}; + +} // namespace Slang + +#endif |
