MLIR 23.0.0git
SPIRVOpDefinition.cpp
Go to the documentation of this file.
1//===- SPIRVOpDefinition.cpp - MLIR SPIR-V Op Definition Implementation ---===//
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// Defines the TableGen'erated SPIR-V op implementation in the SPIR-V dialect.
10// These are placed in a separate file to reduce the total amount of code in
11// SPIRVOps.cpp and make that file faster to recompile.
12//
13//===----------------------------------------------------------------------===//
14
16
17#include "SPIRVParsingUtils.h"
18
20
21namespace mlir::spirv {
22/// Returns true if the given op is a function-like op or nested in a
23/// function-like op without a module-like op in the middle.
25 if (!op)
26 return false;
28 return false;
29 if (isa<FunctionOpInterface>(op))
30 return true;
32}
33
34/// Returns true if the given op is a GraphARM op or nested in a
35/// GraphARM op without a module-like op in the middle.
37 if (!op)
38 return false;
40 return false;
41 if (isa<spirv::GraphARMOp>(op))
42 return true;
44}
45
46/// Returns true if the given op is an module-like op that maintains a symbol
47/// table.
49 return op && op->hasTrait<OpTrait::SymbolTable>();
50}
51
52/// Returns a boolean scalar or vector type matching the shape of the given
53/// type. Scalar inputs yield i1, vector inputs yield vector<Nxi1>.
54static Type getMatchingBoolType(Type operandType) {
55 Builder builder(operandType.getContext());
56 Type resultType = builder.getIntegerType(1);
57 if (auto vecType = dyn_cast<VectorType>(operandType))
58 return VectorType::get(vecType.getNumElements(), resultType);
59 return resultType;
60}
61
62static ParseResult parseImageOperands(OpAsmParser &parser,
63 spirv::ImageOperandsAttr &attr) {
64 // Expect image operands
65 if (parser.parseOptionalLSquare())
66 return success();
67
68 spirv::ImageOperands imageOperands;
69 if (parseEnumStrAttr(imageOperands, parser))
70 return failure();
71
72 attr = spirv::ImageOperandsAttr::get(parser.getContext(), imageOperands);
73
74 return parser.parseRSquare();
75}
76
77static void printImageOperands(OpAsmPrinter &printer, Operation *imageOp,
78 spirv::ImageOperandsAttr attr) {
79 if (attr) {
80 auto strImageOperands = stringifyImageOperands(attr.getValue());
81 printer << "[\"" << strImageOperands << "\"]";
82 }
83}
84
85/// Adapted from the cf.switch implementation.
86/// <cases> ::= `default` `:` bb-id (`(` ssa-use-and-type-list `)`)?
87/// ( `,` integer `:` bb-id (`(` ssa-use-and-type-list `)`)? )*
88static ParseResult parseSwitchOpCases(
89 OpAsmParser &parser, Type &selectorType, Block *&defaultTarget,
91 SmallVectorImpl<Type> &defaultOperandTypes, DenseIntElementsAttr &literals,
94 &targetOperands,
95 SmallVectorImpl<SmallVector<Type>> &targetOperandTypes) {
96 if (parser.parseKeyword("default") || parser.parseColon() ||
97 parser.parseSuccessor(defaultTarget))
98 return failure();
99 if (succeeded(parser.parseOptionalLParen())) {
100 if (parser.parseOperandList(defaultOperands, OpAsmParser::Delimiter::None,
101 /*allowResultNumber=*/false) ||
102 parser.parseColonTypeList(defaultOperandTypes) || parser.parseRParen())
103 return failure();
104 }
105
106 SmallVector<APInt> values;
107 unsigned bitWidth = selectorType.getIntOrFloatBitWidth();
108 while (succeeded(parser.parseOptionalComma())) {
109 int64_t value = 0;
110 if (failed(parser.parseInteger(value)))
111 return failure();
112 values.push_back(APInt(bitWidth, value, /*isSigned=*/true));
113
114 Block *target;
116 SmallVector<Type> operandTypes;
117 if (failed(parser.parseColon()) || failed(parser.parseSuccessor(target)))
118 return failure();
119 if (succeeded(parser.parseOptionalLParen())) {
120 if (failed(parser.parseOperandList(operands,
122 failed(parser.parseColonTypeList(operandTypes)) ||
123 failed(parser.parseRParen()))
124 return failure();
125 }
126 targets.push_back(target);
127 targetOperands.emplace_back(operands);
128 targetOperandTypes.emplace_back(operandTypes);
129 }
130
131 if (!values.empty()) {
132 ShapedType literalType =
133 VectorType::get(static_cast<int64_t>(values.size()), selectorType);
134 literals = DenseIntElementsAttr::get(literalType, values);
135 }
136 return success();
137}
138
139static void
140printSwitchOpCases(OpAsmPrinter &p, SwitchOp op, Type selectorType,
141 Block *defaultTarget, OperandRange defaultOperands,
142 TypeRange defaultOperandTypes, DenseIntElementsAttr literals,
143 SuccessorRange targets, OperandRangeRange targetOperands,
144 const TypeRangeRange &targetOperandTypes) {
145 p << " default: ";
146 p.printSuccessorAndUseList(defaultTarget, defaultOperands);
147
148 if (!literals)
149 return;
150
151 for (auto [index, literal] : llvm::enumerate(literals.getValues<APInt>())) {
152 p << ',';
153 p.printNewline();
154 p << " ";
155 p << literal.getLimitedValue();
156 p << ": ";
157 p.printSuccessorAndUseList(targets[index], targetOperands[index]);
158 }
159 p.printNewline();
160}
161
162} // namespace mlir::spirv
163
164// TablenGen'erated operation definitions.
165#define GET_OP_CLASSES
166#include "mlir/Dialect/SPIRV/IR/SPIRVOps.cpp.inc"
return success()
@ None
Zero or more operands with no delimiters.
virtual ParseResult parseColonTypeList(SmallVectorImpl< Type > &result)=0
Parse a colon followed by a type list, which must have at least one type.
MLIRContext * getContext() const
virtual ParseResult parseRParen()=0
Parse a ) token.
virtual ParseResult parseRSquare()=0
Parse a ] token.
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual ParseResult parseOptionalComma()=0
Parse a , token if present.
virtual ParseResult parseColon()=0
Parse a : token.
virtual ParseResult parseOptionalLParen()=0
Parse a ( token if present.
ParseResult parseKeyword(StringRef keyword)
Parse a given keyword.
virtual ParseResult parseOptionalLSquare()=0
Parse a [ token if present.
virtual void printNewline()
Print a newline and indent the printer to the start of the current operation/attribute/type.
Block represents an ordered list of Operations.
Definition Block.h:33
This class is a general helper class for creating context-global objects like types,...
Definition Builders.h:51
IntegerType getIntegerType(unsigned width)
Definition Builders.cpp:71
An attribute that represents a reference to a dense integer vector or tensor object.
static DenseIntElementsAttr get(const ShapedType &type, Arg &&arg)
Get an instance of a DenseIntElementsAttr with the given arguments.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual ParseResult parseSuccessor(Block *&dest)=0
Parse a single operation successor.
virtual ParseResult parseOperandList(SmallVectorImpl< UnresolvedOperand > &result, Delimiter delimiter=Delimiter::None, bool allowResultNumber=true, int requiredOperandCount=-1)=0
Parse zero or more SSA comma-separated operand references with a specified surrounding delimiter,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
virtual void printSuccessorAndUseList(Block *successor, ValueRange succOperands)=0
Print the successor and its operands.
A trait used to provide symbol table functionalities to a region operation.
This class represents a contiguous range of operand ranges, e.g.
Definition ValueRange.h:85
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:44
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
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition Operation.h:252
This class implements the successor iterators for Block.
This class provides an abstraction for a range of TypeRange.
Definition TypeRange.h:107
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:40
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition Types.cpp:35
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
Definition Types.cpp:124
static bool isNestedInGraphARMOpInterface(Operation *op)
Returns true if the given op is a GraphARM op or nested in a GraphARM op without a module-like op in ...
ParseResult parseEnumStrAttr(EnumClass &value, OpAsmParser &parser, StringRef attrName=spirv::attributeName< EnumClass >())
Parses the next string attribute in parser as an enumerant of the given EnumClass.
static bool isDirectInModuleLikeOp(Operation *op)
Returns true if the given op is an module-like op that maintains a symbol table.
static ParseResult parseSwitchOpCases(OpAsmParser &parser, Type &selectorType, Block *&defaultTarget, SmallVectorImpl< OpAsmParser::UnresolvedOperand > &defaultOperands, SmallVectorImpl< Type > &defaultOperandTypes, DenseIntElementsAttr &literals, SmallVectorImpl< Block * > &targets, SmallVectorImpl< SmallVector< OpAsmParser::UnresolvedOperand > > &targetOperands, SmallVectorImpl< SmallVector< Type > > &targetOperandTypes)
Adapted from the cf.switch implementation.
static void printImageOperands(OpAsmPrinter &printer, Operation *imageOp, spirv::ImageOperandsAttr attr)
static bool isNestedInFunctionOpInterface(Operation *op)
Returns true if the given op is a function-like op or nested in a function-like op without a module-l...
static ParseResult parseImageOperands(OpAsmParser &parser, spirv::ImageOperandsAttr &attr)
static Type getMatchingBoolType(Type operandType)
Returns a boolean scalar or vector type matching the shape of the given type.
static void printSwitchOpCases(OpAsmPrinter &p, SwitchOp op, Type selectorType, Block *defaultTarget, OperandRange defaultOperands, TypeRange defaultOperandTypes, DenseIntElementsAttr literals, SuccessorRange targets, OperandRangeRange targetOperands, const TypeRangeRange &targetOperandTypes)