MLIR  18.0.0git
Deserializer.h
Go to the documentation of this file.
1 //===- Deserializer.h - MLIR SPIR-V Deserializer ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the SPIR-V binary to MLIR SPIR-V module deserializer.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_TARGET_SPIRV_DESERIALIZER_H
14 #define MLIR_TARGET_SPIRV_DESERIALIZER_H
15 
18 #include "mlir/IR/Builders.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/SetVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/ScopedPrinter.h"
23 #include <cstdint>
24 #include <optional>
25 
26 namespace mlir {
27 namespace spirv {
28 
29 //===----------------------------------------------------------------------===//
30 // Utility Definitions
31 //===----------------------------------------------------------------------===//
32 
33 /// A struct for containing a header block's merge and continue targets.
34 ///
35 /// This struct is used to track original structured control flow info from
36 /// SPIR-V blob. This info will be used to create
37 /// spirv.mlir.selection/spirv.mlir.loop later.
40  Block *continueBlock; // nullptr for spirv.mlir.selection
42  uint32_t control; // Selection/loop control
43 
44  BlockMergeInfo(Location location, uint32_t control)
45  : mergeBlock(nullptr), continueBlock(nullptr), loc(location),
46  control(control) {}
47  BlockMergeInfo(Location location, uint32_t control, Block *m,
48  Block *c = nullptr)
49  : mergeBlock(m), continueBlock(c), loc(location), control(control) {}
50 };
51 
52 /// A struct for containing OpLine instruction information.
53 struct DebugLine {
54  uint32_t fileID;
55  uint32_t line;
56  uint32_t column;
57 };
58 
59 /// Map from a selection/loop's header block to its merge (and continue) target.
61 
62 /// A "deferred struct type" is a struct type with one or more member types not
63 /// known when the Deserializer first encounters the struct. This happens, for
64 /// example, with recursive structs where a pointer to the struct type is
65 /// forward declared through OpTypeForwardPointer in the SPIR-V module before
66 /// the struct declaration; the actual pointer to struct type should be defined
67 /// later through an OpTypePointer. For example, the following C struct:
68 ///
69 /// struct A {
70 /// A* next;
71 /// };
72 ///
73 /// would be represented in the SPIR-V module as:
74 ///
75 /// OpName %A "A"
76 /// OpTypeForwardPointer %APtr Generic
77 /// %A = OpTypeStruct %APtr
78 /// %APtr = OpTypePointer Generic %A
79 ///
80 /// This means that the spirv::StructType cannot be fully constructed directly
81 /// when the Deserializer encounters it. Instead we create a
82 /// DeferredStructTypeInfo that contains all the information we know about the
83 /// spirv::StructType. Once all forward references for the struct are resolved,
84 /// the struct's body is set with all member info.
87 
88  // A list of all unresolved member types for the struct. First element of each
89  // item is operand ID, second element is member index in the struct.
91 
92  // The list of member types. For unresolved members, this list contains
93  // place-holder empty types that will be updated later.
97 };
98 
99 /// A struct that collects the info needed to materialize/emit a
100 /// SpecConstantOperation op.
102  spirv::Opcode enclodesOpcode;
103  uint32_t resultTypeID;
105 };
106 
107 //===----------------------------------------------------------------------===//
108 // Deserializer Declaration
109 //===----------------------------------------------------------------------===//
110 
111 /// A SPIR-V module serializer.
112 ///
113 /// A SPIR-V binary module is a single linear stream of instructions; each
114 /// instruction is composed of 32-bit words. The first word of an instruction
115 /// records the total number of words of that instruction using the 16
116 /// higher-order bits. So this deserializer uses that to get instruction
117 /// boundary and parse instructions and build a SPIR-V ModuleOp gradually.
118 ///
119 // TODO: clean up created ops on errors
121 public:
122  /// Creates a deserializer for the given SPIR-V `binary` module.
123  /// The SPIR-V ModuleOp will be created into `context.
124  explicit Deserializer(ArrayRef<uint32_t> binary, MLIRContext *context);
125 
126  /// Deserializes the remembered SPIR-V binary module.
128 
129  /// Collects the final SPIR-V ModuleOp.
131 
132 private:
133  //===--------------------------------------------------------------------===//
134  // Module structure
135  //===--------------------------------------------------------------------===//
136 
137  /// Initializes the `module` ModuleOp in this deserializer instance.
138  OwningOpRef<spirv::ModuleOp> createModuleOp();
139 
140  /// Processes SPIR-V module header in `binary`.
141  LogicalResult processHeader();
142 
143  /// Processes the SPIR-V OpCapability with `operands` and updates bookkeeping
144  /// in the deserializer.
145  LogicalResult processCapability(ArrayRef<uint32_t> operands);
146 
147  /// Processes the SPIR-V OpExtension with `operands` and updates bookkeeping
148  /// in the deserializer.
149  LogicalResult processExtension(ArrayRef<uint32_t> words);
150 
151  /// Processes the SPIR-V OpExtInstImport with `operands` and updates
152  /// bookkeeping in the deserializer.
153  LogicalResult processExtInstImport(ArrayRef<uint32_t> words);
154 
155  /// Attaches (version, capabilities, extensions) triple to `module` as an
156  /// attribute.
157  void attachVCETriple();
158 
159  /// Processes the SPIR-V OpMemoryModel with `operands` and updates `module`.
160  LogicalResult processMemoryModel(ArrayRef<uint32_t> operands);
161 
162  /// Process SPIR-V OpName with `operands`.
163  LogicalResult processName(ArrayRef<uint32_t> operands);
164 
165  /// Processes an OpDecorate instruction.
166  LogicalResult processDecoration(ArrayRef<uint32_t> words);
167 
168  // Processes an OpMemberDecorate instruction.
169  LogicalResult processMemberDecoration(ArrayRef<uint32_t> words);
170 
171  /// Processes an OpMemberName instruction.
172  LogicalResult processMemberName(ArrayRef<uint32_t> words);
173 
174  /// Gets the function op associated with a result <id> of OpFunction.
175  spirv::FuncOp getFunction(uint32_t id) { return funcMap.lookup(id); }
176 
177  /// Processes the SPIR-V function at the current `offset` into `binary`.
178  /// The operands to the OpFunction instruction is passed in as ``operands`.
179  /// This method processes each instruction inside the function and dispatches
180  /// them to their handler method accordingly.
181  LogicalResult processFunction(ArrayRef<uint32_t> operands);
182 
183  /// Processes OpFunctionEnd and finalizes function. This wires up block
184  /// argument created from OpPhi instructions and also structurizes control
185  /// flow.
186  LogicalResult processFunctionEnd(ArrayRef<uint32_t> operands);
187 
188  /// Gets the constant's attribute and type associated with the given <id>.
189  std::optional<std::pair<Attribute, Type>> getConstant(uint32_t id);
190 
191  /// Gets the info needed to materialize the spec constant operation op
192  /// associated with the given <id>.
193  std::optional<SpecConstOperationMaterializationInfo>
194  getSpecConstantOperation(uint32_t id);
195 
196  /// Gets the constant's integer attribute with the given <id>. Returns a
197  /// null IntegerAttr if the given is not registered or does not correspond
198  /// to an integer constant.
199  IntegerAttr getConstantInt(uint32_t id);
200 
201  /// Returns a symbol to be used for the function name with the given
202  /// result <id>. This tries to use the function's OpName if
203  /// exists; otherwise creates one based on the <id>.
204  std::string getFunctionSymbol(uint32_t id);
205 
206  /// Returns a symbol to be used for the specialization constant with the given
207  /// result <id>. This tries to use the specialization constant's OpName if
208  /// exists; otherwise creates one based on the <id>.
209  std::string getSpecConstantSymbol(uint32_t id);
210 
211  /// Gets the specialization constant with the given result <id>.
212  spirv::SpecConstantOp getSpecConstant(uint32_t id) {
213  return specConstMap.lookup(id);
214  }
215 
216  /// Gets the composite specialization constant with the given result <id>.
217  spirv::SpecConstantCompositeOp getSpecConstantComposite(uint32_t id) {
218  return specConstCompositeMap.lookup(id);
219  }
220 
221  /// Creates a spirv::SpecConstantOp.
222  spirv::SpecConstantOp createSpecConstant(Location loc, uint32_t resultID,
223  TypedAttr defaultValue);
224 
225  /// Processes the OpVariable instructions at current `offset` into `binary`.
226  /// It is expected that this method is used for variables that are to be
227  /// defined at module scope and will be deserialized into a
228  /// spirv.GlobalVariable instruction.
229  LogicalResult processGlobalVariable(ArrayRef<uint32_t> operands);
230 
231  /// Gets the global variable associated with a result <id> of OpVariable.
232  spirv::GlobalVariableOp getGlobalVariable(uint32_t id) {
233  return globalVariableMap.lookup(id);
234  }
235 
236  //===--------------------------------------------------------------------===//
237  // Type
238  //===--------------------------------------------------------------------===//
239 
240  /// Gets type for a given result <id>.
241  Type getType(uint32_t id) { return typeMap.lookup(id); }
242 
243  /// Get the type associated with the result <id> of an OpUndef.
244  Type getUndefType(uint32_t id) { return undefMap.lookup(id); }
245 
246  /// Returns true if the given `type` is for SPIR-V void type.
247  bool isVoidType(Type type) const { return isa<NoneType>(type); }
248 
249  /// Processes a SPIR-V type instruction with given `opcode` and `operands` and
250  /// registers the type into `module`.
251  LogicalResult processType(spirv::Opcode opcode, ArrayRef<uint32_t> operands);
252 
253  LogicalResult processOpTypePointer(ArrayRef<uint32_t> operands);
254 
255  LogicalResult processArrayType(ArrayRef<uint32_t> operands);
256 
257  LogicalResult processCooperativeMatrixTypeKHR(ArrayRef<uint32_t> operands);
258 
259  LogicalResult processCooperativeMatrixTypeNV(ArrayRef<uint32_t> operands);
260 
261  LogicalResult processFunctionType(ArrayRef<uint32_t> operands);
262 
263  LogicalResult processJointMatrixType(ArrayRef<uint32_t> operands);
264 
265  LogicalResult processImageType(ArrayRef<uint32_t> operands);
266 
267  LogicalResult processSampledImageType(ArrayRef<uint32_t> operands);
268 
269  LogicalResult processRuntimeArrayType(ArrayRef<uint32_t> operands);
270 
271  LogicalResult processStructType(ArrayRef<uint32_t> operands);
272 
273  LogicalResult processMatrixType(ArrayRef<uint32_t> operands);
274 
275  LogicalResult processTypeForwardPointer(ArrayRef<uint32_t> operands);
276 
277  //===--------------------------------------------------------------------===//
278  // Constant
279  //===--------------------------------------------------------------------===//
280 
281  /// Processes a SPIR-V Op{|Spec}Constant instruction with the given
282  /// `operands`. `isSpec` indicates whether this is a specialization constant.
283  LogicalResult processConstant(ArrayRef<uint32_t> operands, bool isSpec);
284 
285  /// Processes a SPIR-V Op{|Spec}Constant{True|False} instruction with the
286  /// given `operands`. `isSpec` indicates whether this is a specialization
287  /// constant.
288  LogicalResult processConstantBool(bool isTrue, ArrayRef<uint32_t> operands,
289  bool isSpec);
290 
291  /// Processes a SPIR-V OpConstantComposite instruction with the given
292  /// `operands`.
293  LogicalResult processConstantComposite(ArrayRef<uint32_t> operands);
294 
295  /// Processes a SPIR-V OpSpecConstantComposite instruction with the given
296  /// `operands`.
297  LogicalResult processSpecConstantComposite(ArrayRef<uint32_t> operands);
298 
299  /// Processes a SPIR-V OpSpecConstantOp instruction with the given
300  /// `operands`.
301  LogicalResult processSpecConstantOperation(ArrayRef<uint32_t> operands);
302 
303  /// Materializes/emits an OpSpecConstantOp instruction.
304  Value materializeSpecConstantOperation(uint32_t resultID,
305  spirv::Opcode enclosedOpcode,
306  uint32_t resultTypeID,
307  ArrayRef<uint32_t> enclosedOpOperands);
308 
309  /// Processes a SPIR-V OpConstantNull instruction with the given `operands`.
310  LogicalResult processConstantNull(ArrayRef<uint32_t> operands);
311 
312  //===--------------------------------------------------------------------===//
313  // Debug
314  //===--------------------------------------------------------------------===//
315 
316  /// Discontinues any source-level location information that might be active
317  /// from a previous OpLine instruction.
318  void clearDebugLine();
319 
320  /// Creates a FileLineColLoc with the OpLine location information.
321  Location createFileLineColLoc(OpBuilder opBuilder);
322 
323  /// Processes a SPIR-V OpLine instruction with the given `operands`.
324  LogicalResult processDebugLine(ArrayRef<uint32_t> operands);
325 
326  /// Processes a SPIR-V OpString instruction with the given `operands`.
327  LogicalResult processDebugString(ArrayRef<uint32_t> operands);
328 
329  //===--------------------------------------------------------------------===//
330  // Control flow
331  //===--------------------------------------------------------------------===//
332 
333  /// Returns the block for the given label <id>.
334  Block *getBlock(uint32_t id) const { return blockMap.lookup(id); }
335 
336  // In SPIR-V, structured control flow is explicitly declared using merge
337  // instructions (OpSelectionMerge and OpLoopMerge). In the SPIR-V dialect,
338  // we use spirv.mlir.selection and spirv.mlir.loop to group structured control
339  // flow. The deserializer need to turn structured control flow marked with
340  // merge instructions into using spirv.mlir.selection/spirv.mlir.loop ops.
341  //
342  // Because structured control flow can nest and the basic block order have
343  // flexibility, we cannot isolate a structured selection/loop without
344  // deserializing all the blocks. So we use the following approach:
345  //
346  // 1. Deserialize all basic blocks in a function and create MLIR blocks for
347  // them into the function's region. In the meanwhile, keep a map between
348  // selection/loop header blocks to their corresponding merge (and continue)
349  // target blocks.
350  // 2. For each selection/loop header block, recursively get all basic blocks
351  // reachable (except the merge block) and put them in a newly created
352  // spirv.mlir.selection/spirv.mlir.loop's region. Structured control flow
353  // guarantees that we enter and exit in structured ways and the construct
354  // is nestable.
355  // 3. Put the new spirv.mlir.selection/spirv.mlir.loop op at the beginning of
356  // the
357  // old merge block and redirect all branches to the old header block to the
358  // old merge block (which contains the spirv.mlir.selection/spirv.mlir.loop
359  // op now).
360 
361  /// For OpPhi instructions, we use block arguments to represent them. OpPhi
362  /// encodes a list of (value, predecessor) pairs. At the time of handling the
363  /// block containing an OpPhi instruction, the predecessor block might not be
364  /// processed yet, also the value sent by it. So we need to defer handling
365  /// the block argument from the predecessors. We use the following approach:
366  ///
367  /// 1. For each OpPhi instruction, add a block argument to the current block
368  /// in construction. Record the block argument in `valueMap` so its uses
369  /// can be resolved. For the list of (value, predecessor) pairs, update
370  /// `blockPhiInfo` for bookkeeping.
371  /// 2. After processing all blocks, loop over `blockPhiInfo` to fix up each
372  /// block recorded there to create the proper block arguments on their
373  /// terminators.
374 
375  /// A data structure for containing a SPIR-V block's phi info. It will be
376  /// represented as block argument in SPIR-V dialect.
377  using BlockPhiInfo =
378  SmallVector<uint32_t, 2>; // The result <id> of the values sent
379 
380  /// Gets or creates the block corresponding to the given label <id>. The newly
381  /// created block will always be placed at the end of the current function.
382  Block *getOrCreateBlock(uint32_t id);
383 
384  LogicalResult processBranch(ArrayRef<uint32_t> operands);
385 
386  LogicalResult processBranchConditional(ArrayRef<uint32_t> operands);
387 
388  /// Processes a SPIR-V OpLabel instruction with the given `operands`.
389  LogicalResult processLabel(ArrayRef<uint32_t> operands);
390 
391  /// Processes a SPIR-V OpSelectionMerge instruction with the given `operands`.
392  LogicalResult processSelectionMerge(ArrayRef<uint32_t> operands);
393 
394  /// Processes a SPIR-V OpLoopMerge instruction with the given `operands`.
395  LogicalResult processLoopMerge(ArrayRef<uint32_t> operands);
396 
397  /// Processes a SPIR-V OpPhi instruction with the given `operands`.
398  LogicalResult processPhi(ArrayRef<uint32_t> operands);
399 
400  /// Creates block arguments on predecessors previously recorded when handling
401  /// OpPhi instructions.
402  LogicalResult wireUpBlockArgument();
403 
404  /// Extracts blocks belonging to a structured selection/loop into a
405  /// spirv.mlir.selection/spirv.mlir.loop op. This method iterates until all
406  /// blocks declared as selection/loop headers are handled.
407  LogicalResult structurizeControlFlow();
408 
409  //===--------------------------------------------------------------------===//
410  // Instruction
411  //===--------------------------------------------------------------------===//
412 
413  /// Get the Value associated with a result <id>.
414  ///
415  /// This method materializes normal constants and inserts "casting" ops
416  /// (`spirv.mlir.addressof` and `spirv.mlir.referenceof`) to turn an symbol
417  /// into a SSA value for handling uses of module scope constants/variables in
418  /// functions.
419  Value getValue(uint32_t id);
420 
421  /// Slices the first instruction out of `binary` and returns its opcode and
422  /// operands via `opcode` and `operands` respectively. Returns failure if
423  /// there is no more remaining instructions (`expectedOpcode` will be used to
424  /// compose the error message) or the next instruction is malformed.
426  sliceInstruction(spirv::Opcode &opcode, ArrayRef<uint32_t> &operands,
427  std::optional<spirv::Opcode> expectedOpcode = std::nullopt);
428 
429  /// Processes a SPIR-V instruction with the given `opcode` and `operands`.
430  /// This method is the main entrance for handling SPIR-V instruction; it
431  /// checks the instruction opcode and dispatches to the corresponding handler.
432  /// Processing of Some instructions (like OpEntryPoint and OpExecutionMode)
433  /// might need to be deferred, since they contain forward references to <id>s
434  /// in the deserialized binary, but module in SPIR-V dialect expects these to
435  /// be ssa-uses.
436  LogicalResult processInstruction(spirv::Opcode opcode,
437  ArrayRef<uint32_t> operands,
438  bool deferInstructions = true);
439 
440  /// Processes a SPIR-V instruction from the given `operands`. It should
441  /// deserialize into an op with the given `opName` and `numOperands`.
442  /// This method is a generic one for dispatching any SPIR-V ops without
443  /// variadic operands and attributes in TableGen definitions.
444  LogicalResult processOpWithoutGrammarAttr(ArrayRef<uint32_t> words,
445  StringRef opName, bool hasResult,
446  unsigned numOperands);
447 
448  /// Processes a OpUndef instruction. Adds a spirv.Undef operation at the
449  /// current insertion point.
450  LogicalResult processUndef(ArrayRef<uint32_t> operands);
451 
452  /// Method to dispatch to the specialized deserialization function for an
453  /// operation in SPIR-V dialect that is a mirror of an instruction in the
454  /// SPIR-V spec. This is auto-generated from ODS. Dispatch is handled for
455  /// all operations in SPIR-V dialect that have hasOpcode == 1.
456  LogicalResult dispatchToAutogenDeserialization(spirv::Opcode opcode,
457  ArrayRef<uint32_t> words);
458 
459  /// Processes a SPIR-V OpExtInst with given `operands`. This slices the
460  /// entries of `operands` that specify the extended instruction set <id> and
461  /// the instruction opcode. The op deserializer is then invoked using the
462  /// other entries.
463  LogicalResult processExtInst(ArrayRef<uint32_t> operands);
464 
465  /// Dispatches the deserialization of extended instruction set operation based
466  /// on the extended instruction set name, and instruction opcode. This is
467  /// autogenerated from ODS.
469  dispatchToExtensionSetAutogenDeserialization(StringRef extensionSetName,
470  uint32_t instructionID,
471  ArrayRef<uint32_t> words);
472 
473  /// Method to deserialize an operation in the SPIR-V dialect that is a mirror
474  /// of an instruction in the SPIR-V spec. This is auto generated if hasOpcode
475  /// == 1 and autogenSerialization == 1 in ODS.
476  template <typename OpTy>
477  LogicalResult processOp(ArrayRef<uint32_t> words) {
478  return emitError(unknownLoc, "unsupported deserialization for ")
479  << OpTy::getOperationName() << " op";
480  }
481 
482 private:
483  /// The SPIR-V binary module.
484  ArrayRef<uint32_t> binary;
485 
486  /// Contains the data of the OpLine instruction which precedes the current
487  /// processing instruction.
488  std::optional<DebugLine> debugLine;
489 
490  /// The current word offset into the binary module.
491  unsigned curOffset = 0;
492 
493  /// MLIRContext to create SPIR-V ModuleOp into.
494  MLIRContext *context;
495 
496  // TODO: create Location subclass for binary blob
497  Location unknownLoc;
498 
499  /// The SPIR-V ModuleOp.
501 
502  /// The current function under construction.
503  std::optional<spirv::FuncOp> curFunction;
504 
505  /// The current block under construction.
506  Block *curBlock = nullptr;
507 
508  OpBuilder opBuilder;
509 
510  spirv::Version version = spirv::Version::V_1_0;
511 
512  /// The list of capabilities used by the module.
513  llvm::SmallSetVector<spirv::Capability, 4> capabilities;
514 
515  /// The list of extensions used by the module.
516  llvm::SmallSetVector<spirv::Extension, 2> extensions;
517 
518  // Result <id> to type mapping.
519  DenseMap<uint32_t, Type> typeMap;
520 
521  // Result <id> to constant attribute and type mapping.
522  ///
523  /// In the SPIR-V binary format, all constants are placed in the module and
524  /// shared by instructions at module level and in subsequent functions. But in
525  /// the SPIR-V dialect, we materialize the constant to where it's used in the
526  /// function. So when seeing a constant instruction in the binary format, we
527  /// don't immediately emit a constant op into the module, we keep its value
528  /// (and type) here. Later when it's used, we materialize the constant.
530 
531  // Result <id> to spec constant mapping.
533 
534  // Result <id> to composite spec constant mapping.
536 
537  /// Result <id> to info needed to materialize an OpSpecConstantOp
538  /// mapping.
540  specConstOperationMap;
541 
542  // Result <id> to variable mapping.
544 
545  // Result <id> to function mapping.
547 
548  // Result <id> to block mapping.
550 
551  // Header block to its merge (and continue) target mapping.
552  BlockMergeInfoMap blockMergeInfo;
553 
554  // For each pair of {predecessor, target} blocks, maps the pair of blocks to
555  // the list of phi arguments passed from predecessor to target.
556  DenseMap<std::pair<Block * /*predecessor*/, Block * /*target*/>, BlockPhiInfo>
557  blockPhiInfo;
558 
559  // Result <id> to value mapping.
560  DenseMap<uint32_t, Value> valueMap;
561 
562  // Mapping from result <id> to undef value of a type.
563  DenseMap<uint32_t, Type> undefMap;
564 
565  // Result <id> to name mapping.
567 
568  // Result <id> to debug info mapping.
569  DenseMap<uint32_t, StringRef> debugInfoMap;
570 
571  // Result <id> to decorations mapping.
573 
574  // Result <id> to type decorations.
575  DenseMap<uint32_t, uint32_t> typeDecorations;
576 
577  // Result <id> to member decorations.
578  // decorated-struct-type-<id> ->
579  // (struct-member-index -> (decoration -> decoration-operands))
580  DenseMap<uint32_t,
582  memberDecorationMap;
583 
584  // Result <id> to member name.
585  // struct-type-<id> -> (struct-member-index -> name)
587 
588  // Result <id> to extended instruction set name.
589  DenseMap<uint32_t, StringRef> extendedInstSets;
590 
591  // List of instructions that are processed in a deferred fashion (after an
592  // initial processing of the entire binary). Some operations like
593  // OpEntryPoint, and OpExecutionMode use forward references to function
594  // <id>s. In SPIR-V dialect the corresponding operations (spirv.EntryPoint and
595  // spirv.ExecutionMode) need these references resolved. So these instructions
596  // are deserialized and stored for processing once the entire binary is
597  // processed.
599  deferredInstructions;
600 
601  /// A list of IDs for all types forward-declared through OpTypeForwardPointer
602  /// instructions.
603  SetVector<uint32_t> typeForwardPointerIDs;
604 
605  /// A list of all structs which have unresolved member types.
606  SmallVector<DeferredStructTypeInfo, 0> deferredStructTypesInfos;
607 
608 #ifndef NDEBUG
609  /// A logger used to emit information during the deserialzation process.
610  llvm::ScopedPrinter logger;
611 #endif
612 };
613 
614 } // namespace spirv
615 } // namespace mlir
616 
617 #endif // MLIR_TARGET_SPIRV_DESERIALIZER_H
Block represents an ordered list of Operations.
Definition: Block.h:30
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
This class helps build Operations.
Definition: Builders.h:206
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:93
A SPIR-V module serializer.
Definition: Deserializer.h:120
LogicalResult deserialize()
Deserializes the remembered SPIR-V binary module.
Deserializer(ArrayRef< uint32_t > binary, MLIRContext *context)
Creates a deserializer for the given SPIR-V binary module.
OwningOpRef< spirv::ModuleOp > collect()
Collects the final SPIR-V ModuleOp.
SPIR-V struct type.
Definition: SPIRVTypes.h:284
This header declares functions that assist transformations in the MemRef dialect.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
A struct for containing a header block's merge and continue targets.
Definition: Deserializer.h:38
BlockMergeInfo(Location location, uint32_t control, Block *m, Block *c=nullptr)
Definition: Deserializer.h:47
BlockMergeInfo(Location location, uint32_t control)
Definition: Deserializer.h:44
A struct for containing OpLine instruction information.
Definition: Deserializer.h:53
A "deferred struct type" is a struct type with one or more member types not known when the Deserializ...
Definition: Deserializer.h:85
spirv::StructType deferredStructType
Definition: Deserializer.h:86
SmallVector< spirv::StructType::MemberDecorationInfo, 0 > memberDecorationsInfo
Definition: Deserializer.h:96
SmallVector< spirv::StructType::OffsetInfo, 0 > offsetInfo
Definition: Deserializer.h:95
SmallVector< Type, 4 > memberTypes
Definition: Deserializer.h:94
SmallVector< std::pair< uint32_t, unsigned >, 0 > unresolvedMemberTypes
Definition: Deserializer.h:90
A struct that collects the info needed to materialize/emit a SpecConstantOperation op.
Definition: Deserializer.h:101