/home/arjun/llvm-project/mlir/include/mlir/IR/OpImplementation.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- OpImplementation.h - Classes for implementing Op types ---*- 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 classes used by the implementation details of Op types. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #ifndef MLIR_IR_OPIMPLEMENTATION_H |
14 | | #define MLIR_IR_OPIMPLEMENTATION_H |
15 | | |
16 | | #include "mlir/IR/DialectInterface.h" |
17 | | #include "mlir/IR/OpDefinition.h" |
18 | | #include "llvm/ADT/Twine.h" |
19 | | #include "llvm/Support/SMLoc.h" |
20 | | #include "llvm/Support/raw_ostream.h" |
21 | | |
22 | | namespace mlir { |
23 | | |
24 | | class Builder; |
25 | | |
26 | | //===----------------------------------------------------------------------===// |
27 | | // OpAsmPrinter |
28 | | //===----------------------------------------------------------------------===// |
29 | | |
30 | | /// This is a pure-virtual base class that exposes the asmprinter hooks |
31 | | /// necessary to implement a custom print() method. |
32 | | class OpAsmPrinter { |
33 | | public: |
34 | 0 | OpAsmPrinter() {} |
35 | | virtual ~OpAsmPrinter(); |
36 | | virtual raw_ostream &getStream() const = 0; |
37 | | |
38 | | /// Print implementations for various things an operation contains. |
39 | | virtual void printOperand(Value value) = 0; |
40 | | virtual void printOperand(Value value, raw_ostream &os) = 0; |
41 | | |
42 | | /// Print a comma separated list of operands. |
43 | | template <typename ContainerType> |
44 | 0 | void printOperands(const ContainerType &container) { |
45 | 0 | printOperands(container.begin(), container.end()); |
46 | 0 | } Unexecuted instantiation: _ZN4mlir12OpAsmPrinter13printOperandsIN4llvm15MutableArrayRefINS_13BlockArgumentEEEEEvRKT_ Unexecuted instantiation: _ZN4mlir12OpAsmPrinter13printOperandsINS_12OperandRangeEEEvRKT_ |
47 | | |
48 | | /// Print a comma separated list of operands. |
49 | | template <typename IteratorType> |
50 | 0 | void printOperands(IteratorType it, IteratorType end) { |
51 | 0 | if (it == end) |
52 | 0 | return; |
53 | 0 | printOperand(*it); |
54 | 0 | for (++it; it != end; ++it) { |
55 | 0 | getStream() << ", "; |
56 | 0 | printOperand(*it); |
57 | 0 | } |
58 | 0 | } Unexecuted instantiation: _ZN4mlir12OpAsmPrinter13printOperandsIPNS_13BlockArgumentEEEvT_S4_ Unexecuted instantiation: _ZN4mlir12OpAsmPrinter13printOperandsIN4llvm6detail27indexed_accessor_range_baseINS_12OperandRangeEPNS_9OpOperandENS_5ValueES8_S8_E8iteratorEEEvT_SB_ |
59 | | virtual void printType(Type type) = 0; |
60 | | virtual void printAttribute(Attribute attr) = 0; |
61 | | |
62 | | /// Print the given attribute without its type. The corresponding parser must |
63 | | /// provide a valid type for the attribute. |
64 | | virtual void printAttributeWithoutType(Attribute attr) = 0; |
65 | | |
66 | | /// Print the given successor. |
67 | | virtual void printSuccessor(Block *successor) = 0; |
68 | | |
69 | | /// Print the successor and its operands. |
70 | | virtual void printSuccessorAndUseList(Block *successor, |
71 | | ValueRange succOperands) = 0; |
72 | | |
73 | | /// If the specified operation has attributes, print out an attribute |
74 | | /// dictionary with their values. elidedAttrs allows the client to ignore |
75 | | /// specific well known attributes, commonly used if the attribute value is |
76 | | /// printed some other way (like as a fixed operand). |
77 | | virtual void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs, |
78 | | ArrayRef<StringRef> elidedAttrs = {}) = 0; |
79 | | |
80 | | /// If the specified operation has attributes, print out an attribute |
81 | | /// dictionary prefixed with 'attributes'. |
82 | | virtual void |
83 | | printOptionalAttrDictWithKeyword(ArrayRef<NamedAttribute> attrs, |
84 | | ArrayRef<StringRef> elidedAttrs = {}) = 0; |
85 | | |
86 | | /// Print the entire operation with the default generic assembly form. |
87 | | virtual void printGenericOp(Operation *op) = 0; |
88 | | |
89 | | /// Prints a region. |
90 | | virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true, |
91 | | bool printBlockTerminators = true) = 0; |
92 | | |
93 | | /// Renumber the arguments for the specified region to the same names as the |
94 | | /// SSA values in namesToUse. This may only be used for IsolatedFromAbove |
95 | | /// operations. If any entry in namesToUse is null, the corresponding |
96 | | /// argument name is left alone. |
97 | | virtual void shadowRegionArgs(Region ®ion, ValueRange namesToUse) = 0; |
98 | | |
99 | | /// Prints an affine map of SSA ids, where SSA id names are used in place |
100 | | /// of dims/symbols. |
101 | | /// Operand values must come from single-result sources, and be valid |
102 | | /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol. |
103 | | virtual void printAffineMapOfSSAIds(AffineMapAttr mapAttr, |
104 | | ValueRange operands) = 0; |
105 | | |
106 | | /// Print an optional arrow followed by a type list. |
107 | | template <typename TypeRange> |
108 | | void printOptionalArrowTypeList(TypeRange &&types) { |
109 | | if (types.begin() != types.end()) |
110 | | printArrowTypeList(types); |
111 | | } |
112 | | template <typename TypeRange> |
113 | 0 | void printArrowTypeList(TypeRange &&types) { |
114 | 0 | auto &os = getStream() << " -> "; |
115 | 0 |
|
116 | 0 | bool wrapped = !llvm::hasSingleElement(types) || |
117 | 0 | (*types.begin()).template isa<FunctionType>(); |
118 | 0 | if (wrapped) |
119 | 0 | os << '('; |
120 | 0 | llvm::interleaveComma(types, *this); |
121 | 0 | if (wrapped) |
122 | 0 | os << ')'; |
123 | 0 | } |
124 | | |
125 | | /// Print the complete type of an operation in functional form. |
126 | 0 | void printFunctionalType(Operation *op) { |
127 | 0 | printFunctionalType(op->getOperandTypes(), op->getResultTypes()); |
128 | 0 | } |
129 | | /// Print the two given type ranges in a functional form. |
130 | | template <typename InputRangeT, typename ResultRangeT> |
131 | 0 | void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results) { |
132 | 0 | auto &os = getStream(); |
133 | 0 | os << "("; |
134 | 0 | llvm::interleaveComma(inputs, *this); |
135 | 0 | os << ")"; |
136 | 0 | printArrowTypeList(results); |
137 | 0 | } |
138 | | |
139 | | /// Print the given string as a symbol reference, i.e. a form representable by |
140 | | /// a SymbolRefAttr. A symbol reference is represented as a string prefixed |
141 | | /// with '@'. The reference is surrounded with ""'s and escaped if it has any |
142 | | /// special or non-printable characters in it. |
143 | | virtual void printSymbolName(StringRef symbolRef) = 0; |
144 | | |
145 | | private: |
146 | | OpAsmPrinter(const OpAsmPrinter &) = delete; |
147 | | void operator=(const OpAsmPrinter &) = delete; |
148 | | }; |
149 | | |
150 | | // Make the implementations convenient to use. |
151 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Value value) { |
152 | 0 | p.printOperand(value); |
153 | 0 | return p; |
154 | 0 | } |
155 | | |
156 | | template <typename T, |
157 | | typename std::enable_if<std::is_convertible<T &, ValueRange>::value && |
158 | | !std::is_convertible<T &, Value &>::value, |
159 | | T>::type * = nullptr> |
160 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &values) { |
161 | 0 | p.printOperands(values); |
162 | 0 | return p; |
163 | 0 | } Unexecuted instantiation: _ZN4mlirlsIN4llvm15MutableArrayRefINS_13BlockArgumentEEELPS4_0EEERNS_12OpAsmPrinterES7_RKT_ Unexecuted instantiation: _ZN4mlirlsINS_12OperandRangeELPS1_0EEERNS_12OpAsmPrinterES4_RKT_ |
164 | | |
165 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Type type) { |
166 | 0 | p.printType(type); |
167 | 0 | return p; |
168 | 0 | } |
169 | | |
170 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Attribute attr) { |
171 | 0 | p.printAttribute(attr); |
172 | 0 | return p; |
173 | 0 | } |
174 | | |
175 | | // Support printing anything that isn't convertible to one of the above types, |
176 | | // even if it isn't exactly one of them. For example, we want to print |
177 | | // FunctionType with the Type version above, not have it match this. |
178 | | template <typename T, typename std::enable_if< |
179 | | !std::is_convertible<T &, Value &>::value && |
180 | | !std::is_convertible<T &, Type &>::value && |
181 | | !std::is_convertible<T &, Attribute &>::value && |
182 | | !std::is_convertible<T &, ValueRange>::value && |
183 | | !llvm::is_one_of<T, bool>::value, |
184 | | T>::type * = nullptr> |
185 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &other) { |
186 | 0 | p.getStream() << other; |
187 | 0 | return p; |
188 | 0 | } Unexecuted instantiation: _ZN4mlirlsIN4llvm9StringRefELPS2_0EEERNS_12OpAsmPrinterES5_RKT_ Unexecuted instantiation: _ZN4mlirlsIA2_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIPKcLPS2_0EEERNS_12OpAsmPrinterES5_RKT_ Unexecuted instantiation: _ZN4mlirlsIA5_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIlLPl0EEERNS_12OpAsmPrinterES3_RKT_ Unexecuted instantiation: _ZN4mlirlsIA7_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA11_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA6_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA13_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA8_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIN4llvm5APIntELPS2_0EEERNS_12OpAsmPrinterES5_RKT_ Unexecuted instantiation: _ZN4mlirlsIA10_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA14_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA20_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA21_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA18_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIcLPc0EEERNS_12OpAsmPrinterES3_RKT_ Unexecuted instantiation: _ZN4mlirlsIA4_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA3_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA17_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIjLPj0EEERNS_12OpAsmPrinterES3_RKT_ Unexecuted instantiation: _ZN4mlirlsIA22_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA12_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA15_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsIA16_cLPS1_0EEERNS_12OpAsmPrinterES4_RKT_ Unexecuted instantiation: _ZN4mlirlsINS_13OperationNameELPS1_0EEERNS_12OpAsmPrinterES4_RKT_ |
189 | | |
190 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, bool value) { |
191 | 0 | return p << (value ? StringRef("true") : "false"); |
192 | 0 | } |
193 | | |
194 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Block *value) { |
195 | 0 | p.printSuccessor(value); |
196 | 0 | return p; |
197 | 0 | } |
198 | | |
199 | | template <typename ValueRangeT> |
200 | | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, |
201 | 0 | const ValueTypeRange<ValueRangeT> &types) { |
202 | 0 | llvm::interleaveComma(types, p); |
203 | 0 | return p; |
204 | 0 | } |
205 | 0 | inline OpAsmPrinter &operator<<(OpAsmPrinter &p, ArrayRef<Type> types) { |
206 | 0 | llvm::interleaveComma(types, p); |
207 | 0 | return p; |
208 | 0 | } |
209 | | |
210 | | //===----------------------------------------------------------------------===// |
211 | | // OpAsmParser |
212 | | //===----------------------------------------------------------------------===// |
213 | | |
214 | | /// The OpAsmParser has methods for interacting with the asm parser: parsing |
215 | | /// things from it, emitting errors etc. It has an intentionally high-level API |
216 | | /// that is designed to reduce/constrain syntax innovation in individual |
217 | | /// operations. |
218 | | /// |
219 | | /// For example, consider an op like this: |
220 | | /// |
221 | | /// %x = load %p[%1, %2] : memref<...> |
222 | | /// |
223 | | /// The "%x = load" tokens are already parsed and therefore invisible to the |
224 | | /// custom op parser. This can be supported by calling `parseOperandList` to |
225 | | /// parse the %p, then calling `parseOperandList` with a `SquareDelimiter` to |
226 | | /// parse the indices, then calling `parseColonTypeList` to parse the result |
227 | | /// type. |
228 | | /// |
229 | | class OpAsmParser { |
230 | | public: |
231 | | virtual ~OpAsmParser(); |
232 | | |
233 | | /// Emit a diagnostic at the specified location and return failure. |
234 | | virtual InFlightDiagnostic emitError(llvm::SMLoc loc, |
235 | | const Twine &message = {}) = 0; |
236 | | |
237 | | /// Return a builder which provides useful access to MLIRContext, global |
238 | | /// objects like types and attributes. |
239 | | virtual Builder &getBuilder() const = 0; |
240 | | |
241 | | /// Get the location of the next token and store it into the argument. This |
242 | | /// always succeeds. |
243 | | virtual llvm::SMLoc getCurrentLocation() = 0; |
244 | 0 | ParseResult getCurrentLocation(llvm::SMLoc *loc) { |
245 | 0 | *loc = getCurrentLocation(); |
246 | 0 | return success(); |
247 | 0 | } |
248 | | |
249 | | /// Return the name of the specified result in the specified syntax, as well |
250 | | /// as the sub-element in the name. It returns an empty string and ~0U for |
251 | | /// invalid result numbers. For example, in this operation: |
252 | | /// |
253 | | /// %x, %y:2, %z = foo.op |
254 | | /// |
255 | | /// getResultName(0) == {"x", 0 } |
256 | | /// getResultName(1) == {"y", 0 } |
257 | | /// getResultName(2) == {"y", 1 } |
258 | | /// getResultName(3) == {"z", 0 } |
259 | | /// getResultName(4) == {"", ~0U } |
260 | | virtual std::pair<StringRef, unsigned> |
261 | | getResultName(unsigned resultNo) const = 0; |
262 | | |
263 | | /// Return the number of declared SSA results. This returns 4 for the foo.op |
264 | | /// example in the comment for `getResultName`. |
265 | | virtual size_t getNumResults() const = 0; |
266 | | |
267 | | /// Return the location of the original name token. |
268 | | virtual llvm::SMLoc getNameLoc() const = 0; |
269 | | |
270 | | // These methods emit an error and return failure or success. This allows |
271 | | // these to be chained together into a linear sequence of || expressions in |
272 | | // many cases. |
273 | | |
274 | | /// Parse an operation in its generic form. |
275 | | /// The parsed operation is parsed in the current context and inserted in the |
276 | | /// provided block and insertion point. The results produced by this operation |
277 | | /// aren't mapped to any named value in the parser. Returns nullptr on |
278 | | /// failure. |
279 | | virtual Operation *parseGenericOperation(Block *insertBlock, |
280 | | Block::iterator insertPt) = 0; |
281 | | |
282 | | //===--------------------------------------------------------------------===// |
283 | | // Token Parsing |
284 | | //===--------------------------------------------------------------------===// |
285 | | |
286 | | /// Parse a '->' token. |
287 | | virtual ParseResult parseArrow() = 0; |
288 | | |
289 | | /// Parse a '->' token if present |
290 | | virtual ParseResult parseOptionalArrow() = 0; |
291 | | |
292 | | /// Parse a `:` token. |
293 | | virtual ParseResult parseColon() = 0; |
294 | | |
295 | | /// Parse a `:` token if present. |
296 | | virtual ParseResult parseOptionalColon() = 0; |
297 | | |
298 | | /// Parse a `,` token. |
299 | | virtual ParseResult parseComma() = 0; |
300 | | |
301 | | /// Parse a `,` token if present. |
302 | | virtual ParseResult parseOptionalComma() = 0; |
303 | | |
304 | | /// Parse a `=` token. |
305 | | virtual ParseResult parseEqual() = 0; |
306 | | |
307 | | /// Parse a '<' token. |
308 | | virtual ParseResult parseLess() = 0; |
309 | | |
310 | | /// Parse a '>' token. |
311 | | virtual ParseResult parseGreater() = 0; |
312 | | |
313 | | /// Parse a given keyword. |
314 | 0 | ParseResult parseKeyword(StringRef keyword, const Twine &msg = "") { |
315 | 0 | auto loc = getCurrentLocation(); |
316 | 0 | if (parseOptionalKeyword(keyword)) |
317 | 0 | return emitError(loc, "expected '") << keyword << "'" << msg; |
318 | 0 | return success(); |
319 | 0 | } |
320 | | |
321 | | /// Parse a keyword into 'keyword'. |
322 | 0 | ParseResult parseKeyword(StringRef *keyword) { |
323 | 0 | auto loc = getCurrentLocation(); |
324 | 0 | if (parseOptionalKeyword(keyword)) |
325 | 0 | return emitError(loc, "expected valid keyword"); |
326 | 0 | return success(); |
327 | 0 | } |
328 | | |
329 | | /// Parse the given keyword if present. |
330 | | virtual ParseResult parseOptionalKeyword(StringRef keyword) = 0; |
331 | | |
332 | | /// Parse a keyword, if present, into 'keyword'. |
333 | | virtual ParseResult parseOptionalKeyword(StringRef *keyword) = 0; |
334 | | |
335 | | /// Parse a `(` token. |
336 | | virtual ParseResult parseLParen() = 0; |
337 | | |
338 | | /// Parse a `(` token if present. |
339 | | virtual ParseResult parseOptionalLParen() = 0; |
340 | | |
341 | | /// Parse a `)` token. |
342 | | virtual ParseResult parseRParen() = 0; |
343 | | |
344 | | /// Parse a `)` token if present. |
345 | | virtual ParseResult parseOptionalRParen() = 0; |
346 | | |
347 | | /// Parse a `[` token. |
348 | | virtual ParseResult parseLSquare() = 0; |
349 | | |
350 | | /// Parse a `[` token if present. |
351 | | virtual ParseResult parseOptionalLSquare() = 0; |
352 | | |
353 | | /// Parse a `]` token. |
354 | | virtual ParseResult parseRSquare() = 0; |
355 | | |
356 | | /// Parse a `]` token if present. |
357 | | virtual ParseResult parseOptionalRSquare() = 0; |
358 | | |
359 | | /// Parse a `...` token if present; |
360 | | virtual ParseResult parseOptionalEllipsis() = 0; |
361 | | |
362 | | //===--------------------------------------------------------------------===// |
363 | | // Attribute Parsing |
364 | | //===--------------------------------------------------------------------===// |
365 | | |
366 | | /// Parse an arbitrary attribute and return it in result. This also adds the |
367 | | /// attribute to the specified attribute list with the specified name. |
368 | | ParseResult parseAttribute(Attribute &result, StringRef attrName, |
369 | 0 | NamedAttrList &attrs) { |
370 | 0 | return parseAttribute(result, Type(), attrName, attrs); |
371 | 0 | } |
372 | | |
373 | | /// Parse an attribute of a specific kind and type. |
374 | | template <typename AttrType> |
375 | | ParseResult parseAttribute(AttrType &result, StringRef attrName, |
376 | 0 | NamedAttrList &attrs) { |
377 | 0 | return parseAttribute(result, Type(), attrName, attrs); |
378 | 0 | } Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_13AffineMapAttrEEENS_11ParseResultERT_N4llvm9StringRefERNS_13NamedAttrListE Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_14IntegerSetAttrEEENS_11ParseResultERT_N4llvm9StringRefERNS_13NamedAttrListE |
379 | | |
380 | | /// Parse an arbitrary attribute of a given type and return it in result. This |
381 | | /// also adds the attribute to the specified attribute list with the specified |
382 | | /// name. |
383 | | virtual ParseResult parseAttribute(Attribute &result, Type type, |
384 | | StringRef attrName, |
385 | | NamedAttrList &attrs) = 0; |
386 | | |
387 | | /// Parse an attribute of a specific kind and type. |
388 | | template <typename AttrType> |
389 | | ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName, |
390 | 0 | NamedAttrList &attrs) { |
391 | 0 | llvm::SMLoc loc = getCurrentLocation(); |
392 | 0 |
|
393 | 0 | // Parse any kind of attribute. |
394 | 0 | Attribute attr; |
395 | 0 | if (parseAttribute(attr, type, attrName, attrs)) |
396 | 0 | return failure(); |
397 | 0 | |
398 | 0 | // Check for the right kind of attribute. |
399 | 0 | result = attr.dyn_cast<AttrType>(); |
400 | 0 | if (!result) |
401 | 0 | return emitError(loc, "invalid kind of attribute specified"); |
402 | 0 | |
403 | 0 | return success(); |
404 | 0 | } Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_13AffineMapAttrEEENS_11ParseResultERT_NS_4TypeEN4llvm9StringRefERNS_13NamedAttrListE Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_11IntegerAttrEEENS_11ParseResultERT_NS_4TypeEN4llvm9StringRefERNS_13NamedAttrListE Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_14IntegerSetAttrEEENS_11ParseResultERT_NS_4TypeEN4llvm9StringRefERNS_13NamedAttrListE Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_10StringAttrEEENS_11ParseResultERT_NS_4TypeEN4llvm9StringRefERNS_13NamedAttrListE Unexecuted instantiation: _ZN4mlir11OpAsmParser14parseAttributeINS_17FlatSymbolRefAttrEEENS_11ParseResultERT_NS_4TypeEN4llvm9StringRefERNS_13NamedAttrListE |
405 | | |
406 | | /// Parse a named dictionary into 'result' if it is present. |
407 | | virtual ParseResult parseOptionalAttrDict(NamedAttrList &result) = 0; |
408 | | |
409 | | /// Parse a named dictionary into 'result' if the `attributes` keyword is |
410 | | /// present. |
411 | | virtual ParseResult |
412 | | parseOptionalAttrDictWithKeyword(NamedAttrList &result) = 0; |
413 | | |
414 | | /// Parse an affine map instance into 'map'. |
415 | | virtual ParseResult parseAffineMap(AffineMap &map) = 0; |
416 | | |
417 | | /// Parse an integer set instance into 'set'. |
418 | | virtual ParseResult printIntegerSet(IntegerSet &set) = 0; |
419 | | |
420 | | //===--------------------------------------------------------------------===// |
421 | | // Identifier Parsing |
422 | | //===--------------------------------------------------------------------===// |
423 | | |
424 | | /// Parse an @-identifier and store it (without the '@' symbol) in a string |
425 | | /// attribute named 'attrName'. |
426 | | ParseResult parseSymbolName(StringAttr &result, StringRef attrName, |
427 | 0 | NamedAttrList &attrs) { |
428 | 0 | if (failed(parseOptionalSymbolName(result, attrName, attrs))) |
429 | 0 | return emitError(getCurrentLocation()) |
430 | 0 | << "expected valid '@'-identifier for symbol name"; |
431 | 0 | return success(); |
432 | 0 | } |
433 | | |
434 | | /// Parse an optional @-identifier and store it (without the '@' symbol) in a |
435 | | /// string attribute named 'attrName'. |
436 | | virtual ParseResult parseOptionalSymbolName(StringAttr &result, |
437 | | StringRef attrName, |
438 | | NamedAttrList &attrs) = 0; |
439 | | |
440 | | //===--------------------------------------------------------------------===// |
441 | | // Operand Parsing |
442 | | //===--------------------------------------------------------------------===// |
443 | | |
444 | | /// This is the representation of an operand reference. |
445 | | struct OperandType { |
446 | | llvm::SMLoc location; // Location of the token. |
447 | | StringRef name; // Value name, e.g. %42 or %abc |
448 | | unsigned number; // Number, e.g. 12 for an operand like %xyz#12 |
449 | | }; |
450 | | |
451 | | /// Parse a single operand. |
452 | | virtual ParseResult parseOperand(OperandType &result) = 0; |
453 | | |
454 | | /// Parse a single operand if present. |
455 | | virtual OptionalParseResult parseOptionalOperand(OperandType &result) = 0; |
456 | | |
457 | | /// These are the supported delimiters around operand lists and region |
458 | | /// argument lists, used by parseOperandList and parseRegionArgumentList. |
459 | | enum class Delimiter { |
460 | | /// Zero or more operands with no delimiters. |
461 | | None, |
462 | | /// Parens surrounding zero or more operands. |
463 | | Paren, |
464 | | /// Square brackets surrounding zero or more operands. |
465 | | Square, |
466 | | /// Parens supporting zero or more operands, or nothing. |
467 | | OptionalParen, |
468 | | /// Square brackets supporting zero or more ops, or nothing. |
469 | | OptionalSquare, |
470 | | }; |
471 | | |
472 | | /// Parse zero or more SSA comma-separated operand references with a specified |
473 | | /// surrounding delimiter, and an optional required operand count. |
474 | | virtual ParseResult |
475 | | parseOperandList(SmallVectorImpl<OperandType> &result, |
476 | | int requiredOperandCount = -1, |
477 | | Delimiter delimiter = Delimiter::None) = 0; |
478 | | ParseResult parseOperandList(SmallVectorImpl<OperandType> &result, |
479 | 0 | Delimiter delimiter) { |
480 | 0 | return parseOperandList(result, /*requiredOperandCount=*/-1, delimiter); |
481 | 0 | } |
482 | | |
483 | | /// Parse zero or more trailing SSA comma-separated trailing operand |
484 | | /// references with a specified surrounding delimiter, and an optional |
485 | | /// required operand count. A leading comma is expected before the operands. |
486 | | virtual ParseResult |
487 | | parseTrailingOperandList(SmallVectorImpl<OperandType> &result, |
488 | | int requiredOperandCount = -1, |
489 | | Delimiter delimiter = Delimiter::None) = 0; |
490 | | ParseResult parseTrailingOperandList(SmallVectorImpl<OperandType> &result, |
491 | 0 | Delimiter delimiter) { |
492 | 0 | return parseTrailingOperandList(result, /*requiredOperandCount=*/-1, |
493 | 0 | delimiter); |
494 | 0 | } |
495 | | |
496 | | /// Resolve an operand to an SSA value, emitting an error on failure. |
497 | | virtual ParseResult resolveOperand(const OperandType &operand, Type type, |
498 | | SmallVectorImpl<Value> &result) = 0; |
499 | | |
500 | | /// Resolve a list of operands to SSA values, emitting an error on failure, or |
501 | | /// appending the results to the list on success. This method should be used |
502 | | /// when all operands have the same type. |
503 | | ParseResult resolveOperands(ArrayRef<OperandType> operands, Type type, |
504 | 0 | SmallVectorImpl<Value> &result) { |
505 | 0 | for (auto elt : operands) |
506 | 0 | if (resolveOperand(elt, type, result)) |
507 | 0 | return failure(); |
508 | 0 | return success(); |
509 | 0 | } |
510 | | |
511 | | /// Resolve a list of operands and a list of operand types to SSA values, |
512 | | /// emitting an error and returning failure, or appending the results |
513 | | /// to the list on success. |
514 | | ParseResult resolveOperands(ArrayRef<OperandType> operands, |
515 | | ArrayRef<Type> types, llvm::SMLoc loc, |
516 | 0 | SmallVectorImpl<Value> &result) { |
517 | 0 | if (operands.size() != types.size()) |
518 | 0 | return emitError(loc) |
519 | 0 | << operands.size() << " operands present, but expected " |
520 | 0 | << types.size(); |
521 | 0 | |
522 | 0 | for (unsigned i = 0, e = operands.size(); i != e; ++i) |
523 | 0 | if (resolveOperand(operands[i], types[i], result)) |
524 | 0 | return failure(); |
525 | 0 | return success(); |
526 | 0 | } |
527 | | template <typename Operands> |
528 | | ParseResult resolveOperands(Operands &&operands, Type type, llvm::SMLoc loc, |
529 | 0 | SmallVectorImpl<Value> &result) { |
530 | 0 | return resolveOperands(std::forward<Operands>(operands), |
531 | 0 | ArrayRef<Type>(type), loc, result); |
532 | 0 | } |
533 | | template <typename Operands, typename Types> |
534 | | std::enable_if_t<!std::is_convertible<Types, Type>::value, ParseResult> |
535 | | resolveOperands(Operands &&operands, Types &&types, llvm::SMLoc loc, |
536 | 0 | SmallVectorImpl<Value> &result) { |
537 | 0 | size_t operandSize = std::distance(operands.begin(), operands.end()); |
538 | 0 | size_t typeSize = std::distance(types.begin(), types.end()); |
539 | 0 | if (operandSize != typeSize) |
540 | 0 | return emitError(loc) |
541 | 0 | << operandSize << " operands present, but expected " << typeSize; |
542 | 0 | |
543 | 0 | for (auto it : llvm::zip(operands, types)) |
544 | 0 | if (resolveOperand(std::get<0>(it), std::get<1>(it), result)) |
545 | 0 | return failure(); |
546 | 0 | return success(); |
547 | 0 | } Unexecuted instantiation: _ZN4mlir11OpAsmParser15resolveOperandsIRN4llvm11SmallVectorINS0_11OperandTypeELj4EEERNS3_INS_4TypeELj1EEEEENSt9enable_ifIXntsr3std14is_convertibleIT0_S7_EE5valueENS_11ParseResultEE4typeEOT_OSB_NS2_5SMLocERNS2_15SmallVectorImplINS_5ValueEEE Unexecuted instantiation: _ZN4mlir11OpAsmParser15resolveOperandsIRN4llvm11SmallVectorINS0_11OperandTypeELj4EEENS2_8ArrayRefINS_4TypeEEEEENSt9enable_ifIXntsr3std14is_convertibleIT0_S8_EE5valueENS_11ParseResultEE4typeEOT_OSB_NS2_5SMLocERNS2_15SmallVectorImplINS_5ValueEEE Unexecuted instantiation: _ZN4mlir11OpAsmParser15resolveOperandsIRN4llvm11SmallVectorINS0_11OperandTypeELj4EEERNS2_8ArrayRefINS_4TypeEEEEENSt9enable_ifIXntsr3std14is_convertibleIT0_S8_EE5valueENS_11ParseResultEE4typeEOT_OSC_NS2_5SMLocERNS2_15SmallVectorImplINS_5ValueEEE |
548 | | |
549 | | /// Parses an affine map attribute where dims and symbols are SSA operands. |
550 | | /// Operand values must come from single-result sources, and be valid |
551 | | /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol. |
552 | | virtual ParseResult |
553 | | parseAffineMapOfSSAIds(SmallVectorImpl<OperandType> &operands, Attribute &map, |
554 | | StringRef attrName, NamedAttrList &attrs, |
555 | | Delimiter delimiter = Delimiter::Square) = 0; |
556 | | |
557 | | //===--------------------------------------------------------------------===// |
558 | | // Region Parsing |
559 | | //===--------------------------------------------------------------------===// |
560 | | |
561 | | /// Parses a region. Any parsed blocks are appended to "region" and must be |
562 | | /// moved to the op regions after the op is created. The first block of the |
563 | | /// region takes "arguments" of types "argTypes". If "enableNameShadowing" is |
564 | | /// set to true, the argument names are allowed to shadow the names of other |
565 | | /// existing SSA values defined above the region scope. "enableNameShadowing" |
566 | | /// can only be set to true for regions attached to operations that are |
567 | | /// "IsolatedFromAbove". |
568 | | virtual ParseResult parseRegion(Region ®ion, |
569 | | ArrayRef<OperandType> arguments, |
570 | | ArrayRef<Type> argTypes, |
571 | | bool enableNameShadowing = false) = 0; |
572 | | |
573 | | /// Parses a region if present. |
574 | | virtual ParseResult parseOptionalRegion(Region ®ion, |
575 | | ArrayRef<OperandType> arguments, |
576 | | ArrayRef<Type> argTypes, |
577 | | bool enableNameShadowing = false) = 0; |
578 | | |
579 | | /// Parse a region argument, this argument is resolved when calling |
580 | | /// 'parseRegion'. |
581 | | virtual ParseResult parseRegionArgument(OperandType &argument) = 0; |
582 | | |
583 | | /// Parse zero or more region arguments with a specified surrounding |
584 | | /// delimiter, and an optional required argument count. Region arguments |
585 | | /// define new values; so this also checks if values with the same names have |
586 | | /// not been defined yet. |
587 | | virtual ParseResult |
588 | | parseRegionArgumentList(SmallVectorImpl<OperandType> &result, |
589 | | int requiredOperandCount = -1, |
590 | | Delimiter delimiter = Delimiter::None) = 0; |
591 | | virtual ParseResult |
592 | | parseRegionArgumentList(SmallVectorImpl<OperandType> &result, |
593 | 0 | Delimiter delimiter) { |
594 | 0 | return parseRegionArgumentList(result, /*requiredOperandCount=*/-1, |
595 | 0 | delimiter); |
596 | 0 | } |
597 | | |
598 | | /// Parse a region argument if present. |
599 | | virtual ParseResult parseOptionalRegionArgument(OperandType &argument) = 0; |
600 | | |
601 | | //===--------------------------------------------------------------------===// |
602 | | // Successor Parsing |
603 | | //===--------------------------------------------------------------------===// |
604 | | |
605 | | /// Parse a single operation successor. |
606 | | virtual ParseResult parseSuccessor(Block *&dest) = 0; |
607 | | |
608 | | /// Parse an optional operation successor. |
609 | | virtual OptionalParseResult parseOptionalSuccessor(Block *&dest) = 0; |
610 | | |
611 | | /// Parse a single operation successor and its operand list. |
612 | | virtual ParseResult |
613 | | parseSuccessorAndUseList(Block *&dest, SmallVectorImpl<Value> &operands) = 0; |
614 | | |
615 | | //===--------------------------------------------------------------------===// |
616 | | // Type Parsing |
617 | | //===--------------------------------------------------------------------===// |
618 | | |
619 | | /// Parse a type. |
620 | | virtual ParseResult parseType(Type &result) = 0; |
621 | | |
622 | | /// Parse an optional type. |
623 | | virtual OptionalParseResult parseOptionalType(Type &result) = 0; |
624 | | |
625 | | /// Parse a type of a specific type. |
626 | | template <typename TypeT> |
627 | 0 | ParseResult parseType(TypeT &result) { |
628 | 0 | llvm::SMLoc loc = getCurrentLocation(); |
629 | 0 |
|
630 | 0 | // Parse any kind of type. |
631 | 0 | Type type; |
632 | 0 | if (parseType(type)) |
633 | 0 | return failure(); |
634 | 0 | |
635 | 0 | // Check for the right kind of attribute. |
636 | 0 | result = type.dyn_cast<TypeT>(); |
637 | 0 | if (!result) |
638 | 0 | return emitError(loc, "invalid kind of type specified"); |
639 | 0 | |
640 | 0 | return success(); |
641 | 0 | } Unexecuted instantiation: _ZN4mlir11OpAsmParser9parseTypeINS_10VectorTypeEEENS_11ParseResultERT_ Unexecuted instantiation: _ZN4mlir11OpAsmParser9parseTypeINS_12FunctionTypeEEENS_11ParseResultERT_ |
642 | | |
643 | | /// Parse a type list. |
644 | 0 | ParseResult parseTypeList(SmallVectorImpl<Type> &result) { |
645 | 0 | do { |
646 | 0 | Type type; |
647 | 0 | if (parseType(type)) |
648 | 0 | return failure(); |
649 | 0 | result.push_back(type); |
650 | 0 | } while (succeeded(parseOptionalComma())); |
651 | 0 | return success(); |
652 | 0 | } |
653 | | |
654 | | /// Parse an arrow followed by a type list. |
655 | | virtual ParseResult parseArrowTypeList(SmallVectorImpl<Type> &result) = 0; |
656 | | |
657 | | /// Parse an optional arrow followed by a type list. |
658 | | virtual ParseResult |
659 | | parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) = 0; |
660 | | |
661 | | /// Parse a colon followed by a type. |
662 | | virtual ParseResult parseColonType(Type &result) = 0; |
663 | | |
664 | | /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType. |
665 | | template <typename TypeType> |
666 | 0 | ParseResult parseColonType(TypeType &result) { |
667 | 0 | llvm::SMLoc loc = getCurrentLocation(); |
668 | 0 |
|
669 | 0 | // Parse any kind of type. |
670 | 0 | Type type; |
671 | 0 | if (parseColonType(type)) |
672 | 0 | return failure(); |
673 | 0 | |
674 | 0 | // Check for the right kind of attribute. |
675 | 0 | result = type.dyn_cast<TypeType>(); |
676 | 0 | if (!result) |
677 | 0 | return emitError(loc, "invalid kind of type specified"); |
678 | 0 | |
679 | 0 | return success(); |
680 | 0 | } |
681 | | |
682 | | /// Parse a colon followed by a type list, which must have at least one type. |
683 | | virtual ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) = 0; |
684 | | |
685 | | /// Parse an optional colon followed by a type list, which if present must |
686 | | /// have at least one type. |
687 | | virtual ParseResult |
688 | | parseOptionalColonTypeList(SmallVectorImpl<Type> &result) = 0; |
689 | | |
690 | | /// Parse a list of assignments of the form |
691 | | /// (%x1 = %y1 : type1, %x2 = %y2 : type2, ...). |
692 | | /// The list must contain at least one entry |
693 | | virtual ParseResult |
694 | | parseAssignmentList(SmallVectorImpl<OperandType> &lhs, |
695 | | SmallVectorImpl<OperandType> &rhs) = 0; |
696 | | |
697 | | /// Parse a keyword followed by a type. |
698 | 0 | ParseResult parseKeywordType(const char *keyword, Type &result) { |
699 | 0 | return failure(parseKeyword(keyword) || parseType(result)); |
700 | 0 | } |
701 | | |
702 | | /// Add the specified type to the end of the specified type list and return |
703 | | /// success. This is a helper designed to allow parse methods to be simple |
704 | | /// and chain through || operators. |
705 | 0 | ParseResult addTypeToList(Type type, SmallVectorImpl<Type> &result) { |
706 | 0 | result.push_back(type); |
707 | 0 | return success(); |
708 | 0 | } |
709 | | |
710 | | /// Add the specified types to the end of the specified type list and return |
711 | | /// success. This is a helper designed to allow parse methods to be simple |
712 | | /// and chain through || operators. |
713 | | ParseResult addTypesToList(ArrayRef<Type> types, |
714 | 0 | SmallVectorImpl<Type> &result) { |
715 | 0 | result.append(types.begin(), types.end()); |
716 | 0 | return success(); |
717 | 0 | } |
718 | | |
719 | | private: |
720 | | /// Parse either an operand list or a region argument list depending on |
721 | | /// whether isOperandList is true. |
722 | | ParseResult parseOperandOrRegionArgList(SmallVectorImpl<OperandType> &result, |
723 | | bool isOperandList, |
724 | | int requiredOperandCount, |
725 | | Delimiter delimiter); |
726 | | }; |
727 | | |
728 | | //===--------------------------------------------------------------------===// |
729 | | // Dialect OpAsm interface. |
730 | | //===--------------------------------------------------------------------===// |
731 | | |
732 | | /// A functor used to set the name of the start of a result group of an |
733 | | /// operation. See 'getAsmResultNames' below for more details. |
734 | | using OpAsmSetValueNameFn = function_ref<void(Value, StringRef)>; |
735 | | |
736 | | class OpAsmDialectInterface |
737 | | : public DialectInterface::Base<OpAsmDialectInterface> { |
738 | | public: |
739 | 0 | OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {} |
740 | | |
741 | | /// Hooks for getting identifier aliases for symbols. The identifier is used |
742 | | /// in place of the symbol when printing textual IR. |
743 | | /// |
744 | | /// Hook for defining Attribute kind aliases. This will generate an alias for |
745 | | /// all attributes of the given kind in the form : <alias>[0-9]+. These |
746 | | /// aliases must not contain `.`. |
747 | | virtual void getAttributeKindAliases( |
748 | 0 | SmallVectorImpl<std::pair<unsigned, StringRef>> &aliases) const {} |
749 | | /// Hook for defining Attribute aliases. These aliases must not contain `.` or |
750 | | /// end with a numeric digit([0-9]+). |
751 | | virtual void getAttributeAliases( |
752 | 0 | SmallVectorImpl<std::pair<Attribute, StringRef>> &aliases) const {} |
753 | | /// Hook for defining Type aliases. |
754 | | virtual void |
755 | 0 | getTypeAliases(SmallVectorImpl<std::pair<Type, StringRef>> &aliases) const {} |
756 | | |
757 | | /// Get a special name to use when printing the given operation. See |
758 | | /// OpAsmInterface.td#getAsmResultNames for usage details and documentation. |
759 | | virtual void getAsmResultNames(Operation *op, |
760 | 0 | OpAsmSetValueNameFn setNameFn) const {} |
761 | | |
762 | | /// Get a special name to use when printing the entry block arguments of the |
763 | | /// region contained by an operation in this dialect. |
764 | | virtual void getAsmBlockArgumentNames(Block *block, |
765 | 0 | OpAsmSetValueNameFn setNameFn) const {} |
766 | | }; |
767 | | |
768 | | //===--------------------------------------------------------------------===// |
769 | | // Operation OpAsm interface. |
770 | | //===--------------------------------------------------------------------===// |
771 | | |
772 | | /// The OpAsmOpInterface, see OpAsmInterface.td for more details. |
773 | | #include "mlir/IR/OpAsmInterface.h.inc" |
774 | | |
775 | | } // end namespace mlir |
776 | | |
777 | | #endif |