20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/Support/Debug.h"
27#define DEBUG_TYPE "spirv-deserialization"
35 return static_cast<spirv::Opcode
>(word & 0xffff);
45 return spirv::ConstantOp::create(opBuilder, unknownLoc, constInfo->second,
48 if (std::optional<std::pair<Attribute, Type>> constCompositeReplicateInfo =
50 return spirv::EXTConstantCompositeReplicateOp::create(
51 opBuilder, unknownLoc, constCompositeReplicateInfo->second,
52 constCompositeReplicateInfo->first);
56 spirv::AddressOfOp::create(opBuilder, unknownLoc, varOp.getType(),
57 SymbolRefAttr::get(varOp.getOperation()));
58 return addressOfOp.getPointer();
61 auto referenceOfOp = spirv::ReferenceOfOp::create(
62 opBuilder, unknownLoc, constOp.getDefaultValue().getType(),
63 SymbolRefAttr::get(constOp.getOperation()));
64 return referenceOfOp.getReference();
66 if (SpecConstantCompositeOp specConstCompositeOp =
68 auto referenceOfOp = spirv::ReferenceOfOp::create(
69 opBuilder, unknownLoc, specConstCompositeOp.getType(),
70 SymbolRefAttr::get(specConstCompositeOp.getOperation()));
71 return referenceOfOp.getReference();
73 if (
auto specConstCompositeReplicateOp =
75 auto referenceOfOp = spirv::ReferenceOfOp::create(
76 opBuilder, unknownLoc, specConstCompositeReplicateOp.getType(),
77 SymbolRefAttr::get(specConstCompositeReplicateOp.getOperation()));
78 return referenceOfOp.getReference();
82 id, specConstOperationInfo->enclodesOpcode,
83 specConstOperationInfo->resultTypeID,
84 specConstOperationInfo->enclosedOpOperands);
87 return spirv::UndefOp::create(opBuilder, unknownLoc, undef);
89 if (std::optional<spirv::GraphConstantARMOpMaterializationInfo>
91 IntegerAttr graphConstantID = graphConstantARMInfo->graphConstantID;
92 Type resultType = graphConstantARMInfo->resultType;
93 return spirv::GraphConstantARMOp::create(opBuilder, unknownLoc, resultType,
96 return valueMap.lookup(
id);
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)
113 uint32_t wordCount = binary[curOffset] >> 16;
116 return emitError(unknownLoc,
"word count cannot be zero");
118 uint32_t nextOffset = curOffset + wordCount;
119 if (nextOffset > binarySize)
120 return emitError(unknownLoc,
"insufficient words for the last instruction");
123 operands = binary.slice(curOffset + 1, wordCount - 1);
124 curOffset = nextOffset;
135 size_t binarySize = binary.size();
136 auto isNextContinuation = [&]() {
137 if (curOffset >= binarySize)
139 uint32_t wordCount = binary[curOffset] >> 16;
140 if (wordCount == 0 || curOffset + wordCount > binarySize)
145 if (!isNextContinuation())
148 mergedStorage.assign(operands);
150 spirv::Opcode contOpcode;
154 llvm::append_range(mergedStorage, contOperands);
155 }
while (isNextContinuation());
156 operands = mergedStorage;
161 LLVM_DEBUG(logger.startLine() <<
"[inst] processing instruction "
162 << spirv::stringifyOpcode(opcode) <<
"\n");
170 case spirv::Opcode::OpCapability:
171 return processCapability(operands);
172 case spirv::Opcode::OpExtension:
173 return processExtension(operands);
174 case spirv::Opcode::OpExtInst:
176 case spirv::Opcode::OpExtInstImport:
177 return processExtInstImport(operands);
178 case spirv::Opcode::OpMemberName:
179 return processMemberName(operands);
180 case spirv::Opcode::OpMemoryModel:
181 return processMemoryModel(operands);
182 case spirv::Opcode::OpEntryPoint:
183 case spirv::Opcode::OpExecutionMode:
184 case spirv::Opcode::OpExecutionModeId:
185 if (deferInstructions) {
186 deferredInstructions.emplace_back(opcode, operands);
190 case spirv::Opcode::OpVariable:
191 if (isa<spirv::ModuleOp>(opBuilder.getBlock()->getParentOp())) {
195 case spirv::Opcode::OpLine:
197 case spirv::Opcode::OpNoLine:
200 case spirv::Opcode::OpName:
201 return processName(operands);
202 case spirv::Opcode::OpString:
204 case spirv::Opcode::OpModuleProcessed:
205 case spirv::Opcode::OpSource:
206 case spirv::Opcode::OpSourceContinued:
207 case spirv::Opcode::OpSourceExtension:
211 case spirv::Opcode::OpTypeVoid:
212 case spirv::Opcode::OpTypeBool:
213 case spirv::Opcode::OpTypeInt:
214 case spirv::Opcode::OpTypeFloat:
215 case spirv::Opcode::OpTypeVector:
216 case spirv::Opcode::OpTypeMatrix:
217 case spirv::Opcode::OpTypeArray:
218 case spirv::Opcode::OpTypeFunction:
219 case spirv::Opcode::OpTypeImage:
220 case spirv::Opcode::OpTypeSampler:
221 case spirv::Opcode::OpTypeNamedBarrier:
222 case spirv::Opcode::OpTypeSampledImage:
223 case spirv::Opcode::OpTypeRuntimeArray:
224 case spirv::Opcode::OpTypeStruct:
225 case spirv::Opcode::OpTypePointer:
226 case spirv::Opcode::OpTypeTensorARM:
227 case spirv::Opcode::OpTypeGraphARM:
228 case spirv::Opcode::OpTypeCooperativeMatrixKHR:
230 case spirv::Opcode::OpTypeForwardPointer:
232 case spirv::Opcode::OpConstant:
234 case spirv::Opcode::OpSpecConstant:
236 case spirv::Opcode::OpConstantComposite:
238 case spirv::Opcode::OpConstantCompositeReplicateEXT:
240 case spirv::Opcode::OpSpecConstantComposite:
242 case spirv::Opcode::OpSpecConstantCompositeReplicateEXT:
244 case spirv::Opcode::OpSpecConstantOp:
246 case spirv::Opcode::OpConstantTrue:
248 case spirv::Opcode::OpSpecConstantTrue:
250 case spirv::Opcode::OpConstantFalse:
252 case spirv::Opcode::OpSpecConstantFalse:
254 case spirv::Opcode::OpConstantNull:
256 case spirv::Opcode::OpGraphConstantARM:
258 case spirv::Opcode::OpDecorate:
259 case spirv::Opcode::OpDecorateId:
260 return processDecoration(operands);
261 case spirv::Opcode::OpMemberDecorate:
262 return processMemberDecoration(operands);
263 case spirv::Opcode::OpFunction:
265 case spirv::Opcode::OpGraphEntryPointARM:
266 if (deferInstructions) {
267 deferredInstructions.emplace_back(opcode, operands);
271 case spirv::Opcode::OpGraphARM:
273 case spirv::Opcode::OpGraphSetOutputARM:
275 case spirv::Opcode::OpGraphEndARM:
277 case spirv::Opcode::OpLabel:
279 case spirv::Opcode::OpBranch:
281 case spirv::Opcode::OpBranchConditional:
283 case spirv::Opcode::OpSelectionMerge:
285 case spirv::Opcode::OpLoopMerge:
287 case spirv::Opcode::OpPhi:
289 case spirv::Opcode::OpSwitch:
291 case spirv::Opcode::OpUndef:
301 unsigned numOperands) {
303 uint32_t valueID = 0;
305 size_t wordIndex = 0;
307 if (wordIndex >= words.size())
309 "expected result type <id> while deserializing for ")
313 auto type =
getType(words[wordIndex]);
315 return emitError(unknownLoc,
"unknown type result <id>: ")
317 resultTypes.push_back(type);
321 if (wordIndex >= words.size())
323 "expected result <id> while deserializing for ")
325 valueID = words[wordIndex];
333 size_t operandIndex = 0;
334 for (; operandIndex < numOperands && wordIndex < words.size();
335 ++operandIndex, ++wordIndex) {
336 auto arg =
getValue(words[wordIndex]);
338 return emitError(unknownLoc,
"unknown result <id>: ") << words[wordIndex];
339 operands.push_back(arg);
341 if (operandIndex != numOperands) {
344 "found less operands than expected when deserializing for ")
345 << opName <<
"; only " << operandIndex <<
" of " << numOperands
348 if (wordIndex != words.size()) {
351 "found more operands than expected when deserializing for ")
352 << opName <<
"; only " << wordIndex <<
" of " << words.size()
357 if (decorations.count(valueID)) {
358 auto attrs = decorations[valueID].getAttrs();
359 attributes.append(attrs.begin(), attrs.end());
380 if (operands.size() != 2) {
381 return emitError(unknownLoc,
"OpUndef instruction must have two operands");
383 auto type =
getType(operands[0]);
385 return emitError(unknownLoc,
"unknown type <id> with OpUndef instruction");
387 undefMap[operands[1]] = type;
392 if (operands.size() < 4) {
394 "OpExtInst must have at least 4 operands, result type "
395 "<id>, result <id>, set <id> and instruction opcode");
397 if (!extendedInstSets.count(operands[2])) {
398 return emitError(unknownLoc,
"undefined set <id> in OpExtInst");
401 slicedOperands.append(operands.begin(), std::next(operands.begin(), 2));
402 slicedOperands.append(std::next(operands.begin(), 4), operands.end());
404 extendedInstSets[operands[2]], operands[3], slicedOperands);
413 unsigned wordIndex = 0;
414 if (wordIndex >= words.size()) {
416 "missing Execution Model specification in OpEntryPoint");
418 auto execModel = spirv::ExecutionModelAttr::get(
419 context,
static_cast<spirv::ExecutionModel
>(words[wordIndex++]));
420 if (wordIndex >= words.size()) {
421 return emitError(unknownLoc,
"missing <id> in OpEntryPoint");
424 auto fnID = words[wordIndex++];
428 auto parsedFunc = getFunction(fnID);
430 return emitError(unknownLoc,
"no function matching <id> ") << fnID;
432 if (parsedFunc.getName() != fnName) {
436 if (!parsedFunc.getName().starts_with(
"spirv_fn_"))
438 "function name mismatch between OpEntryPoint "
439 "and OpFunction with <id> ")
440 << fnID <<
": " << fnName <<
" vs. " << parsedFunc.getName();
441 parsedFunc.setName(fnName);
444 while (wordIndex < words.size()) {
445 auto arg = getGlobalVariable(words[wordIndex]);
447 return emitError(unknownLoc,
"undefined result <id> ")
448 << words[wordIndex] <<
" while decoding OpEntryPoint";
450 interface.push_back(SymbolRefAttr::get(arg.getOperation()));
453 spirv::EntryPointOp::create(
454 opBuilder, unknownLoc, execModel,
455 SymbolRefAttr::get(opBuilder.getContext(), fnName),
456 opBuilder.getArrayAttr(interface));
463 unsigned wordIndex = 0;
464 if (wordIndex >= words.size()) {
466 "missing function result <id> in OpExecutionMode");
469 auto fnID = words[wordIndex++];
470 auto fn = getFunction(fnID);
472 return emitError(unknownLoc,
"no function matching <id> ") << fnID;
475 if (wordIndex >= words.size()) {
476 return emitError(unknownLoc,
"missing Execution Mode in OpExecutionMode");
478 auto execMode = spirv::ExecutionModeAttr::get(
479 context,
static_cast<spirv::ExecutionMode
>(words[wordIndex++]));
483 while (wordIndex < words.size()) {
484 attrListElems.push_back(opBuilder.getI32IntegerAttr(words[wordIndex++]));
486 auto values = opBuilder.getArrayAttr(attrListElems);
487 spirv::ExecutionModeOp::create(
488 opBuilder, unknownLoc,
489 SymbolRefAttr::get(opBuilder.getContext(), fn.getName()), execMode,
497 unsigned wordIndex = 0;
498 unsigned const wordsSize = words.size();
499 if (wordIndex >= wordsSize)
501 "missing function result <id> in OpExecutionModeId");
504 uint32_t fnID = words[wordIndex++];
505 FuncOp fn = getFunction(fnID);
507 return emitError(unknownLoc,
"no function matching <id> ") << fnID;
510 if (wordIndex >= wordsSize)
511 return emitError(unknownLoc,
"missing Execution Mode in OpExecutionModeId");
513 ExecutionModeAttr execMode = spirv::ExecutionModeAttr::get(
514 context,
static_cast<spirv::ExecutionMode
>(words[wordIndex++]));
518 while (wordIndex < words.size()) {
519 std::string
id = getSpecConstantSymbol(words[wordIndex++]);
522 ArrayAttr values = opBuilder.getArrayAttr(attrListElems);
523 spirv::ExecutionModeIdOp::create(
524 opBuilder, unknownLoc,
525 SymbolRefAttr::get(opBuilder.getContext(), fn.getName()), execMode,
533 if (operands.size() < 3) {
535 "OpFunctionCall must have at least 3 operands");
540 return emitError(unknownLoc,
"undefined result type from <id> ")
545 if (isVoidType(resultType))
546 resultType =
nullptr;
548 auto resultID = operands[1];
549 auto functionID = operands[2];
551 auto functionName = getFunctionSymbol(functionID);
554 for (
auto operand : llvm::drop_begin(operands, 3)) {
555 auto value = getValue(operand);
557 return emitError(unknownLoc,
"unknown <id> ")
558 << operand <<
" used by OpFunctionCall";
560 arguments.push_back(value);
563 auto opFunctionCall = spirv::FunctionCallOp::create(
564 opBuilder, unknownLoc, resultType,
565 SymbolRefAttr::get(opBuilder.getContext(), functionName), arguments);
568 valueMap[resultID] = opFunctionCall.getResult(0);
576 size_t wordIndex = 0;
580 if (wordIndex < words.size()) {
581 auto arg = getValue(words[wordIndex]);
584 return emitError(unknownLoc,
"unknown result <id> : ")
588 operands.push_back(arg);
592 if (wordIndex < words.size()) {
593 auto arg = getValue(words[wordIndex]);
596 return emitError(unknownLoc,
"unknown result <id> : ")
600 operands.push_back(arg);
604 bool isAlignedAttr =
false;
606 if (wordIndex < words.size()) {
607 auto attrValue = words[wordIndex++];
608 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
609 static_cast<spirv::MemoryAccess
>(attrValue));
610 attributes.push_back(
612 isAlignedAttr = (attrValue == 2);
615 if (isAlignedAttr && wordIndex < words.size()) {
616 attributes.push_back(opBuilder.getNamedAttr(
617 "alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
620 if (wordIndex < words.size()) {
621 auto attrValue = words[wordIndex++];
622 auto attr = opBuilder.getAttr<spirv::MemoryAccessAttr>(
623 static_cast<spirv::MemoryAccess
>(attrValue));
624 attributes.push_back(opBuilder.getNamedAttr(
"source_memory_access", attr));
627 if (wordIndex < words.size()) {
628 attributes.push_back(opBuilder.getNamedAttr(
629 "source_alignment", opBuilder.getI32IntegerAttr(words[wordIndex++])));
632 if (wordIndex != words.size()) {
634 "found more operands than expected when deserializing "
635 "spirv::CopyMemoryOp, only ")
636 << wordIndex <<
" of " << words.size() <<
" processed";
639 Location loc = createFileLineColLoc(opBuilder);
640 spirv::CopyMemoryOp::create(opBuilder, loc, resultTypes, operands,
649 if (words.size() != 4) {
651 "expected 4 words in GenericCastToPtrExplicitOp"
657 uint32_t valueID = 0;
661 return emitError(unknownLoc,
"unknown type result <id> : ") << words[0];
662 resultTypes.push_back(type);
666 auto arg = getValue(words[2]);
668 return emitError(unknownLoc,
"unknown result <id> : ") << words[2];
669 operands.push_back(arg);
671 Location loc = createFileLineColLoc(opBuilder);
672 Operation *op = spirv::GenericCastToPtrExplicitOp::create(
673 opBuilder, loc, resultTypes, operands);
680#define GET_DESERIALIZATION_FNS
681#include "mlir/Dialect/SPIRV/IR/SPIRVSerialization.inc"
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...
This class provides the API for ops that are known to be terminators.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
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...
void mergeLongCompositeContinuations(spirv::Opcode opcode, ArrayRef< uint32_t > &operands, SmallVectorImpl< uint32_t > &mergedStorage)
If opcode is a SPV_INTEL_long_composites splittable opcode and the next binary instruction(s) are mat...
LogicalResult processTypeForwardPointer(ArrayRef< uint32_t > operands)
LogicalResult processSwitch(ArrayRef< uint32_t > operands)
Processes a SPIR-V OpSwitch instruction with the given 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.
std::optional< spirv::Opcode > getContinuationOpcode(spirv::Opcode parent)
Returns the SPV_INTEL_long_composites continuation opcode that may follow parent, or std::nullopt if ...
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.
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)