MLIR  20.0.0git
ExtensibleDialect.h
Go to the documentation of this file.
1 //===- ExtensibleDialect.h - Extensible dialect -----------------*- C++ -*-===//
2 //
3 // This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the DynamicOpDefinition class, the DynamicTypeDefinition
10 // class, and the DynamicAttrDefinition class, which represent respectively
11 // operations, types, and attributes that can be defined at runtime. They can
12 // be registered at runtime to an extensible dialect, using the
13 // ExtensibleDialect class defined in this file.
14 //
15 // For a more complete documentation, see
16 // https://mlir.llvm.org/docs/ExtensibleDialects/ .
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #ifndef MLIR_IR_EXTENSIBLEDIALECT_H
21 #define MLIR_IR_EXTENSIBLEDIALECT_H
22 
23 #include "mlir/IR/Dialect.h"
25 #include "mlir/IR/MLIRContext.h"
26 #include "mlir/IR/OpDefinition.h"
28 #include "mlir/Support/TypeID.h"
29 #include "llvm/ADT/StringMap.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include <optional>
32 
33 namespace mlir {
34 class AsmParser;
35 class AsmPrinter;
36 class DynamicAttr;
37 class DynamicType;
38 class ExtensibleDialect;
39 class MLIRContext;
40 class OptionalParseResult;
41 
42 namespace detail {
43 struct DynamicAttrStorage;
44 struct DynamicTypeStorage;
45 } // namespace detail
46 
47 //===----------------------------------------------------------------------===//
48 // Dynamic attribute
49 //===----------------------------------------------------------------------===//
50 
51 /// The definition of a dynamic attribute. A dynamic attribute is an attribute
52 /// that is defined at runtime, and that can be registered at runtime by an
53 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
54 /// stores the parser, the printer, and the verifier of the attribute. Each
55 /// dynamic attribute definition refers to one instance of this class.
57 public:
58  using VerifierFn = llvm::unique_function<LogicalResult(
60  using ParserFn = llvm::unique_function<ParseResult(
61  AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
62  const>;
63  using PrinterFn = llvm::unique_function<void(
64  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
65 
66  /// Create a new attribute definition at runtime. The attribute is registered
67  /// only after passing it to the dialect using registerDynamicAttr.
68  static std::unique_ptr<DynamicAttrDefinition>
69  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
70  static std::unique_ptr<DynamicAttrDefinition>
71  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
72  ParserFn &&parser, PrinterFn &&printer);
73 
74  /// Sets the verifier function for this attribute. It should emits an error
75  /// message and returns failure if a problem is detected, or returns success
76  /// if everything is ok.
77  void setVerifyFn(VerifierFn &&verify) { verifier = std::move(verify); }
78 
79  /// Sets the static hook for parsing this attribute assembly.
80  void setParseFn(ParserFn &&parse) { parser = std::move(parse); }
81 
82  /// Sets the static hook for printing this attribute assembly.
83  void setPrintFn(PrinterFn &&print) { printer = std::move(print); }
84 
85  /// Check that the attribute parameters are valid.
87  ArrayRef<Attribute> params) const {
88  return verifier(emitError, params);
89  }
90 
91  /// Return the MLIRContext in which the dynamic attributes are uniqued.
92  MLIRContext &getContext() const { return *ctx; }
93 
94  /// Return the name of the attribute, in the format 'attrname' and
95  /// not 'dialectname.attrname'.
96  StringRef getName() const { return name; }
97 
98  /// Return the dialect defining the attribute.
99  ExtensibleDialect *getDialect() const { return dialect; }
100 
101 private:
102  DynamicAttrDefinition(StringRef name, ExtensibleDialect *dialect,
103  VerifierFn &&verifier, ParserFn &&parser,
104  PrinterFn &&printer);
105 
106  /// This constructor should only be used when we need a pointer to
107  /// the DynamicAttrDefinition in the verifier, the parser, or the printer.
108  /// The verifier, parser, and printer need thus to be initialized after the
109  /// constructor.
110  DynamicAttrDefinition(ExtensibleDialect *dialect, StringRef name);
111 
112  /// Register the concrete attribute in the attribute Uniquer.
113  void registerInAttrUniquer();
114 
115  /// The name should be prefixed with the dialect name followed by '.'.
116  std::string name;
117 
118  /// Dialect in which this attribute is defined.
119  ExtensibleDialect *dialect;
120 
121  /// The attribute verifier. It checks that the attribute parameters satisfy
122  /// the invariants.
123  VerifierFn verifier;
124 
125  /// The attribute parameters parser. It parses only the parameters, and
126  /// expects the attribute name to have already been parsed.
127  ParserFn parser;
128 
129  /// The attribute parameters printer. It prints only the parameters, and
130  /// expects the attribute name to have already been printed.
131  PrinterFn printer;
132 
133  /// Context in which the concrete attributes are uniqued.
134  MLIRContext *ctx;
135 
136  friend ExtensibleDialect;
137  friend DynamicAttr;
138 };
139 
140 /// This trait is used to determine if an attribute is a dynamic attribute or
141 /// not; it should only be implemented by dynamic attributes.
142 /// Note: This is only required because dynamic attributes do not have a
143 /// static/single TypeID.
144 namespace AttributeTrait {
145 template <typename ConcreteType>
146 class IsDynamicAttr : public TraitBase<ConcreteType, IsDynamicAttr> {};
147 } // namespace AttributeTrait
148 
149 /// A dynamic attribute instance. This is an attribute whose definition is
150 /// defined at runtime.
151 /// It is possible to check if an attribute is a dynamic attribute using
152 /// `my_attr.isa<DynamicAttr>()`, and getting the attribute definition of a
153 /// dynamic attribute using the `DynamicAttr::getAttrDef` method.
154 /// All dynamic attributes have the same storage, which is an array of
155 /// attributes.
156 
157 class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute,
158  detail::DynamicAttrStorage,
159  AttributeTrait::IsDynamicAttr> {
160 public:
161  // Inherit Base constructors.
162  using Base::Base;
163 
164  /// Return an instance of a dynamic attribute given a dynamic attribute
165  /// definition and attribute parameters.
166  /// This asserts that the attribute verifier succeeded.
167  static DynamicAttr get(DynamicAttrDefinition *attrDef,
168  ArrayRef<Attribute> params = {});
169 
170  /// Return an instance of a dynamic attribute given a dynamic attribute
171  /// definition and attribute parameters. If the parameters provided are
172  /// invalid, errors are emitted using the provided location and a null object
173  /// is returned.
175  DynamicAttrDefinition *attrDef,
176  ArrayRef<Attribute> params = {});
177 
178  /// Return the attribute definition of the concrete attribute.
180 
181  /// Return the attribute parameters.
183 
184  /// Check if an attribute is a specific dynamic attribute.
185  static bool isa(Attribute attr, DynamicAttrDefinition *attrDef) {
186  return attr.getTypeID() == attrDef->getTypeID();
187  }
188 
189  /// Check if an attribute is a dynamic attribute.
190  static bool classof(Attribute attr);
191 
192  /// Parse the dynamic attribute parameters and construct the attribute.
193  /// The parameters are either empty, and nothing is parsed,
194  /// or they are in the format '<>' or '<attr (,attr)*>'.
195  static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef,
196  DynamicAttr &parsedAttr);
197 
198  /// Print the dynamic attribute with the format 'attrname' if there is no
199  /// parameters, or 'attrname<attr (,attr)*>'.
200  void print(AsmPrinter &printer);
201 };
202 
203 //===----------------------------------------------------------------------===//
204 // Dynamic type
205 //===----------------------------------------------------------------------===//
206 
207 /// The definition of a dynamic type. A dynamic type is a type that is
208 /// defined at runtime, and that can be registered at runtime by an
209 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
210 /// stores the parser, the printer, and the verifier of the type. Each dynamic
211 /// type definition refers to one instance of this class.
213 public:
214  using VerifierFn = llvm::unique_function<LogicalResult(
216  using ParserFn = llvm::unique_function<ParseResult(
217  AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
218  const>;
219  using PrinterFn = llvm::unique_function<void(
220  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
221 
222  /// Create a new dynamic type definition. The type is registered only after
223  /// passing it to the dialect using registerDynamicType.
224  static std::unique_ptr<DynamicTypeDefinition>
225  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
226  static std::unique_ptr<DynamicTypeDefinition>
227  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
228  ParserFn &&parser, PrinterFn &&printer);
229 
230  /// Sets the verifier function for this type. It should emits an error
231  /// message and returns failure if a problem is detected, or returns success
232  /// if everything is ok.
233  void setVerifyFn(VerifierFn &&verify) { verifier = std::move(verify); }
234 
235  /// Sets the static hook for parsing this type assembly.
236  void setParseFn(ParserFn &&parse) { parser = std::move(parse); }
237 
238  /// Sets the static hook for printing this type assembly.
239  void setPrintFn(PrinterFn &&print) { printer = std::move(print); }
240 
241  /// Check that the type parameters are valid.
243  ArrayRef<Attribute> params) const {
244  return verifier(emitError, params);
245  }
246 
247  /// Return the MLIRContext in which the dynamic types is uniqued.
248  MLIRContext &getContext() const { return *ctx; }
249 
250  /// Return the name of the type, in the format 'typename' and
251  /// not 'dialectname.typename'.
252  StringRef getName() const { return name; }
253 
254  /// Return the dialect defining the type.
255  ExtensibleDialect *getDialect() const { return dialect; }
256 
257 private:
258  DynamicTypeDefinition(StringRef name, ExtensibleDialect *dialect,
259  VerifierFn &&verifier, ParserFn &&parser,
260  PrinterFn &&printer);
261 
262  /// This constructor should only be used when we need a pointer to
263  /// the DynamicTypeDefinition in the verifier, the parser, or the printer.
264  /// The verifier, parser, and printer need thus to be initialized after the
265  /// constructor.
266  DynamicTypeDefinition(ExtensibleDialect *dialect, StringRef name);
267 
268  /// Register the concrete type in the type Uniquer.
269  void registerInTypeUniquer();
270 
271  /// The name should be prefixed with the dialect name followed by '.'.
272  std::string name;
273 
274  /// Dialect in which this type is defined.
275  ExtensibleDialect *dialect;
276 
277  /// The type verifier. It checks that the type parameters satisfy the
278  /// invariants.
279  VerifierFn verifier;
280 
281  /// The type parameters parser. It parses only the parameters, and expects the
282  /// type name to have already been parsed.
283  ParserFn parser;
284 
285  /// The type parameters printer. It prints only the parameters, and expects
286  /// the type name to have already been printed.
287  PrinterFn printer;
288 
289  /// Context in which the concrete types are uniqued.
290  MLIRContext *ctx;
291 
292  friend ExtensibleDialect;
293  friend DynamicType;
294 };
295 
296 /// This trait is used to determine if a type is a dynamic type or not;
297 /// it should only be implemented by dynamic types.
298 /// Note: This is only required because dynamic type do not have a
299 /// static/single TypeID.
300 namespace TypeTrait {
301 template <typename ConcreteType>
302 class IsDynamicType : public TypeTrait::TraitBase<ConcreteType, IsDynamicType> {
303 };
304 } // namespace TypeTrait
305 
306 /// A dynamic type instance. This is a type whose definition is defined at
307 /// runtime.
308 /// It is possible to check if a type is a dynamic type using
309 /// `my_type.isa<DynamicType>()`, and getting the type definition of a dynamic
310 /// type using the `DynamicType::getTypeDef` method.
311 /// All dynamic types have the same storage, which is an array of attributes.
313  : public Type::TypeBase<DynamicType, Type, detail::DynamicTypeStorage,
314  TypeTrait::IsDynamicType> {
315 public:
316  // Inherit Base constructors.
317  using Base::Base;
318 
319  /// Return an instance of a dynamic type given a dynamic type definition and
320  /// type parameters.
321  /// This asserts that the type verifier succeeded.
322  static DynamicType get(DynamicTypeDefinition *typeDef,
323  ArrayRef<Attribute> params = {});
324 
325  /// Return an instance of a dynamic type given a dynamic type definition and
326  /// type parameters. If the parameters provided are invalid, errors are
327  /// emitted using the provided location and a null object is returned.
329  DynamicTypeDefinition *typeDef,
330  ArrayRef<Attribute> params = {});
331 
332  /// Return the type definition of the concrete type.
334 
335  /// Return the type parameters.
337 
338  /// Check if a type is a specific dynamic type.
339  static bool isa(Type type, DynamicTypeDefinition *typeDef) {
340  return type.getTypeID() == typeDef->getTypeID();
341  }
342 
343  /// Check if a type is a dynamic type.
344  static bool classof(Type type);
345 
346  /// Parse the dynamic type parameters and construct the type.
347  /// The parameters are either empty, and nothing is parsed,
348  /// or they are in the format '<>' or '<attr (,attr)*>'.
349  static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef,
350  DynamicType &parsedType);
351 
352  /// Print the dynamic type with the format
353  /// 'type' or 'type<>' if there is no parameters, or 'type<attr (,attr)*>'.
354  void print(AsmPrinter &printer);
355 };
356 
357 //===----------------------------------------------------------------------===//
358 // Dynamic operation
359 //===----------------------------------------------------------------------===//
360 
361 /// The definition of a dynamic op. A dynamic op is an op that is defined at
362 /// runtime, and that can be registered at runtime by an extensible dialect (a
363 /// dialect inheriting ExtensibleDialect). This class implements the method
364 /// exposed by the OperationName class, and in addition defines the TypeID of
365 /// the op that will be defined. Each dynamic operation definition refers to one
366 /// instance of this class.
368 public:
370  llvm::unique_function<void(RewritePatternSet &, MLIRContext *) const>;
371 
372  /// Create a new op at runtime. The op is registered only after passing it to
373  /// the dialect using registerDynamicOp.
374  static std::unique_ptr<DynamicOpDefinition>
375  get(StringRef name, ExtensibleDialect *dialect,
377  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn);
378  static std::unique_ptr<DynamicOpDefinition>
379  get(StringRef name, ExtensibleDialect *dialect,
384  static std::unique_ptr<DynamicOpDefinition>
385  get(StringRef name, ExtensibleDialect *dialect,
390  OperationName::FoldHookFn &&foldHookFn,
391  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
392  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
393 
394  /// Returns the op typeID.
395  TypeID getTypeID() { return typeID; }
396 
397  /// Sets the verifier function for this operation. It should emits an error
398  /// message and returns failure if a problem is detected, or returns success
399  /// if everything is ok.
401  verifyFn = std::move(verify);
402  }
403 
404  /// Sets the region verifier function for this operation. It should emits an
405  /// error message and returns failure if a problem is detected, or returns
406  /// success if everything is ok.
408  verifyRegionFn = std::move(verify);
409  }
410 
411  /// Sets the static hook for parsing this op assembly.
413  parseFn = std::move(parse);
414  }
415 
416  /// Sets the static hook for printing this op assembly.
418  printFn = std::move(print);
419  }
420 
421  /// Sets the hook implementing a generalized folder for the op. See
422  /// `RegisteredOperationName::foldHook` for more details
424  foldHookFn = std::move(foldHook);
425  }
426 
427  /// Set the hook returning any canonicalization pattern rewrites that the op
428  /// supports, for use by the canonicalization pass.
431  getCanonicalizationPatternsFn = std::move(getCanonicalizationPatterns);
432  }
433 
434  /// Set the hook populating default attributes.
437  populateDefaultAttrsFn = std::move(populateDefaultAttrs);
438  }
439 
440  LogicalResult foldHook(Operation *op, ArrayRef<Attribute> attrs,
441  SmallVectorImpl<OpFoldResult> &results) final {
442  return foldHookFn(op, attrs, results);
443  }
445  MLIRContext *context) final {
446  getCanonicalizationPatternsFn(set, context);
447  }
448  bool hasTrait(TypeID id) final { return false; }
450  return [&](OpAsmParser &parser, OperationState &state) {
451  return parseFn(parser, state);
452  };
453  }
455  NamedAttrList &attrs) final {
456  populateDefaultAttrsFn(name, attrs);
457  }
459  StringRef name) final {
460  printFn(op, printer, name);
461  }
462  LogicalResult verifyInvariants(Operation *op) final { return verifyFn(op); }
463  LogicalResult verifyRegionInvariants(Operation *op) final {
464  return verifyRegionFn(op);
465  }
466 
467  /// Implementation for properties (unsupported right now here).
468  std::optional<Attribute> getInherentAttr(Operation *op,
469  StringRef name) final {
470  llvm::report_fatal_error("Unsupported getInherentAttr on Dynamic dialects");
471  }
472  void setInherentAttr(Operation *op, StringAttr name, Attribute value) final {
473  llvm::report_fatal_error("Unsupported setInherentAttr on Dynamic dialects");
474  }
475  void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final {}
476  LogicalResult
479  return success();
480  }
481  int getOpPropertyByteSize() final { return 0; }
483  OpaqueProperties init) final {}
484  void deleteProperties(OpaqueProperties prop) final {}
486  OpaqueProperties properties) final {}
487 
488  LogicalResult
490  Attribute attr,
492  emitError() << "extensible Dialects don't support properties";
493  return failure();
494  }
495  Attribute getPropertiesAsAttr(Operation *op) final { return {}; }
497  bool compareProperties(OpaqueProperties, OpaqueProperties) final { return false; }
498  llvm::hash_code hashProperties(OpaqueProperties prop) final { return {}; }
499 
500 private:
502  StringRef name, ExtensibleDialect *dialect,
507  OperationName::FoldHookFn &&foldHookFn,
508  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
509  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
510 
511  /// Dialect defining this operation.
512  ExtensibleDialect *getdialect();
513 
518  OperationName::FoldHookFn foldHookFn;
519  GetCanonicalizationPatternsFn getCanonicalizationPatternsFn;
520  OperationName::PopulateDefaultAttrsFn populateDefaultAttrsFn;
521 
522  friend ExtensibleDialect;
523 };
524 
525 //===----------------------------------------------------------------------===//
526 // Extensible dialect
527 //===----------------------------------------------------------------------===//
528 
529 /// A dialect that can be extended with new operations/types/attributes at
530 /// runtime.
532 public:
533  ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID);
534 
535  /// Add a new type defined at runtime to the dialect.
536  void registerDynamicType(std::unique_ptr<DynamicTypeDefinition> &&type);
537 
538  /// Add a new attribute defined at runtime to the dialect.
539  void registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> &&attr);
540 
541  /// Add a new operation defined at runtime to the dialect.
542  void registerDynamicOp(std::unique_ptr<DynamicOpDefinition> &&type);
543 
544  /// Check if the dialect is an extensible dialect.
545  static bool classof(const Dialect *dialect);
546 
547  /// Returns nullptr if the definition was not found.
549  return nameToDynTypes.lookup(name);
550  }
551 
552  /// Returns nullptr if the definition was not found.
554  auto it = dynTypes.find(id);
555  if (it == dynTypes.end())
556  return nullptr;
557  return it->second.get();
558  }
559 
560  /// Returns nullptr if the definition was not found.
562  return nameToDynAttrs.lookup(name);
563  }
564 
565  /// Returns nullptr if the definition was not found.
567  auto it = dynAttrs.find(id);
568  if (it == dynAttrs.end())
569  return nullptr;
570  return it->second.get();
571  }
572 
573 protected:
574  /// Parse the dynamic type 'typeName' in the dialect 'dialect'.
575  /// typename should not be prefixed with the dialect name.
576  /// If the dynamic type does not exist, return no value.
577  /// Otherwise, parse it, and return the parse result.
578  /// If the parsing succeed, put the resulting type in 'resultType'.
580  AsmParser &parser,
581  Type &resultType) const;
582 
583  /// If 'type' is a dynamic type, print it.
584  /// Returns success if the type was printed, and failure if the type was not a
585  /// dynamic type.
586  static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer);
587 
588  /// Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
589  /// attrname should not be prefixed with the dialect name.
590  /// If the dynamic attribute does not exist, return no value.
591  /// Otherwise, parse it, and return the parse result.
592  /// If the parsing succeed, put the resulting attribute in 'resultAttr'.
594  AsmParser &parser,
595  Attribute &resultAttr) const;
596 
597  /// If 'attr' is a dynamic attribute, print it.
598  /// Returns success if the attribute was printed, and failure if the
599  /// attribute was not a dynamic attribute.
600  static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer);
601 
602 private:
603  /// The set of all dynamic types registered.
605 
606  /// This structure allows to get in O(1) a dynamic type given its name.
607  llvm::StringMap<DynamicTypeDefinition *> nameToDynTypes;
608 
609  /// The set of all dynamic attributes registered.
611 
612  /// This structure allows to get in O(1) a dynamic attribute given its name.
613  llvm::StringMap<DynamicAttrDefinition *> nameToDynAttrs;
614 
615  /// Give DynamicOpDefinition access to allocateTypeID.
616  friend DynamicOpDefinition;
617 
618  /// Allocates a type ID to uniquify operations.
619  TypeID allocateTypeID() { return typeIDAllocator.allocate(); }
620 
621  /// Owns the TypeID generated at runtime for operations.
622  TypeIDAllocator typeIDAllocator;
623 };
624 
625 //===----------------------------------------------------------------------===//
626 // Dynamic dialect
627 //===----------------------------------------------------------------------===//
628 
629 /// A dialect that can be defined at runtime. It can be extended with new
630 /// operations, types, and attributes at runtime.
632 public:
633  DynamicDialect(StringRef name, MLIRContext *ctx);
634 
636 
637  /// Check if the dialect is an extensible dialect.
638  static bool classof(const Dialect *dialect);
639 
640  virtual Type parseType(DialectAsmParser &parser) const override;
641  virtual void printType(Type type, DialectAsmPrinter &printer) const override;
642 
643  virtual Attribute parseAttribute(DialectAsmParser &parser,
644  Type type) const override;
645  virtual void printAttribute(Attribute attr,
646  DialectAsmPrinter &printer) const override;
647 };
648 } // namespace mlir
649 
650 namespace llvm {
651 /// Provide isa functionality for ExtensibleDialect.
652 /// This is to override the isa functionality for Dialect.
653 template <>
654 struct isa_impl<mlir::ExtensibleDialect, mlir::Dialect> {
655  static inline bool doit(const ::mlir::Dialect &dialect) {
656  return mlir::ExtensibleDialect::classof(&dialect);
657  }
658 };
659 
660 /// Provide isa functionality for DynamicDialect.
661 /// This is to override the isa functionality for Dialect.
662 template <>
663 struct isa_impl<mlir::DynamicDialect, mlir::Dialect> {
664  static inline bool doit(const ::mlir::Dialect &dialect) {
665  return mlir::DynamicDialect::classof(&dialect);
666  }
667 };
668 } // namespace llvm
669 
670 #endif // MLIR_IR_EXTENSIBLEDIALECT_H
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This base class exposes generic asm parser hooks, usable across the various derived parsers.
This base class exposes generic asm printer hooks, usable across the various derived printers.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
Definition: Attributes.h:70
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:38
The definition of a dynamic attribute.
ExtensibleDialect * getDialect() const
Return the dialect defining the attribute.
void setVerifyFn(VerifierFn &&verify)
Sets the verifier function for this attribute.
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the attribute parameters are valid.
void setParseFn(ParserFn &&parse)
Sets the static hook for parsing this attribute assembly.
StringRef getName() const
Return the name of the attribute, in the format 'attrname' and not 'dialectname.attrname'.
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
void setPrintFn(PrinterFn &&print)
Sets the static hook for printing this attribute assembly.
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
A dynamic attribute instance.
static DynamicAttr getChecked(function_ref< InFlightDiagnostic()> emitError, DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic attribute given a dynamic attribute definition and attribute paramete...
ArrayRef< Attribute > getParams()
Return the attribute parameters.
static DynamicAttr get(DynamicAttrDefinition *attrDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic attribute given a dynamic attribute definition and attribute paramete...
void print(AsmPrinter &printer)
Print the dynamic attribute with the format 'attrname' if there is no parameters, or 'attrname<attr (...
static bool classof(Attribute attr)
Check if an attribute is a dynamic attribute.
static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef, DynamicAttr &parsedAttr)
Parse the dynamic attribute parameters and construct the attribute.
DynamicAttrDefinition * getAttrDef()
Return the attribute definition of the concrete attribute.
static bool isa(Attribute attr, DynamicAttrDefinition *attrDef)
Check if an attribute is a specific dynamic attribute.
A dialect that can be defined at runtime.
virtual void printAttribute(Attribute attr, DialectAsmPrinter &printer) const override
Print an attribute registered to this dialect.
DynamicDialect(StringRef name, MLIRContext *ctx)
virtual Attribute parseAttribute(DialectAsmParser &parser, Type type) const override
Parse an attribute registered to this dialect.
virtual void printType(Type type, DialectAsmPrinter &printer) const override
Print a type registered to this dialect.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
virtual Type parseType(DialectAsmParser &parser) const override
Parse a type registered to this dialect.
The definition of a dynamic op.
LogicalResult verifyInvariants(Operation *op) final
TypeID getTypeID()
Returns the op typeID.
LogicalResult foldHook(Operation *op, ArrayRef< Attribute > attrs, SmallVectorImpl< OpFoldResult > &results) final
LogicalResult verifyRegionInvariants(Operation *op) final
void setParseFn(OperationName::ParseAssemblyFn &&parse)
Sets the static hook for parsing this op assembly.
bool hasTrait(TypeID id) final
void setVerifyRegionFn(OperationName::VerifyRegionInvariantsFn &&verify)
Sets the region verifier function for this operation.
static std::unique_ptr< DynamicOpDefinition > get(StringRef name, ExtensibleDialect *dialect, OperationName::VerifyInvariantsFn &&verifyFn, OperationName::VerifyRegionInvariantsFn &&verifyRegionFn)
Create a new op at runtime.
void printAssembly(Operation *op, OpAsmPrinter &printer, StringRef name) final
Attribute getPropertiesAsAttr(Operation *op) final
void initProperties(OperationName opName, OpaqueProperties storage, OpaqueProperties init) final
std::optional< Attribute > getInherentAttr(Operation *op, StringRef name) final
Implementation for properties (unsupported right now here).
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
OperationName::ParseAssemblyFn getParseAssemblyFn() final
void setFoldHookFn(OperationName::FoldHookFn &&foldHook)
Sets the hook implementing a generalized folder for the op.
void copyProperties(OpaqueProperties lhs, OpaqueProperties rhs) final
LogicalResult setPropertiesFromAttr(OperationName opName, OpaqueProperties properties, Attribute attr, function_ref< InFlightDiagnostic()> emitError) final
LogicalResult verifyInherentAttrs(OperationName opName, NamedAttrList &attributes, function_ref< InFlightDiagnostic()> emitError) final
void populateDefaultAttrs(const OperationName &name, NamedAttrList &attrs) final
bool compareProperties(OpaqueProperties, OpaqueProperties) final
void setInherentAttr(Operation *op, StringAttr name, Attribute value) final
void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final
void deleteProperties(OpaqueProperties prop) final
void setVerifyFn(OperationName::VerifyInvariantsFn &&verify)
Sets the verifier function for this operation.
void populateDefaultProperties(OperationName opName, OpaqueProperties properties) final
llvm::hash_code hashProperties(OpaqueProperties prop) final
void setGetCanonicalizationPatternsFn(GetCanonicalizationPatternsFn &&getCanonicalizationPatterns)
Set the hook returning any canonicalization pattern rewrites that the op supports,...
void setPrintFn(OperationName::PrintAssemblyFn &&print)
Sets the static hook for printing this op assembly.
void setPopulateDefaultAttrsFn(OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrs)
Set the hook populating default attributes.
void getCanonicalizationPatterns(RewritePatternSet &set, MLIRContext *context) final
The definition of a dynamic type.
void setPrintFn(PrinterFn &&print)
Sets the static hook for printing this type assembly.
LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, ArrayRef< Attribute > params) const
Check that the type parameters are valid.
StringRef getName() const
Return the name of the type, in the format 'typename' and not 'dialectname.typename'.
void setVerifyFn(VerifierFn &&verify)
Sets the verifier function for this type.
void setParseFn(ParserFn &&parse)
Sets the static hook for parsing this type assembly.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
ExtensibleDialect * getDialect() const
Return the dialect defining the type.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
static std::unique_ptr< DynamicTypeDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new dynamic type definition.
A dynamic type instance.
static DynamicType getChecked(function_ref< InFlightDiagnostic()> emitError, DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic type given a dynamic type definition and type parameters.
ArrayRef< Attribute > getParams()
Return the type parameters.
static bool isa(Type type, DynamicTypeDefinition *typeDef)
Check if a type is a specific dynamic type.
void print(AsmPrinter &printer)
Print the dynamic type with the format 'type' or 'type<>' if there is no parameters,...
DynamicTypeDefinition * getTypeDef()
Return the type definition of the concrete type.
static DynamicType get(DynamicTypeDefinition *typeDef, ArrayRef< Attribute > params={})
Return an instance of a dynamic type given a dynamic type definition and type parameters.
static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef, DynamicType &parsedType)
Parse the dynamic type parameters and construct the type.
static bool classof(Type type)
Check if a type is a dynamic type.
A dialect that can be extended with new operations/types/attributes at runtime.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
void registerDynamicOp(std::unique_ptr< DynamicOpDefinition > &&type)
Add a new operation defined at runtime to the dialect.
static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer)
If 'type' is a dynamic type, print it.
void registerDynamicType(std::unique_ptr< DynamicTypeDefinition > &&type)
Add a new type defined at runtime to the dialect.
static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer)
If 'attr' is a dynamic attribute, print it.
OptionalParseResult parseOptionalDynamicAttr(StringRef attrName, AsmParser &parser, Attribute &resultAttr) const
Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
DynamicAttrDefinition * lookupAttrDefinition(TypeID id) const
Returns nullptr if the definition was not found.
DynamicTypeDefinition * lookupTypeDefinition(TypeID id) const
Returns nullptr if the definition was not found.
ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID)
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
void registerDynamicAttr(std::unique_ptr< DynamicAttrDefinition > &&attr)
Add a new attribute defined at runtime to the dialect.
OptionalParseResult parseOptionalDynamicType(StringRef typeName, AsmParser &parser, Type &resultType) const
Parse the dynamic type 'typeName' in the dialect 'dialect'.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:313
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
StringAttr name
The name of the operation.
TypeID typeID
The unique identifier of the derived Op class.
Dialect * dialect
The following fields are only populated when the operation is registered.
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
llvm::unique_function< void(const OperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:39
Defines a TypeID for each instance of this class by using a pointer to the instance.
Definition: TypeID.h:312
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition: TypeID.h:324
TypeID allocate()
Allocate a new TypeID, that is ensured to be unique for the lifetime of the TypeIDAllocator.
Definition: TypeID.h:296
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
TypeID getTypeID()
Return a unique identifier for the concrete type.
Definition: Types.h:117
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
Helper class for implementing traits for storage classes.
Include the generated interface declarations.
Definition: CallGraph.h:229
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:20
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:421
static bool doit(const ::mlir::Dialect &dialect)
static bool doit(const ::mlir::Dialect &dialect)
This represents an operation in an abstracted form, suitable for use with the builder APIs.