MLIR  19.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 class ParseResult;
42 
43 namespace detail {
44 struct DynamicAttrStorage;
45 struct DynamicTypeStorage;
46 } // namespace detail
47 
48 //===----------------------------------------------------------------------===//
49 // Dynamic attribute
50 //===----------------------------------------------------------------------===//
51 
52 /// The definition of a dynamic attribute. A dynamic attribute is an attribute
53 /// that is defined at runtime, and that can be registered at runtime by an
54 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
55 /// stores the parser, the printer, and the verifier of the attribute. Each
56 /// dynamic attribute definition refers to one instance of this class.
58 public:
59  using VerifierFn = llvm::unique_function<LogicalResult(
61  using ParserFn = llvm::unique_function<ParseResult(
62  AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
63  const>;
64  using PrinterFn = llvm::unique_function<void(
65  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
66 
67  /// Create a new attribute definition at runtime. The attribute is registered
68  /// only after passing it to the dialect using registerDynamicAttr.
69  static std::unique_ptr<DynamicAttrDefinition>
70  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
71  static std::unique_ptr<DynamicAttrDefinition>
72  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
73  ParserFn &&parser, PrinterFn &&printer);
74 
75  /// Sets the verifier function for this attribute. It should emits an error
76  /// message and returns failure if a problem is detected, or returns success
77  /// if everything is ok.
78  void setVerifyFn(VerifierFn &&verify) { verifier = std::move(verify); }
79 
80  /// Sets the static hook for parsing this attribute assembly.
81  void setParseFn(ParserFn &&parse) { parser = std::move(parse); }
82 
83  /// Sets the static hook for printing this attribute assembly.
84  void setPrintFn(PrinterFn &&print) { printer = std::move(print); }
85 
86  /// Check that the attribute parameters are valid.
88  ArrayRef<Attribute> params) const {
89  return verifier(emitError, params);
90  }
91 
92  /// Return the MLIRContext in which the dynamic attributes are uniqued.
93  MLIRContext &getContext() const { return *ctx; }
94 
95  /// Return the name of the attribute, in the format 'attrname' and
96  /// not 'dialectname.attrname'.
97  StringRef getName() const { return name; }
98 
99  /// Return the dialect defining the attribute.
100  ExtensibleDialect *getDialect() const { return dialect; }
101 
102 private:
103  DynamicAttrDefinition(StringRef name, ExtensibleDialect *dialect,
104  VerifierFn &&verifier, ParserFn &&parser,
105  PrinterFn &&printer);
106 
107  /// This constructor should only be used when we need a pointer to
108  /// the DynamicAttrDefinition in the verifier, the parser, or the printer.
109  /// The verifier, parser, and printer need thus to be initialized after the
110  /// constructor.
111  DynamicAttrDefinition(ExtensibleDialect *dialect, StringRef name);
112 
113  /// Register the concrete attribute in the attribute Uniquer.
114  void registerInAttrUniquer();
115 
116  /// The name should be prefixed with the dialect name followed by '.'.
117  std::string name;
118 
119  /// Dialect in which this attribute is defined.
120  ExtensibleDialect *dialect;
121 
122  /// The attribute verifier. It checks that the attribute parameters satisfy
123  /// the invariants.
124  VerifierFn verifier;
125 
126  /// The attribute parameters parser. It parses only the parameters, and
127  /// expects the attribute name to have already been parsed.
128  ParserFn parser;
129 
130  /// The attribute parameters printer. It prints only the parameters, and
131  /// expects the attribute name to have already been printed.
132  PrinterFn printer;
133 
134  /// Context in which the concrete attributes are uniqued.
135  MLIRContext *ctx;
136 
137  friend ExtensibleDialect;
138  friend DynamicAttr;
139 };
140 
141 /// This trait is used to determine if an attribute is a dynamic attribute or
142 /// not; it should only be implemented by dynamic attributes.
143 /// Note: This is only required because dynamic attributes do not have a
144 /// static/single TypeID.
145 namespace AttributeTrait {
146 template <typename ConcreteType>
147 class IsDynamicAttr : public TraitBase<ConcreteType, IsDynamicAttr> {};
148 } // namespace AttributeTrait
149 
150 /// A dynamic attribute instance. This is an attribute whose definition is
151 /// defined at runtime.
152 /// It is possible to check if an attribute is a dynamic attribute using
153 /// `my_attr.isa<DynamicAttr>()`, and getting the attribute definition of a
154 /// dynamic attribute using the `DynamicAttr::getAttrDef` method.
155 /// All dynamic attributes have the same storage, which is an array of
156 /// attributes.
157 
158 class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute,
159  detail::DynamicAttrStorage,
160  AttributeTrait::IsDynamicAttr> {
161 public:
162  // Inherit Base constructors.
163  using Base::Base;
164 
165  /// Return an instance of a dynamic attribute given a dynamic attribute
166  /// definition and attribute parameters.
167  /// This asserts that the attribute verifier succeeded.
168  static DynamicAttr get(DynamicAttrDefinition *attrDef,
169  ArrayRef<Attribute> params = {});
170 
171  /// Return an instance of a dynamic attribute given a dynamic attribute
172  /// definition and attribute parameters. If the parameters provided are
173  /// invalid, errors are emitted using the provided location and a null object
174  /// is returned.
176  DynamicAttrDefinition *attrDef,
177  ArrayRef<Attribute> params = {});
178 
179  /// Return the attribute definition of the concrete attribute.
181 
182  /// Return the attribute parameters.
184 
185  /// Check if an attribute is a specific dynamic attribute.
186  static bool isa(Attribute attr, DynamicAttrDefinition *attrDef) {
187  return attr.getTypeID() == attrDef->getTypeID();
188  }
189 
190  /// Check if an attribute is a dynamic attribute.
191  static bool classof(Attribute attr);
192 
193  /// Parse the dynamic attribute parameters and construct the attribute.
194  /// The parameters are either empty, and nothing is parsed,
195  /// or they are in the format '<>' or '<attr (,attr)*>'.
196  static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef,
197  DynamicAttr &parsedAttr);
198 
199  /// Print the dynamic attribute with the format 'attrname' if there is no
200  /// parameters, or 'attrname<attr (,attr)*>'.
201  void print(AsmPrinter &printer);
202 };
203 
204 //===----------------------------------------------------------------------===//
205 // Dynamic type
206 //===----------------------------------------------------------------------===//
207 
208 /// The definition of a dynamic type. A dynamic type is a type that is
209 /// defined at runtime, and that can be registered at runtime by an
210 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
211 /// stores the parser, the printer, and the verifier of the type. Each dynamic
212 /// type definition refers to one instance of this class.
214 public:
215  using VerifierFn = llvm::unique_function<LogicalResult(
217  using ParserFn = llvm::unique_function<ParseResult(
218  AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
219  const>;
220  using PrinterFn = llvm::unique_function<void(
221  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
222 
223  /// Create a new dynamic type definition. The type is registered only after
224  /// passing it to the dialect using registerDynamicType.
225  static std::unique_ptr<DynamicTypeDefinition>
226  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
227  static std::unique_ptr<DynamicTypeDefinition>
228  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
229  ParserFn &&parser, PrinterFn &&printer);
230 
231  /// Sets the verifier function for this type. It should emits an error
232  /// message and returns failure if a problem is detected, or returns success
233  /// if everything is ok.
234  void setVerifyFn(VerifierFn &&verify) { verifier = std::move(verify); }
235 
236  /// Sets the static hook for parsing this type assembly.
237  void setParseFn(ParserFn &&parse) { parser = std::move(parse); }
238 
239  /// Sets the static hook for printing this type assembly.
240  void setPrintFn(PrinterFn &&print) { printer = std::move(print); }
241 
242  /// Check that the type parameters are valid.
244  ArrayRef<Attribute> params) const {
245  return verifier(emitError, params);
246  }
247 
248  /// Return the MLIRContext in which the dynamic types is uniqued.
249  MLIRContext &getContext() const { return *ctx; }
250 
251  /// Return the name of the type, in the format 'typename' and
252  /// not 'dialectname.typename'.
253  StringRef getName() const { return name; }
254 
255  /// Return the dialect defining the type.
256  ExtensibleDialect *getDialect() const { return dialect; }
257 
258 private:
259  DynamicTypeDefinition(StringRef name, ExtensibleDialect *dialect,
260  VerifierFn &&verifier, ParserFn &&parser,
261  PrinterFn &&printer);
262 
263  /// This constructor should only be used when we need a pointer to
264  /// the DynamicTypeDefinition in the verifier, the parser, or the printer.
265  /// The verifier, parser, and printer need thus to be initialized after the
266  /// constructor.
267  DynamicTypeDefinition(ExtensibleDialect *dialect, StringRef name);
268 
269  /// Register the concrete type in the type Uniquer.
270  void registerInTypeUniquer();
271 
272  /// The name should be prefixed with the dialect name followed by '.'.
273  std::string name;
274 
275  /// Dialect in which this type is defined.
276  ExtensibleDialect *dialect;
277 
278  /// The type verifier. It checks that the type parameters satisfy the
279  /// invariants.
280  VerifierFn verifier;
281 
282  /// The type parameters parser. It parses only the parameters, and expects the
283  /// type name to have already been parsed.
284  ParserFn parser;
285 
286  /// The type parameters printer. It prints only the parameters, and expects
287  /// the type name to have already been printed.
288  PrinterFn printer;
289 
290  /// Context in which the concrete types are uniqued.
291  MLIRContext *ctx;
292 
293  friend ExtensibleDialect;
294  friend DynamicType;
295 };
296 
297 /// This trait is used to determine if a type is a dynamic type or not;
298 /// it should only be implemented by dynamic types.
299 /// Note: This is only required because dynamic type do not have a
300 /// static/single TypeID.
301 namespace TypeTrait {
302 template <typename ConcreteType>
303 class IsDynamicType : public TypeTrait::TraitBase<ConcreteType, IsDynamicType> {
304 };
305 } // namespace TypeTrait
306 
307 /// A dynamic type instance. This is a type whose definition is defined at
308 /// runtime.
309 /// It is possible to check if a type is a dynamic type using
310 /// `my_type.isa<DynamicType>()`, and getting the type definition of a dynamic
311 /// type using the `DynamicType::getTypeDef` method.
312 /// All dynamic types have the same storage, which is an array of attributes.
314  : public Type::TypeBase<DynamicType, Type, detail::DynamicTypeStorage,
315  TypeTrait::IsDynamicType> {
316 public:
317  // Inherit Base constructors.
318  using Base::Base;
319 
320  /// Return an instance of a dynamic type given a dynamic type definition and
321  /// type parameters.
322  /// This asserts that the type verifier succeeded.
323  static DynamicType get(DynamicTypeDefinition *typeDef,
324  ArrayRef<Attribute> params = {});
325 
326  /// Return an instance of a dynamic type given a dynamic type definition and
327  /// type parameters. If the parameters provided are invalid, errors are
328  /// emitted using the provided location and a null object is returned.
330  DynamicTypeDefinition *typeDef,
331  ArrayRef<Attribute> params = {});
332 
333  /// Return the type definition of the concrete type.
335 
336  /// Return the type parameters.
338 
339  /// Check if a type is a specific dynamic type.
340  static bool isa(Type type, DynamicTypeDefinition *typeDef) {
341  return type.getTypeID() == typeDef->getTypeID();
342  }
343 
344  /// Check if a type is a dynamic type.
345  static bool classof(Type type);
346 
347  /// Parse the dynamic type parameters and construct the type.
348  /// The parameters are either empty, and nothing is parsed,
349  /// or they are in the format '<>' or '<attr (,attr)*>'.
350  static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef,
351  DynamicType &parsedType);
352 
353  /// Print the dynamic type with the format
354  /// 'type' or 'type<>' if there is no parameters, or 'type<attr (,attr)*>'.
355  void print(AsmPrinter &printer);
356 };
357 
358 //===----------------------------------------------------------------------===//
359 // Dynamic operation
360 //===----------------------------------------------------------------------===//
361 
362 /// The definition of a dynamic op. A dynamic op is an op that is defined at
363 /// runtime, and that can be registered at runtime by an extensible dialect (a
364 /// dialect inheriting ExtensibleDialect). This class implements the method
365 /// exposed by the OperationName class, and in addition defines the TypeID of
366 /// the op that will be defined. Each dynamic operation definition refers to one
367 /// instance of this class.
369 public:
371  llvm::unique_function<void(RewritePatternSet &, MLIRContext *) const>;
372 
373  /// Create a new op at runtime. The op is registered only after passing it to
374  /// the dialect using registerDynamicOp.
375  static std::unique_ptr<DynamicOpDefinition>
376  get(StringRef name, ExtensibleDialect *dialect,
378  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn);
379  static std::unique_ptr<DynamicOpDefinition>
380  get(StringRef name, ExtensibleDialect *dialect,
385  static std::unique_ptr<DynamicOpDefinition>
386  get(StringRef name, ExtensibleDialect *dialect,
391  OperationName::FoldHookFn &&foldHookFn,
392  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
393  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
394 
395  /// Returns the op typeID.
396  TypeID getTypeID() { return typeID; }
397 
398  /// Sets the verifier function for this operation. It should emits an error
399  /// message and returns failure if a problem is detected, or returns success
400  /// if everything is ok.
402  verifyFn = std::move(verify);
403  }
404 
405  /// Sets the region verifier function for this operation. It should emits an
406  /// error message and returns failure if a problem is detected, or returns
407  /// success if everything is ok.
409  verifyRegionFn = std::move(verify);
410  }
411 
412  /// Sets the static hook for parsing this op assembly.
414  parseFn = std::move(parse);
415  }
416 
417  /// Sets the static hook for printing this op assembly.
419  printFn = std::move(print);
420  }
421 
422  /// Sets the hook implementing a generalized folder for the op. See
423  /// `RegisteredOperationName::foldHook` for more details
425  foldHookFn = std::move(foldHook);
426  }
427 
428  /// Set the hook returning any canonicalization pattern rewrites that the op
429  /// supports, for use by the canonicalization pass.
432  getCanonicalizationPatternsFn = std::move(getCanonicalizationPatterns);
433  }
434 
435  /// Set the hook populating default attributes.
438  populateDefaultAttrsFn = std::move(populateDefaultAttrs);
439  }
440 
442  SmallVectorImpl<OpFoldResult> &results) final {
443  return foldHookFn(op, attrs, results);
444  }
446  MLIRContext *context) final {
447  getCanonicalizationPatternsFn(set, context);
448  }
449  bool hasTrait(TypeID id) final { return false; }
451  return [&](OpAsmParser &parser, OperationState &state) {
452  return parseFn(parser, state);
453  };
454  }
456  NamedAttrList &attrs) final {
457  populateDefaultAttrsFn(name, attrs);
458  }
460  StringRef name) final {
461  printFn(op, printer, name);
462  }
463  LogicalResult verifyInvariants(Operation *op) final { return verifyFn(op); }
465  return verifyRegionFn(op);
466  }
467 
468  /// Implementation for properties (unsupported right now here).
469  std::optional<Attribute> getInherentAttr(Operation *op,
470  StringRef name) final {
471  llvm::report_fatal_error("Unsupported getInherentAttr on Dynamic dialects");
472  }
473  void setInherentAttr(Operation *op, StringAttr name, Attribute value) final {
474  llvm::report_fatal_error("Unsupported setInherentAttr on Dynamic dialects");
475  }
476  void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final {}
480  return success();
481  }
482  int getOpPropertyByteSize() final { return 0; }
484  OpaqueProperties init) final {}
485  void deleteProperties(OpaqueProperties prop) final {}
487  OpaqueProperties properties) final {}
488 
491  Attribute attr,
493  emitError() << "extensible Dialects don't support properties";
494  return failure();
495  }
496  Attribute getPropertiesAsAttr(Operation *op) final { return {}; }
498  bool compareProperties(OpaqueProperties, OpaqueProperties) final { return false; }
499  llvm::hash_code hashProperties(OpaqueProperties prop) final { return {}; }
500 
501 private:
503  StringRef name, ExtensibleDialect *dialect,
508  OperationName::FoldHookFn &&foldHookFn,
509  GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
510  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
511 
512  /// Dialect defining this operation.
513  ExtensibleDialect *getdialect();
514 
519  OperationName::FoldHookFn foldHookFn;
520  GetCanonicalizationPatternsFn getCanonicalizationPatternsFn;
521  OperationName::PopulateDefaultAttrsFn populateDefaultAttrsFn;
522 
523  friend ExtensibleDialect;
524 };
525 
526 //===----------------------------------------------------------------------===//
527 // Extensible dialect
528 //===----------------------------------------------------------------------===//
529 
530 /// A dialect that can be extended with new operations/types/attributes at
531 /// runtime.
533 public:
534  ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID);
535 
536  /// Add a new type defined at runtime to the dialect.
537  void registerDynamicType(std::unique_ptr<DynamicTypeDefinition> &&type);
538 
539  /// Add a new attribute defined at runtime to the dialect.
540  void registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> &&attr);
541 
542  /// Add a new operation defined at runtime to the dialect.
543  void registerDynamicOp(std::unique_ptr<DynamicOpDefinition> &&type);
544 
545  /// Check if the dialect is an extensible dialect.
546  static bool classof(const Dialect *dialect);
547 
548  /// Returns nullptr if the definition was not found.
550  return nameToDynTypes.lookup(name);
551  }
552 
553  /// Returns nullptr if the definition was not found.
555  auto it = dynTypes.find(id);
556  if (it == dynTypes.end())
557  return nullptr;
558  return it->second.get();
559  }
560 
561  /// Returns nullptr if the definition was not found.
563  return nameToDynAttrs.lookup(name);
564  }
565 
566  /// Returns nullptr if the definition was not found.
568  auto it = dynAttrs.find(id);
569  if (it == dynAttrs.end())
570  return nullptr;
571  return it->second.get();
572  }
573 
574 protected:
575  /// Parse the dynamic type 'typeName' in the dialect 'dialect'.
576  /// typename should not be prefixed with the dialect name.
577  /// If the dynamic type does not exist, return no value.
578  /// Otherwise, parse it, and return the parse result.
579  /// If the parsing succeed, put the resulting type in 'resultType'.
581  AsmParser &parser,
582  Type &resultType) const;
583 
584  /// If 'type' is a dynamic type, print it.
585  /// Returns success if the type was printed, and failure if the type was not a
586  /// dynamic type.
587  static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer);
588 
589  /// Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
590  /// attrname should not be prefixed with the dialect name.
591  /// If the dynamic attribute does not exist, return no value.
592  /// Otherwise, parse it, and return the parse result.
593  /// If the parsing succeed, put the resulting attribute in 'resultAttr'.
595  AsmParser &parser,
596  Attribute &resultAttr) const;
597 
598  /// If 'attr' is a dynamic attribute, print it.
599  /// Returns success if the attribute was printed, and failure if the
600  /// attribute was not a dynamic attribute.
601  static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer);
602 
603 private:
604  /// The set of all dynamic types registered.
606 
607  /// This structure allows to get in O(1) a dynamic type given its name.
608  llvm::StringMap<DynamicTypeDefinition *> nameToDynTypes;
609 
610  /// The set of all dynamic attributes registered.
612 
613  /// This structure allows to get in O(1) a dynamic attribute given its name.
614  llvm::StringMap<DynamicAttrDefinition *> nameToDynAttrs;
615 
616  /// Give DynamicOpDefinition access to allocateTypeID.
617  friend DynamicOpDefinition;
618 
619  /// Allocates a type ID to uniquify operations.
620  TypeID allocateTypeID() { return typeIDAllocator.allocate(); }
621 
622  /// Owns the TypeID generated at runtime for operations.
623  TypeIDAllocator typeIDAllocator;
624 };
625 
626 //===----------------------------------------------------------------------===//
627 // Dynamic dialect
628 //===----------------------------------------------------------------------===//
629 
630 /// A dialect that can be defined at runtime. It can be extended with new
631 /// operations, types, and attributes at runtime.
633 public:
634  DynamicDialect(StringRef name, MLIRContext *ctx);
635 
637 
638  /// Check if the dialect is an extensible dialect.
639  static bool classof(const Dialect *dialect);
640 
641  virtual Type parseType(DialectAsmParser &parser) const override;
642  virtual void printType(Type type, DialectAsmPrinter &printer) const override;
643 
644  virtual Attribute parseAttribute(DialectAsmParser &parser,
645  Type type) const override;
646  virtual void printAttribute(Attribute attr,
647  DialectAsmPrinter &printer) const override;
648 };
649 } // namespace mlir
650 
651 namespace llvm {
652 /// Provide isa functionality for ExtensibleDialect.
653 /// This is to override the isa functionality for Dialect.
654 template <>
655 struct isa_impl<mlir::ExtensibleDialect, mlir::Dialect> {
656  static inline bool doit(const ::mlir::Dialect &dialect) {
657  return mlir::ExtensibleDialect::classof(&dialect);
658  }
659 };
660 
661 /// Provide isa functionality for DynamicDialect.
662 /// This is to override the isa functionality for Dialect.
663 template <>
664 struct isa_impl<mlir::DynamicDialect, mlir::Dialect> {
665  static inline bool doit(const ::mlir::Dialect &dialect) {
666  return mlir::DynamicDialect::classof(&dialect);
667  }
668 };
669 } // namespace llvm
670 
671 #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:65
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:41
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:308
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
This class represents success/failure for parsing-like operations that find it important to chain tog...
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:112
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:21
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
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 class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This represents an operation in an abstracted form, suitable for use with the builder APIs.