Coverage Report

Created: 2020-06-26 05:44

/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 &region, 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 &region,
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 &region,
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