//===- SPIRVBinaryUtils.cpp - SPIR-V Binary Module Utils --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file declares common utilities for SPIR-V binary module. // //===----------------------------------------------------------------------===// #ifndef MLIR_TARGET_SPIRV_SPIRVBINARYUTILS_H #define MLIR_TARGET_SPIRV_SPIRVBINARYUTILS_H #include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h" #include "mlir/Support/LLVM.h" #include #include namespace mlir { namespace spirv { /// SPIR-V binary header word count constexpr unsigned kHeaderWordCount = 5; /// SPIR-V magic number constexpr uint32_t kMagicNumber = 0x07230203; /// The serializer tool ID registered to the Khronos Group constexpr uint32_t kGeneratorNumber = 22; /// Max number of words /// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_universal_limits constexpr uint32_t kMaxWordCount = 65535; /// Max number of words for literal constexpr uint32_t kMaxLiteralWordCount = kMaxWordCount - 3; /// Appends a SPRI-V module header to `header` with the given `version` and /// `idBound`. void appendModuleHeader(SmallVectorImpl &header, spirv::Version version, uint32_t idBound); /// Returns the word-count-prefixed opcode for an SPIR-V instruction. uint32_t getPrefixedOpcode(uint32_t wordCount, spirv::Opcode opcode); /// Encodes an SPIR-V `literal` string into the given `binary` vector. void encodeStringLiteralInto(SmallVectorImpl &binary, StringRef literal); /// Decodes a string literal in `words` starting at `wordIndex`. Update the /// latter to point to the position in words after the string literal. inline StringRef decodeStringLiteral(ArrayRef words, unsigned &wordIndex) { StringRef str(reinterpret_cast(words.data() + wordIndex)); wordIndex += str.size() / 4 + 1; return str; } /// Returns the SPV_INTEL_long_composites continuation opcode that may follow /// `parent`, or std::nullopt if `parent` is not a splittable composite/struct /// op. inline std::optional getContinuationOpcode(spirv::Opcode parent) { switch (parent) { case spirv::Opcode::OpTypeStruct: return spirv::Opcode::OpTypeStructContinuedINTEL; case spirv::Opcode::OpConstantComposite: return spirv::Opcode::OpConstantCompositeContinuedINTEL; case spirv::Opcode::OpSpecConstantComposite: return spirv::Opcode::OpSpecConstantCompositeContinuedINTEL; case spirv::Opcode::OpCompositeConstruct: return spirv::Opcode::OpCompositeConstructContinuedINTEL; default: return std::nullopt; } } } // namespace spirv } // namespace mlir #endif // MLIR_TARGET_SPIRV_SPIRVBINARYUTILS_H