23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/FileSystem.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/Path.h"
27#include "llvm/Support/SourceMgr.h"
28#include "llvm/Support/ToolOutputFile.h"
44 auto *start = input->getBufferStart();
45 auto size = input->getBufferSize();
46 if (size %
sizeof(uint32_t) != 0) {
48 <<
"SPIR-V binary module must contain integral number of 32-bit words";
52 auto binary =
llvm::ArrayRef(
reinterpret_cast<const uint32_t *
>(start),
53 size /
sizeof(uint32_t));
59 static llvm::cl::opt<bool> enableControlFlowStructurization(
60 "spirv-structurize-control-flow",
62 "Enable control flow structurization into `spirv.mlir.selection` and "
63 "`spirv.mlir.loop`. This may need to be disabled to support "
64 "deserialization of early exits (see #138688)"),
65 llvm::cl::init(
true));
68 "deserialize-spirv",
"deserializes the SPIR-V module",
69 [](llvm::SourceMgr &sourceMgr,
MLIRContext *context) {
70 assert(sourceMgr.getNumBuffers() == 1 &&
"expected one buffer");
72 sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()), context,
73 {enableControlFlowStructurization});
89 size_t sizeInBytes = binary.size() *
sizeof(uint32_t);
91 output.write(
reinterpret_cast<char *
>(binary.data()), sizeInBytes);
93 if (
options.saveModuleForValidation) {
95 options.validationFilePrefix.find(llvm::sys::path::get_separator());
97 if (dirSeparator != std::string::npos) {
98 llvm::StringRef parentDir =
99 llvm::sys::path::parent_path(
options.validationFilePrefix);
100 if (!llvm::sys::fs::is_directory(parentDir))
101 return moduleOp.emitError(
102 "validation prefix directory does not exist\n");
108 std::error_code errorCode = llvm::sys::fs::createUniqueFile(
109 options.validationFilePrefix +
"%%%%%%.spv", fd, filename);
111 return moduleOp.emitError(
"error creating validation output file: ")
112 << errorCode.message() <<
"\n";
114 llvm::raw_fd_ostream validationOutput(fd,
true);
115 validationOutput.write(
reinterpret_cast<char *
>(binary.data()),
117 validationOutput.flush();
120 return mlir::success();
125 static llvm::cl::opt<bool> emitDebugInfo(
126 "spirv-emit-debug-info",
127 llvm::cl::desc(
"Emit SPIR-V debug information during serialization"),
128 llvm::cl::init(
false));
130 static llvm::cl::opt<std::string> validationFilesPrefix(
131 "spirv-save-validation-files-with-prefix",
133 "When non-empty string is passed each serialized SPIR-V module is "
134 "saved to an additional file that starts with the given prefix. This "
135 "is used to generate separate binaries for validation, where "
136 "`--split-input-file` normally combines all outputs into one. The "
137 "one combined output (`-o`) is still written. Created files need to "
138 "be removed manually once processed."),
142 "serialize-spirv",
"serialize SPIR-V dialect",
143 [](spirv::ModuleOp moduleOp,
raw_ostream &output) {
145 {
true, emitDebugInfo,
146 !validationFilesPrefix.empty(),
147 validationFilesPrefix});
150 registry.insert<spirv::SPIRVDialect>();
165 options.emitDebugInfo = emitDebugInfo;
177 spirvModule->print(output);
179 return mlir::success();
185 "test-spirv-roundtrip",
"test roundtrip in SPIR-V dialect",
190 registry.insert<spirv::SPIRVDialect>();
196 "test-spirv-roundtrip-debug",
"test roundtrip debug in SPIR-V",
201 registry.insert<spirv::SPIRVDialect>();
static llvm::ManagedStatic< PassManagerOptions > options
static LogicalResult roundTripModule(spirv::ModuleOp module, bool emitDebugInfo, raw_ostream &output)
static OwningOpRef< Operation * > deserializeModule(const llvm::MemoryBuffer *input, MLIRContext *context, const spirv::DeserializationOptions &options)
static LogicalResult serializeModule(spirv::ModuleOp moduleOp, raw_ostream &output, const spirv::SerializationOptions &options)
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
MLIRContext is the top-level object for a collection of MLIR operations.
const DialectRegistry & getDialectRegistry()
Return the dialect registry associated with this context.
void loadDialect()
Load a dialect in the context.
void loadAllAvailableDialects()
Load all dialects available in the registry in this context.
This class acts as an owning reference to an op, and will automatically destroy the held op on destru...
LogicalResult serialize(ModuleOp moduleOp, SmallVectorImpl< uint32_t > &binary, const SerializationOptions &options={})
Serializes the given SPIR-V moduleOp and writes to binary.
OwningOpRef< spirv::ModuleOp > deserialize(ArrayRef< uint32_t > binary, MLIRContext *context, const DeserializationOptions &options={})
Deserializes the given SPIR-V binary module and creates a MLIR ModuleOp in the given context.
Include the generated interface declarations.
void registerTestRoundtripSPIRV()
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
void registerFromSPIRVTranslation()
void registerTestRoundtripDebugSPIRV()
void registerToSPIRVTranslation()
Use Translate[ToMLIR|FromMLIR]Registration as an initializer that registers a function and associates...