MLIR 22.0.0git
DeserializeOps.cpp
Go to the documentation of this file.
1//===- DeserializeOps.cpp - MLIR SPIR-V Deserialization (Ops) -------------===//
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 defines the Deserializer methods for SPIR-V binary instructions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Deserializer.h"
14
17#include "mlir/IR/Builders.h"
18#include "mlir/IR/Location.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/Support/Debug.h"
23#include <optional>
24
25using namespace mlir;
26
27#define DEBUG_TYPE "spirv-deserialization"
28
29//===----------------------------------------------------------------------===//
30// Utility Functions
31//===----------------------------------------------------------------------===//
32
33/// Extracts the opcode from the given first word of a SPIR-V instruction.
34static inline spirv::Opcode extractOpcode(uint32_t word) {
35 return static_cast<spirv::Opcode>(word & 0xffff);
36}
37
38//===----------------------------------------------------------------------===//
39// Instruction
40//===----------------------------------------------------------------------===//
41
43 if (auto constInfo = getConstant(id)) {
44 // Materialize a `spirv.Constant` op at every use site.
45 return spirv::ConstantOp::create(opBuilder, unknownLoc, constInfo->second,
46 constInfo->first);
47 }
48 if (std::optional<std::pair<Attribute, Type>> constCompositeReplicateInfo =
50 return spirv::EXTConstantCompositeReplicateOp::create(
51 opBuilder, unknownLoc, constCompositeReplicateInfo->second,
52 constCompositeReplicateInfo->first);
53 }
54 if (auto varOp = getGlobalVariable(id)) {
55 auto addressOfOp =
56 spirv::AddressOfOp::create(opBuilder, unknownLoc, varOp.getType(),
57 SymbolRefAttr::get(varOp.getOperation()));
58 return addressOfOp.getPointer();
59 }
60 if (auto constOp = getSpecConstant(id)) {
61 auto referenceOfOp = spirv::ReferenceOfOp::create(
62 opBuilder, unknownLoc, constOp.getDefaultValue().getType(),
63 SymbolRefAttr::get(constOp.getOperation()));
64 return referenceOfOp.getReference();
65 }
66 if (SpecConstantCompositeOp specConstCompositeOp =
68 auto referenceOfOp = spirv::ReferenceOfOp::create(
69 opBuilder, unknownLoc, specConstCompositeOp.getType(),
70 SymbolRefAttr::get(specConstCompositeOp.getOperation()));
71 return referenceOfOp.getReference();
72 }
73 if (auto specConstCompositeReplicateOp =
75 auto referenceOfOp = spirv::ReferenceOfOp::create(
76 opBuilder, unknownLoc, specConstCompositeReplicateOp.getType(),
77 SymbolRefAttr::get(specConstCompositeReplicateOp.getOperation()));
78 return referenceOfOp.getReference();
79 }
80 if (auto specConstOperationInfo = getSpecConstantOperation(id)) {
82 id, specConstOperationInfo->enclodesOpcode,
83 specConstOperationInfo->resultTypeID,
84 specConstOperationInfo->enclosedOpOperands);
85 }
86 if (auto undef = getUndefType(id)) {
87 return spirv::UndefOp::create(opBuilder, unknownLoc, undef);
88 }
89 if (std::optional<spirv::GraphConstantARMOpMaterializationInfo>
90 graphConstantARMInfo = getGraphConstantARM(id)) {
91 IntegerAttr graphConstantID = graphConstantARMInfo->graphConstantID;
92 Type resultType = graphConstantARMInfo->resultType;
93 return spirv::GraphConstantARMOp::create(opBuilder, unknownLoc, resultType,
94 graphConstantID);
95 }
96 return valueMap.lookup(id);
97}
98
100 spirv::Opcode &opcode, ArrayRef<uint32_t> &operands,
101 std::optional<spirv::Opcode> expectedOpcode) {
102 auto binarySize = binary.size();
103 if (curOffset >= binarySize) {
104 return emitError(unknownLoc, "expected ")
105 << (expectedOpcode ? spirv::stringifyOpcode(*expectedOpcode)
106 : "more")
107 << " instruction";
108 }
109
110 // For each instruction, get its word count from the first word to slice it
111 // from the stream properly, and then dispatch to the instruction handler.
112
113 uint32_t wordCount = binary[curOffset] >> 16;
114
115 if (wordCount == 0)
116 return emitError(unknownLoc, "word count cannot be zero");
117
118 uint32_t nextOffset = curOffset + wordCount;
119 if (nextOffset > binarySize)
120 return emitError(unknownLoc, "insufficient words for the last instruction");
121
122 opcode = extractOpcode(binary[curOffset]);
123 operands = binary.slice(curOffset + 1, wordCount - 1);
124 curOffset = nextOffset;
125 return success();
126}
127
129 spirv::Opcode opcode, ArrayRef<uint32_t> operands, bool deferInstructions) {
130 LLVM_DEBUG(logger.startLine() << "[inst] processing instruction "
131 << spirv::stringifyOpcode(opcode) << "\n");
132
133 // First dispatch all the instructions whose opcode does not correspond to
134 // those that have a direct mirror in the SPIR-V dialect
135 switch (opcode) {
136 case spirv::Opcode::OpCapability:
137 return processCapability(operands);
138 case spirv::Opcode::OpExtension:
139 return processExtension(operands);
140 case spirv::Opcode::OpExtInst:
141 return processExtInst(operands);
142 case spirv::Opcode::OpExtInstImport:
143 return processExtInstImport(operands);
144 case spirv::Opcode::OpMemberName:
145 return processMemberName(operands);
146 case spirv::Opcode::OpMemoryModel:
147 return processMemoryModel(operands);
148 case spirv::Opcode::OpEntryPoint:
149 case spirv::Opcode::OpExecutionMode:
150 if (deferInstructions) {
151 deferredInstructions.emplace_back(opcode, operands);
152 return success();
153 }
154 break;
155 case spirv::Opcode::OpVariable:
156 if (isa<spirv::ModuleOp>(opBuilder.getBlock()->getParentOp())) {
157 return processGlobalVariable(operands);
158 }
159 break;
160 case spirv::Opcode::OpLine:
161 return processDebugLine(operands);
162 case spirv::Opcode::OpNoLine:
164 return success();
165 case spirv::Opcode::OpName:
166 return processName(operands);
167 case spirv::Opcode::OpString:
168 return processDebugString(operands);
169 case spirv::Opcode::OpModuleProcessed:
170 case spirv::Opcode::OpSource:
171 case spirv::Opcode::OpSourceContinued:
172 case spirv::Opcode::OpSourceExtension:
173 // TODO: This is debug information embedded in the binary which should be
174 // translated into the spirv.module.
175 return success();
176 case spirv::Opcode::OpTypeVoid:
177 case spirv::Opcode::OpTypeBool:
178 case spirv::Opcode::OpTypeInt:
179 case spirv::Opcode::OpTypeFloat:
180 case spirv::Opcode::OpTypeVector:
181 case spirv::Opcode::OpTypeMatrix:
182 case spirv::Opcode::OpTypeArray:
183 case spirv::Opcode::OpTypeFunction:
184 case spirv::Opcode::OpTypeImage:
185 case spirv::Opcode::OpTypeSampledImage:
186 case spirv::Opcode::OpTypeRuntimeArray:
187 case spirv::Opcode::OpTypeStruct:
188 case spirv::Opcode::OpTypePointer:
189 case spirv::Opcode::OpTypeTensorARM:
190 case spirv::Opcode::OpTypeGraphARM:
191 case spirv::Opcode::OpTypeCooperativeMatrixKHR:
192 return processType(opcode, operands);
193 case spirv::Opcode::OpTypeForwardPointer:
194 return processTypeForwardPointer(operands);
195 case spirv::Opcode::OpConstant:
196 return processConstant(operands, /*isSpec=*/false);
197 case spirv::Opcode::OpSpecConstant:
198 return processConstant(operands, /*isSpec=*/true);
199 case spirv::Opcode::OpConstantComposite:
200 return processConstantComposite(operands);
201 case spirv::Opcode::OpConstantCompositeReplicateEXT:
203 case spirv::Opcode::OpSpecConstantComposite:
204 return processSpecConstantComposite(operands);
205 case spirv::Opcode::OpSpecConstantCompositeReplicateEXT:
207 case spirv::Opcode::OpSpecConstantOp:
208 return processSpecConstantOperation(operands);
209 case spirv::Opcode::OpConstantTrue:
210 return processConstantBool(/*isTrue=*/true, operands, /*isSpec=*/false);
211 case spirv::Opcode::OpSpecConstantTrue:
212 return processConstantBool(/*isTrue=*/true, operands, /*isSpec=*/true);
213 case spirv::Opcode::OpConstantFalse:
214 return processConstantBool(/*isTrue=*/false, operands, /*isSpec=*/false);
215 case spirv::Opcode::OpSpecConstantFalse:
216 return processConstantBool(/*isTrue=*/false, operands, /*isSpec=*/true);
217 case spirv::Opcode::OpConstantNull:
218 return processConstantNull(operands);
219 case spirv::Opcode::OpGraphConstantARM:
220 return processGraphConstantARM(operands);
221 case spirv::Opcode::OpDecorate:
222 return processDecoration(operands);
223 case spirv::Opcode::OpMemberDecorate:
224 return processMemberDecoration(operands);
225 case spirv::Opcode::OpFunction:
226 return processFunction(operands);
227 case spirv::Opcode::OpGraphEntryPointARM:
228 if (deferInstructions) {
229 deferredInstructions.emplace_back(opcode, operands);
230 return success();
231 }
232 return processGraphEntryPointARM(operands);
233 case spirv::Opcode::OpGraphARM:
234 return processGraphARM(operands);
235 case spirv::Opcode::OpGraphSetOutputARM:
236 return processOpGraphSetOutputARM(operands);
237 case spirv::Opcode::OpGraphEndARM:
238 return processGraphEndARM(operands);
239 case spirv::Opcode::OpLabel:
240 return processLabel(operands);
241 case spirv::Opcode::OpBranch:
242 return processBranch(operands);
243 case spirv::Opcode::OpBranchConditional:
244 return processBranchConditional(operands);
245 case spirv::Opcode::OpSelectionMerge:
246 return processSelectionMerge(operands);
247 case spirv::Opcode::OpLoopMerge:
248 return processLoopMerge(operands);
249 case spirv::Opcode::OpPhi:
250 return processPhi(operands);
251 case spirv::Opcode::OpUndef:
252 return processUndef(operands);
253 default:
254 break;
255 }
256 return dispatchToAutogenDeserialization(opcode, operands);
257}
258
260 ArrayRef<uint32_t> words, StringRef opName, bool hasResult,
261 unsigned numOperands) {
262 SmallVector<Type, 1> resultTypes;
263 uint32_t valueID = 0;
264
265 size_t wordIndex = 0;
266 if (hasResult) {
267 if (wordIndex >= words.size())
268 return emitError(unknownLoc,
269 "expected result type <id> while deserializing for ")
270 << opName;
271
272 // Decode the type <id>
273 auto type = getType(words[wordIndex]);
274 if (!type)
275 return emitError(unknownLoc, "unknown type result <id>: ")
276 << words[wordIndex];
277 resultTypes.push_back(type);
278 ++wordIndex;
279
280 // Decode the result <id>
281 if (wordIndex >= words.size())
282 return emitError(unknownLoc,
283 "expected result <id> while deserializing for ")
284 << opName;
285 valueID = words[wordIndex];
286 ++wordIndex;
287 }
288
289 SmallVector<Value, 4> operands;
291
292 // Decode operands
293 size_t operandIndex = 0;
294 for (; operandIndex < numOperands && wordIndex < words.size();
295 ++operandIndex, ++wordIndex) {
296 auto arg = getValue(words[wordIndex]);
297 if (!arg)
298 return emitError(unknownLoc, "unknown result <id>: ") << words[wordIndex];
299 operands.push_back(arg);
300 }
301 if (operandIndex != numOperands) {
302 return emitError(
303 unknownLoc,
304 "found less operands than expected when deserializing for ")
305 << opName << "; only " << operandIndex << " of " << numOperands
306 << " processed";
307 }
308 if (wordIndex != words.size()) {
309 return emitError(
310 unknownLoc,
311 "found more operands than expected when deserializing for ")
312 << opName << "; only " << wordIndex << " of " << words.size()
313 << " processed";
314 }
315
316 // Attach attributes from decorations
317 if (decorations.count(valueID)) {
318 auto attrs = decorations[valueID].getAttrs();
319 attributes.append(attrs.begin(), attrs.end());
320 }
321
322 // Create the op and update bookkeeping maps
323 Location loc = createFileLineColLoc(opBuilder);
324 OperationState opState(loc, opName);
325 opState.addOperands(operands);
326 if (hasResult)
327 opState.addTypes(resultTypes);
328 opState.addAttributes(attributes);
329 Operation *op = opBuilder.create(opState);
330 if (hasResult)
331 valueMap[valueID] = op->getResult(0);
332
335
336 return success();
337}
338
340 if (operands.size() != 2) {
341 return emitError(unknownLoc, "OpUndef instruction must have two operands");
342 }
343 auto type = getType(operands[0]);
344 if (!type) {
345 return emitError(unknownLoc, "unknown type <id> with OpUndef instruction");
346 }
347 undefMap[operands[1]] = type;
348 return success();
349}
350
352 if (operands.size() < 4) {
353 return emitError(unknownLoc,
354 "OpExtInst must have at least 4 operands, result type "
355 "<id>, result <id>, set <id> and instruction opcode");
356 }
357 if (!extendedInstSets.count(operands[2])) {
358 return emitError(unknownLoc, "undefined set <id> in OpExtInst");
359 }
360 SmallVector<uint32_t, 4> slicedOperands;
361 slicedOperands.append(operands.begin(), std::next(operands.begin(), 2));
362 slicedOperands.append(std::next(operands.begin(), 4), operands.end());
364 extendedInstSets[operands[2]], operands[3], slicedOperands);
365}
366
367namespace mlir {
368namespace spirv {
369
370template <>
371LogicalResult
373 unsigned wordIndex = 0;
374 if (wordIndex >= words.size()) {
375 return emitError(unknownLoc,
376 "missing Execution Model specification in OpEntryPoint");
377 }
378 auto execModel = spirv::ExecutionModelAttr::get(
379 context, static_cast<spirv::ExecutionModel>(words[wordIndex++]));
380 if (wordIndex >= words.size()) {
381 return emitError(unknownLoc, "missing <id> in OpEntryPoint");
382 }
383 // Get the function <id>
384 auto fnID = words[wordIndex++];
385 // Get the function name
386 auto fnName = decodeStringLiteral(words, wordIndex);
387 // Verify that the function <id> matches the fnName
388 auto parsedFunc = getFunction(fnID);
389 if (!parsedFunc) {
390 return emitError(unknownLoc, "no function matching <id> ") << fnID;
391 }
392 if (parsedFunc.getName() != fnName) {
393 // The deserializer uses "spirv_fn_<id>" as the function name if the input
394 // SPIR-V blob does not contain a name for it. We should use a more clear
395 // indication for such case rather than relying on naming details.
396 if (!parsedFunc.getName().starts_with("spirv_fn_"))
397 return emitError(unknownLoc,
398 "function name mismatch between OpEntryPoint "
399 "and OpFunction with <id> ")
400 << fnID << ": " << fnName << " vs. " << parsedFunc.getName();
401 parsedFunc.setName(fnName);
402 }
404 while (wordIndex < words.size()) {
405 auto arg = getGlobalVariable(words[wordIndex]);
406 if (!arg) {
407 return emitError(unknownLoc, "undefined result <id> ")
408 << words[wordIndex] << " while decoding OpEntryPoint";
409 }
410 interface.push_back(SymbolRefAttr::get(arg.getOperation()));
411 wordIndex++;
412 }
413 spirv::EntryPointOp::create(
414 opBuilder, unknownLoc, execModel,
415 SymbolRefAttr::get(opBuilder.getContext(), fnName),
416 opBuilder.getArrayAttr(interface));
417 return success();
418}
419
420template <>
421LogicalResult
423 unsigned wordIndex = 0;
424 if (wordIndex >= words.size()) {
425 return emitError(unknownLoc,
426 "missing function result <id> in OpExecutionMode");
427 }
428 // Get the function <id> to get the name of the function
429 auto fnID = words[wordIndex++];
430 auto fn = getFunction(fnID);
431 if (!fn) {
432 return emitError(unknownLoc, "no function matching <id> ") << fnID;
433 }
434 // Get the Execution mode
435 if (wordIndex >= words.size()) {
436 return emitError(unknownLoc, "missing Execution Mode in OpExecutionMode");
437 }
438 auto execMode = spirv::ExecutionModeAttr::get(
439 context, static_cast<spirv::ExecutionMode>(words[wordIndex++]));
440
441 // Get the values
442 SmallVector<Attribute, 4> attrListElems;
443 while (wordIndex < words.size()) {
444 attrListElems.push_back(opBuilder.getI32IntegerAttr(words[wordIndex++]));
445 }
446 auto values = opBuilder.getArrayAttr(attrListElems);
447 spirv::ExecutionModeOp::create(
448 opBuilder, unknownLoc,
449 SymbolRefAttr::get(opBuilder.getContext(), fn.getName()), execMode,
450 values);
451 return success();
452}
453
454template <>
455LogicalResult
457 if (operands.size() < 3) {
458 return emitError(unknownLoc,
459 "OpFunctionCall must have at least 3 operands");
460 }
461
462 Type resultType = getType(operands[0]);
463 if (!resultType) {
464 return emitError(unknownLoc, "undefined result type from <id> ")
465 << operands[0];
466 }
467
468 // Use null type to mean no result type.
469 if (isVoidType(resultType))
470 resultType = nullptr;
471
472 auto resultID = operands[1];
473 auto functionID = operands[2];
474
475 auto functionName = getFunctionSymbol(functionID);
476
477 SmallVector<Value, 4> arguments;
478 for (auto operand : llvm::drop_begin(operands, 3)) {
479 auto value = getValue(operand);
480 if (!value) {
481 return emitError(unknownLoc, "unknown <id> ")
482 << operand << " used by OpFunctionCall";
483 }
484 arguments.push_back(value);
485 }
486
487 auto opFunctionCall = spirv::FunctionCallOp::create(
488 opBuilder, unknownLoc, resultType,
489 SymbolRefAttr::get(opBuilder.getContext(), functionName), arguments);
490
491 if (resultType)
492 valueMap[resultID] = opFunctionCall.getResult(0);
493 return success();
494}
495
496template <>
497LogicalResult
499 SmallVector<Type, 1> resultTypes;
500 size_t wordIndex = 0;
501 SmallVector<Value, 4> operands;
503
504 if (wordIndex < words.size()) {
505 auto arg = getValue(words[wordIndex]);
506
507 if (!arg) {
508 return emitError(unknownLoc, "unknown result <id> : ")
509 << words[wordIndex];
510 }
511
512 operands.push_back(arg);
513 wordIndex++;
514 }
515
516 if (wordIndex < words.size()) {
517 auto arg = getValue(words[wordIndex]);
518
519 if (!arg) {
520 return emitError(unknownLoc, "unknown result <id> : ")
521 << words[wordIndex];
522 }
523
524 operands.push_back(arg);
525 wordIndex++;
526 }
527
528 bool isAlignedAttr = false;
529
530 if (wordIndex < words.size()) {
531 auto attrValue = words[wordIndex++];
532 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
533 static_cast<spirv::MemoryAccess>(attrValue));
534 attributes.push_back(
535 opBuilder.getNamedAttr(attributeName<MemoryAccess>(), attr));
536 isAlignedAttr = (attrValue == 2);
537 }
538
539 if (isAlignedAttr && wordIndex < words.size()) {
540 attributes.push_back(opBuilder.getNamedAttr(
541 "alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
542 }
543
544 if (wordIndex < words.size()) {
545 auto attrValue = words[wordIndex++];
546 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
547 static_cast<spirv::MemoryAccess>(attrValue));
548 attributes.push_back(opBuilder.getNamedAttr("source_memory_access", attr));
549 }
550
551 if (wordIndex < words.size()) {
552 attributes.push_back(opBuilder.getNamedAttr(
553 "source_alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
554 }
555
556 if (wordIndex != words.size()) {
557 return emitError(unknownLoc,
558 "found more operands than expected when deserializing "
559 "spirv::CopyMemoryOp, only ")
560 << wordIndex << " of " << words.size() << " processed";
561 }
562
563 Location loc = createFileLineColLoc(opBuilder);
564 spirv::CopyMemoryOp::create(opBuilder, loc, resultTypes, operands,
565 attributes);
566
567 return success();
568}
569
570template <>
572 ArrayRef<uint32_t> words) {
573 if (words.size() != 4) {
574 return emitError(unknownLoc,
575 "expected 4 words in GenericCastToPtrExplicitOp"
576 " but got : ")
577 << words.size();
578 }
579 SmallVector<Type, 1> resultTypes;
580 SmallVector<Value, 4> operands;
581 uint32_t valueID = 0;
582 auto type = getType(words[0]);
583
584 if (!type)
585 return emitError(unknownLoc, "unknown type result <id> : ") << words[0];
586 resultTypes.push_back(type);
587
588 valueID = words[1];
589
590 auto arg = getValue(words[2]);
591 if (!arg)
592 return emitError(unknownLoc, "unknown result <id> : ") << words[2];
593 operands.push_back(arg);
594
595 Location loc = createFileLineColLoc(opBuilder);
596 Operation *op = spirv::GenericCastToPtrExplicitOp::create(
597 opBuilder, loc, resultTypes, operands);
598 valueMap[valueID] = op->getResult(0);
599 return success();
600}
601
602// Pull in auto-generated Deserializer::dispatchToAutogenDeserialization() and
603// various Deserializer::processOp<...>() specializations.
604#define GET_DESERIALIZATION_FNS
605#include "mlir/Dialect/SPIRV/IR/SPIRVSerialization.inc"
606
607} // namespace spirv
608} // namespace mlir
return success()
static spirv::Opcode extractOpcode(uint32_t word)
Extracts the opcode from the given first word of a SPIR-V instruction.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
This class provides the API for ops that are known to be terminators.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition Operation.h:749
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition Operation.h:407
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, OpaqueProperties properties, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition Operation.cpp:67
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:96
Value materializeSpecConstantOperation(uint32_t resultID, spirv::Opcode enclosedOpcode, uint32_t resultTypeID, ArrayRef< uint32_t > enclosedOpOperands)
Materializes/emits an OpSpecConstantOp instruction.
Value getValue(uint32_t id)
Get the Value associated with a result <id>.
LogicalResult processGlobalVariable(ArrayRef< uint32_t > operands)
Processes the OpVariable instructions at current offset into binary.
std::optional< SpecConstOperationMaterializationInfo > getSpecConstantOperation(uint32_t id)
Gets the info needed to materialize the spec constant operation op associated with the given <id>.
LogicalResult processConstantNull(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpConstantNull instruction with the given operands.
LogicalResult processSpecConstantComposite(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSpecConstantComposite instruction with the given operands.
LogicalResult processInstruction(spirv::Opcode opcode, ArrayRef< uint32_t > operands, bool deferInstructions=true)
Processes a SPIR-V instruction with the given opcode and operands.
LogicalResult processBranchConditional(ArrayRef< uint32_t > operands)
spirv::GlobalVariableOp getGlobalVariable(uint32_t id)
Gets the global variable associated with a result <id> of OpVariable.
LogicalResult processGraphARM(ArrayRef< uint32_t > operands)
LogicalResult processLabel(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpLabel instruction with the given operands.
LogicalResult processExtInst(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpExtInst with given operands.
std::optional< spirv::GraphConstantARMOpMaterializationInfo > getGraphConstantARM(uint32_t id)
Gets the GraphConstantARM ID attribute and result type with the given result <id>.
std::optional< std::pair< Attribute, Type > > getConstant(uint32_t id)
Gets the constant's attribute and type associated with the given <id>.
LogicalResult processType(spirv::Opcode opcode, ArrayRef< uint32_t > operands)
Processes a SPIR-V type instruction with given opcode and operands and registers the type into module...
LogicalResult processLoopMerge(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpLoopMerge instruction with the given operands.
LogicalResult dispatchToExtensionSetAutogenDeserialization(StringRef extensionSetName, uint32_t instructionID, ArrayRef< uint32_t > words)
Dispatches the deserialization of extended instruction set operation based on the extended instructio...
LogicalResult sliceInstruction(spirv::Opcode &opcode, ArrayRef< uint32_t > &operands, std::optional< spirv::Opcode > expectedOpcode=std::nullopt)
Slices the first instruction out of binary and returns its opcode and operands via opcode and operand...
spirv::SpecConstantCompositeOp getSpecConstantComposite(uint32_t id)
Gets the composite specialization constant with the given result <id>.
spirv::EXTSpecConstantCompositeReplicateOp getSpecConstantCompositeReplicate(uint32_t id)
Gets the replicated composite specialization constant with the given result <id>.
LogicalResult processOp(ArrayRef< uint32_t > words)
Method to deserialize an operation in the SPIR-V dialect that is a mirror of an instruction in the SP...
Type getUndefType(uint32_t id)
Get the type associated with the result <id> of an OpUndef.
LogicalResult processSpecConstantCompositeReplicateEXT(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSpecConstantCompositeReplicateEXT instruction with the given operands.
LogicalResult processGraphEntryPointARM(ArrayRef< uint32_t > operands)
LogicalResult processFunction(ArrayRef< uint32_t > operands)
Creates a deserializer for the given SPIR-V binary module.
LogicalResult processDebugString(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpString instruction with the given operands.
LogicalResult processPhi(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpPhi instruction with the given operands.
void clearDebugLine()
Discontinues any source-level location information that might be active from a previous OpLine instru...
LogicalResult processTypeForwardPointer(ArrayRef< uint32_t > operands)
LogicalResult dispatchToAutogenDeserialization(spirv::Opcode opcode, ArrayRef< uint32_t > words)
Method to dispatch to the specialized deserialization function for an operation in SPIR-V dialect tha...
LogicalResult processOpWithoutGrammarAttr(ArrayRef< uint32_t > words, StringRef opName, bool hasResult, unsigned numOperands)
Processes a SPIR-V instruction from the given operands.
LogicalResult processGraphEndARM(ArrayRef< uint32_t > operands)
LogicalResult processConstantComposite(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpConstantComposite instruction with the given operands.
LogicalResult processBranch(ArrayRef< uint32_t > operands)
std::optional< std::pair< Attribute, Type > > getConstantCompositeReplicate(uint32_t id)
Gets the replicated composite constant's attribute and type associated with the given <id>.
LogicalResult processUndef(ArrayRef< uint32_t > operands)
Processes a OpUndef instruction.
LogicalResult processSpecConstantOperation(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSpecConstantOp instruction with the given operands.
LogicalResult processConstant(ArrayRef< uint32_t > operands, bool isSpec)
Processes a SPIR-V Op{|Spec}Constant instruction with the given operands.
Location createFileLineColLoc(OpBuilder opBuilder)
Creates a FileLineColLoc with the OpLine location information.
LogicalResult processGraphConstantARM(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpGraphConstantARM instruction with the given operands.
LogicalResult processConstantBool(bool isTrue, ArrayRef< uint32_t > operands, bool isSpec)
Processes a SPIR-V Op{|Spec}Constant{True|False} instruction with the given operands.
spirv::SpecConstantOp getSpecConstant(uint32_t id)
Gets the specialization constant with the given result <id>.
LogicalResult processConstantCompositeReplicateEXT(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpConstantCompositeReplicateEXT instruction with the given operands.
LogicalResult processSelectionMerge(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSelectionMerge instruction with the given operands.
LogicalResult processOpGraphSetOutputARM(ArrayRef< uint32_t > operands)
LogicalResult processDebugLine(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpLine instruction with the given operands.
constexpr StringRef attributeName()
StringRef decodeStringLiteral(ArrayRef< uint32_t > words, unsigned &wordIndex)
Decodes a string literal in words starting at wordIndex.
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Definition Utils.cpp:304
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This represents an operation in an abstracted form, suitable for use with the builder APIs.
void addOperands(ValueRange newOperands)
void addAttributes(ArrayRef< NamedAttribute > newAttributes)
Add an array of named attributes.
void addTypes(ArrayRef< Type > newTypes)