MLIR 23.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 case spirv::Opcode::OpExecutionModeId:
151 if (deferInstructions) {
152 deferredInstructions.emplace_back(opcode, operands);
153 return success();
154 }
155 break;
156 case spirv::Opcode::OpVariable:
157 if (isa<spirv::ModuleOp>(opBuilder.getBlock()->getParentOp())) {
158 return processGlobalVariable(operands);
159 }
160 break;
161 case spirv::Opcode::OpLine:
162 return processDebugLine(operands);
163 case spirv::Opcode::OpNoLine:
165 return success();
166 case spirv::Opcode::OpName:
167 return processName(operands);
168 case spirv::Opcode::OpString:
169 return processDebugString(operands);
170 case spirv::Opcode::OpModuleProcessed:
171 case spirv::Opcode::OpSource:
172 case spirv::Opcode::OpSourceContinued:
173 case spirv::Opcode::OpSourceExtension:
174 // TODO: This is debug information embedded in the binary which should be
175 // translated into the spirv.module.
176 return success();
177 case spirv::Opcode::OpTypeVoid:
178 case spirv::Opcode::OpTypeBool:
179 case spirv::Opcode::OpTypeInt:
180 case spirv::Opcode::OpTypeFloat:
181 case spirv::Opcode::OpTypeVector:
182 case spirv::Opcode::OpTypeMatrix:
183 case spirv::Opcode::OpTypeArray:
184 case spirv::Opcode::OpTypeFunction:
185 case spirv::Opcode::OpTypeImage:
186 case spirv::Opcode::OpTypeSampledImage:
187 case spirv::Opcode::OpTypeRuntimeArray:
188 case spirv::Opcode::OpTypeStruct:
189 case spirv::Opcode::OpTypePointer:
190 case spirv::Opcode::OpTypeTensorARM:
191 case spirv::Opcode::OpTypeGraphARM:
192 case spirv::Opcode::OpTypeCooperativeMatrixKHR:
193 return processType(opcode, operands);
194 case spirv::Opcode::OpTypeForwardPointer:
195 return processTypeForwardPointer(operands);
196 case spirv::Opcode::OpConstant:
197 return processConstant(operands, /*isSpec=*/false);
198 case spirv::Opcode::OpSpecConstant:
199 return processConstant(operands, /*isSpec=*/true);
200 case spirv::Opcode::OpConstantComposite:
201 return processConstantComposite(operands);
202 case spirv::Opcode::OpConstantCompositeReplicateEXT:
204 case spirv::Opcode::OpSpecConstantComposite:
205 return processSpecConstantComposite(operands);
206 case spirv::Opcode::OpSpecConstantCompositeReplicateEXT:
208 case spirv::Opcode::OpSpecConstantOp:
209 return processSpecConstantOperation(operands);
210 case spirv::Opcode::OpConstantTrue:
211 return processConstantBool(/*isTrue=*/true, operands, /*isSpec=*/false);
212 case spirv::Opcode::OpSpecConstantTrue:
213 return processConstantBool(/*isTrue=*/true, operands, /*isSpec=*/true);
214 case spirv::Opcode::OpConstantFalse:
215 return processConstantBool(/*isTrue=*/false, operands, /*isSpec=*/false);
216 case spirv::Opcode::OpSpecConstantFalse:
217 return processConstantBool(/*isTrue=*/false, operands, /*isSpec=*/true);
218 case spirv::Opcode::OpConstantNull:
219 return processConstantNull(operands);
220 case spirv::Opcode::OpGraphConstantARM:
221 return processGraphConstantARM(operands);
222 case spirv::Opcode::OpDecorate:
223 return processDecoration(operands);
224 case spirv::Opcode::OpMemberDecorate:
225 return processMemberDecoration(operands);
226 case spirv::Opcode::OpFunction:
227 return processFunction(operands);
228 case spirv::Opcode::OpGraphEntryPointARM:
229 if (deferInstructions) {
230 deferredInstructions.emplace_back(opcode, operands);
231 return success();
232 }
233 return processGraphEntryPointARM(operands);
234 case spirv::Opcode::OpGraphARM:
235 return processGraphARM(operands);
236 case spirv::Opcode::OpGraphSetOutputARM:
237 return processOpGraphSetOutputARM(operands);
238 case spirv::Opcode::OpGraphEndARM:
239 return processGraphEndARM(operands);
240 case spirv::Opcode::OpLabel:
241 return processLabel(operands);
242 case spirv::Opcode::OpBranch:
243 return processBranch(operands);
244 case spirv::Opcode::OpBranchConditional:
245 return processBranchConditional(operands);
246 case spirv::Opcode::OpSelectionMerge:
247 return processSelectionMerge(operands);
248 case spirv::Opcode::OpLoopMerge:
249 return processLoopMerge(operands);
250 case spirv::Opcode::OpPhi:
251 return processPhi(operands);
252 case spirv::Opcode::OpSwitch:
253 return processSwitch(operands);
254 case spirv::Opcode::OpUndef:
255 return processUndef(operands);
256 default:
257 break;
258 }
259 return dispatchToAutogenDeserialization(opcode, operands);
260}
261
263 ArrayRef<uint32_t> words, StringRef opName, bool hasResult,
264 unsigned numOperands) {
265 SmallVector<Type, 1> resultTypes;
266 uint32_t valueID = 0;
267
268 size_t wordIndex = 0;
269 if (hasResult) {
270 if (wordIndex >= words.size())
271 return emitError(unknownLoc,
272 "expected result type <id> while deserializing for ")
273 << opName;
274
275 // Decode the type <id>
276 auto type = getType(words[wordIndex]);
277 if (!type)
278 return emitError(unknownLoc, "unknown type result <id>: ")
279 << words[wordIndex];
280 resultTypes.push_back(type);
281 ++wordIndex;
282
283 // Decode the result <id>
284 if (wordIndex >= words.size())
285 return emitError(unknownLoc,
286 "expected result <id> while deserializing for ")
287 << opName;
288 valueID = words[wordIndex];
289 ++wordIndex;
290 }
291
292 SmallVector<Value, 4> operands;
294
295 // Decode operands
296 size_t operandIndex = 0;
297 for (; operandIndex < numOperands && wordIndex < words.size();
298 ++operandIndex, ++wordIndex) {
299 auto arg = getValue(words[wordIndex]);
300 if (!arg)
301 return emitError(unknownLoc, "unknown result <id>: ") << words[wordIndex];
302 operands.push_back(arg);
303 }
304 if (operandIndex != numOperands) {
305 return emitError(
306 unknownLoc,
307 "found less operands than expected when deserializing for ")
308 << opName << "; only " << operandIndex << " of " << numOperands
309 << " processed";
310 }
311 if (wordIndex != words.size()) {
312 return emitError(
313 unknownLoc,
314 "found more operands than expected when deserializing for ")
315 << opName << "; only " << wordIndex << " of " << words.size()
316 << " processed";
317 }
318
319 // Attach attributes from decorations
320 if (decorations.count(valueID)) {
321 auto attrs = decorations[valueID].getAttrs();
322 attributes.append(attrs.begin(), attrs.end());
323 }
324
325 // Create the op and update bookkeeping maps
326 Location loc = createFileLineColLoc(opBuilder);
327 OperationState opState(loc, opName);
328 opState.addOperands(operands);
329 if (hasResult)
330 opState.addTypes(resultTypes);
331 opState.addAttributes(attributes);
332 Operation *op = opBuilder.create(opState);
333 if (hasResult)
334 valueMap[valueID] = op->getResult(0);
335
338
339 return success();
340}
341
343 if (operands.size() != 2) {
344 return emitError(unknownLoc, "OpUndef instruction must have two operands");
345 }
346 auto type = getType(operands[0]);
347 if (!type) {
348 return emitError(unknownLoc, "unknown type <id> with OpUndef instruction");
349 }
350 undefMap[operands[1]] = type;
351 return success();
352}
353
355 if (operands.size() < 4) {
356 return emitError(unknownLoc,
357 "OpExtInst must have at least 4 operands, result type "
358 "<id>, result <id>, set <id> and instruction opcode");
359 }
360 if (!extendedInstSets.count(operands[2])) {
361 return emitError(unknownLoc, "undefined set <id> in OpExtInst");
362 }
363 SmallVector<uint32_t, 4> slicedOperands;
364 slicedOperands.append(operands.begin(), std::next(operands.begin(), 2));
365 slicedOperands.append(std::next(operands.begin(), 4), operands.end());
367 extendedInstSets[operands[2]], operands[3], slicedOperands);
368}
369
370namespace mlir {
371namespace spirv {
372
373template <>
374LogicalResult
376 unsigned wordIndex = 0;
377 if (wordIndex >= words.size()) {
378 return emitError(unknownLoc,
379 "missing Execution Model specification in OpEntryPoint");
380 }
381 auto execModel = spirv::ExecutionModelAttr::get(
382 context, static_cast<spirv::ExecutionModel>(words[wordIndex++]));
383 if (wordIndex >= words.size()) {
384 return emitError(unknownLoc, "missing <id> in OpEntryPoint");
385 }
386 // Get the function <id>
387 auto fnID = words[wordIndex++];
388 // Get the function name
389 auto fnName = decodeStringLiteral(words, wordIndex);
390 // Verify that the function <id> matches the fnName
391 auto parsedFunc = getFunction(fnID);
392 if (!parsedFunc) {
393 return emitError(unknownLoc, "no function matching <id> ") << fnID;
394 }
395 if (parsedFunc.getName() != fnName) {
396 // The deserializer uses "spirv_fn_<id>" as the function name if the input
397 // SPIR-V blob does not contain a name for it. We should use a more clear
398 // indication for such case rather than relying on naming details.
399 if (!parsedFunc.getName().starts_with("spirv_fn_"))
400 return emitError(unknownLoc,
401 "function name mismatch between OpEntryPoint "
402 "and OpFunction with <id> ")
403 << fnID << ": " << fnName << " vs. " << parsedFunc.getName();
404 parsedFunc.setName(fnName);
405 }
407 while (wordIndex < words.size()) {
408 auto arg = getGlobalVariable(words[wordIndex]);
409 if (!arg) {
410 return emitError(unknownLoc, "undefined result <id> ")
411 << words[wordIndex] << " while decoding OpEntryPoint";
412 }
413 interface.push_back(SymbolRefAttr::get(arg.getOperation()));
414 wordIndex++;
415 }
416 spirv::EntryPointOp::create(
417 opBuilder, unknownLoc, execModel,
418 SymbolRefAttr::get(opBuilder.getContext(), fnName),
419 opBuilder.getArrayAttr(interface));
420 return success();
421}
422
423template <>
424LogicalResult
426 unsigned wordIndex = 0;
427 if (wordIndex >= words.size()) {
428 return emitError(unknownLoc,
429 "missing function result <id> in OpExecutionMode");
430 }
431 // Get the function <id> to get the name of the function
432 auto fnID = words[wordIndex++];
433 auto fn = getFunction(fnID);
434 if (!fn) {
435 return emitError(unknownLoc, "no function matching <id> ") << fnID;
436 }
437 // Get the Execution mode
438 if (wordIndex >= words.size()) {
439 return emitError(unknownLoc, "missing Execution Mode in OpExecutionMode");
440 }
441 auto execMode = spirv::ExecutionModeAttr::get(
442 context, static_cast<spirv::ExecutionMode>(words[wordIndex++]));
443
444 // Get the values
445 SmallVector<Attribute, 4> attrListElems;
446 while (wordIndex < words.size()) {
447 attrListElems.push_back(opBuilder.getI32IntegerAttr(words[wordIndex++]));
448 }
449 auto values = opBuilder.getArrayAttr(attrListElems);
450 spirv::ExecutionModeOp::create(
451 opBuilder, unknownLoc,
452 SymbolRefAttr::get(opBuilder.getContext(), fn.getName()), execMode,
453 values);
454 return success();
455}
456
457template <>
458LogicalResult
460 unsigned wordIndex = 0;
461 unsigned const wordsSize = words.size();
462 if (wordIndex >= wordsSize)
463 return emitError(unknownLoc,
464 "missing function result <id> in OpExecutionModeId");
465
466 // Get the function <id> to get the name of the function.
467 uint32_t fnID = words[wordIndex++];
468 FuncOp fn = getFunction(fnID);
469 if (!fn)
470 return emitError(unknownLoc, "no function matching <id> ") << fnID;
471
472 // Get the Execution mode.
473 if (wordIndex >= wordsSize)
474 return emitError(unknownLoc, "missing Execution Mode in OpExecutionModeId");
475
476 ExecutionModeAttr execMode = spirv::ExecutionModeAttr::get(
477 context, static_cast<spirv::ExecutionMode>(words[wordIndex++]));
478
479 // Get the values.
480 SmallVector<Attribute, 4> attrListElems;
481 while (wordIndex < words.size()) {
482 std::string id = getSpecConstantSymbol(words[wordIndex++]);
483 attrListElems.push_back(FlatSymbolRefAttr::get(context, id));
484 }
485 ArrayAttr values = opBuilder.getArrayAttr(attrListElems);
486 spirv::ExecutionModeIdOp::create(
487 opBuilder, unknownLoc,
488 SymbolRefAttr::get(opBuilder.getContext(), fn.getName()), execMode,
489 values);
490 return success();
491}
492
493template <>
494LogicalResult
496 if (operands.size() < 3) {
497 return emitError(unknownLoc,
498 "OpFunctionCall must have at least 3 operands");
499 }
500
501 Type resultType = getType(operands[0]);
502 if (!resultType) {
503 return emitError(unknownLoc, "undefined result type from <id> ")
504 << operands[0];
505 }
506
507 // Use null type to mean no result type.
508 if (isVoidType(resultType))
509 resultType = nullptr;
510
511 auto resultID = operands[1];
512 auto functionID = operands[2];
513
514 auto functionName = getFunctionSymbol(functionID);
515
516 SmallVector<Value, 4> arguments;
517 for (auto operand : llvm::drop_begin(operands, 3)) {
518 auto value = getValue(operand);
519 if (!value) {
520 return emitError(unknownLoc, "unknown <id> ")
521 << operand << " used by OpFunctionCall";
522 }
523 arguments.push_back(value);
524 }
525
526 auto opFunctionCall = spirv::FunctionCallOp::create(
527 opBuilder, unknownLoc, resultType,
528 SymbolRefAttr::get(opBuilder.getContext(), functionName), arguments);
529
530 if (resultType)
531 valueMap[resultID] = opFunctionCall.getResult(0);
532 return success();
533}
534
535template <>
536LogicalResult
538 SmallVector<Type, 1> resultTypes;
539 size_t wordIndex = 0;
540 SmallVector<Value, 4> operands;
542
543 if (wordIndex < words.size()) {
544 auto arg = getValue(words[wordIndex]);
545
546 if (!arg) {
547 return emitError(unknownLoc, "unknown result <id> : ")
548 << words[wordIndex];
549 }
550
551 operands.push_back(arg);
552 wordIndex++;
553 }
554
555 if (wordIndex < words.size()) {
556 auto arg = getValue(words[wordIndex]);
557
558 if (!arg) {
559 return emitError(unknownLoc, "unknown result <id> : ")
560 << words[wordIndex];
561 }
562
563 operands.push_back(arg);
564 wordIndex++;
565 }
566
567 bool isAlignedAttr = false;
568
569 if (wordIndex < words.size()) {
570 auto attrValue = words[wordIndex++];
571 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
572 static_cast<spirv::MemoryAccess>(attrValue));
573 attributes.push_back(
574 opBuilder.getNamedAttr(attributeName<MemoryAccess>(), attr));
575 isAlignedAttr = (attrValue == 2);
576 }
577
578 if (isAlignedAttr && wordIndex < words.size()) {
579 attributes.push_back(opBuilder.getNamedAttr(
580 "alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
581 }
582
583 if (wordIndex < words.size()) {
584 auto attrValue = words[wordIndex++];
585 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
586 static_cast<spirv::MemoryAccess>(attrValue));
587 attributes.push_back(opBuilder.getNamedAttr("source_memory_access", attr));
588 }
589
590 if (wordIndex < words.size()) {
591 attributes.push_back(opBuilder.getNamedAttr(
592 "source_alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
593 }
594
595 if (wordIndex != words.size()) {
596 return emitError(unknownLoc,
597 "found more operands than expected when deserializing "
598 "spirv::CopyMemoryOp, only ")
599 << wordIndex << " of " << words.size() << " processed";
600 }
601
602 Location loc = createFileLineColLoc(opBuilder);
603 spirv::CopyMemoryOp::create(opBuilder, loc, resultTypes, operands,
604 attributes);
605
606 return success();
607}
608
609template <>
611 ArrayRef<uint32_t> words) {
612 if (words.size() != 4) {
613 return emitError(unknownLoc,
614 "expected 4 words in GenericCastToPtrExplicitOp"
615 " but got : ")
616 << words.size();
617 }
618 SmallVector<Type, 1> resultTypes;
619 SmallVector<Value, 4> operands;
620 uint32_t valueID = 0;
621 auto type = getType(words[0]);
622
623 if (!type)
624 return emitError(unknownLoc, "unknown type result <id> : ") << words[0];
625 resultTypes.push_back(type);
626
627 valueID = words[1];
628
629 auto arg = getValue(words[2]);
630 if (!arg)
631 return emitError(unknownLoc, "unknown result <id> : ") << words[2];
632 operands.push_back(arg);
633
634 Location loc = createFileLineColLoc(opBuilder);
635 Operation *op = spirv::GenericCastToPtrExplicitOp::create(
636 opBuilder, loc, resultTypes, operands);
637 valueMap[valueID] = op->getResult(0);
638 return success();
639}
640
641// Pull in auto-generated Deserializer::dispatchToAutogenDeserialization() and
642// various Deserializer::processOp<...>() specializations.
643#define GET_DESERIALIZATION_FNS
644#include "mlir/Dialect/SPIRV/IR/SPIRVSerialization.inc"
645
646} // namespace spirv
647} // namespace mlir
return success()
static spirv::Opcode extractOpcode(uint32_t word)
Extracts the opcode from the given first word of a SPIR-V instruction.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
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:775
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition Operation.h:433
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, PropertyRef properties, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition Operation.cpp:66
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 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 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 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 dispatchToExtensionSetAutogenDeserialization(StringRef extensionSetName, uint32_t instructionID, ArrayRef< uint32_t > words)
Dispatches the deserialization of extended instruction set operation based on the extended instructio...
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 processSwitch(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSwitch instruction with the given operands.
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.
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:307
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)