//===- Deserializer.h - MLIR SPIR-V Deserializer ----------------*- 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 the SPIR-V binary to MLIR SPIR-V module deserializer. // //===----------------------------------------------------------------------===// #ifndef MLIR_TARGET_SPIRV_DESERIALIZER_H #define MLIR_TARGET_SPIRV_DESERIALIZER_H #include "mlir/Dialect/SPIRV/IR/SPIRVEnums.h" #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h" #include "mlir/IR/Builders.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ScopedPrinter.h" #include <cstdint> #include <optional> namespace mlir { namespace spirv { //===----------------------------------------------------------------------===// // Utility Definitions //===----------------------------------------------------------------------===// /// A struct for containing a header block's merge and continue targets. /// /// This struct is used to track original structured control flow info from /// SPIR-V blob. This info will be used to create /// spirv.mlir.selection/spirv.mlir.loop later. struct BlockMergeInfo { … }; /// A struct for containing OpLine instruction information. struct DebugLine { … }; /// Map from a selection/loop's header block to its merge (and continue) target. BlockMergeInfoMap; /// A "deferred struct type" is a struct type with one or more member types not /// known when the Deserializer first encounters the struct. This happens, for /// example, with recursive structs where a pointer to the struct type is /// forward declared through OpTypeForwardPointer in the SPIR-V module before /// the struct declaration; the actual pointer to struct type should be defined /// later through an OpTypePointer. For example, the following C struct: /// /// struct A { /// A* next; /// }; /// /// would be represented in the SPIR-V module as: /// /// OpName %A "A" /// OpTypeForwardPointer %APtr Generic /// %A = OpTypeStruct %APtr /// %APtr = OpTypePointer Generic %A /// /// This means that the spirv::StructType cannot be fully constructed directly /// when the Deserializer encounters it. Instead we create a /// DeferredStructTypeInfo that contains all the information we know about the /// spirv::StructType. Once all forward references for the struct are resolved, /// the struct's body is set with all member info. struct DeferredStructTypeInfo { … }; /// A struct that collects the info needed to materialize/emit a /// SpecConstantOperation op. struct SpecConstOperationMaterializationInfo { … }; //===----------------------------------------------------------------------===// // Deserializer Declaration //===----------------------------------------------------------------------===// /// A SPIR-V module serializer. /// /// A SPIR-V binary module is a single linear stream of instructions; each /// instruction is composed of 32-bit words. The first word of an instruction /// records the total number of words of that instruction using the 16 /// higher-order bits. So this deserializer uses that to get instruction /// boundary and parse instructions and build a SPIR-V ModuleOp gradually. /// // TODO: clean up created ops on errors class Deserializer { … }; } // namespace spirv } // namespace mlir #endif // MLIR_TARGET_SPIRV_DESERIALIZER_H