MLIR  16.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"
27 #include "mlir/Support/TypeID.h"
28 #include "llvm/ADT/StringMap.h"
29 
30 namespace mlir {
31 class AsmParser;
32 class AsmPrinter;
33 class DynamicAttr;
34 class DynamicType;
35 class ExtensibleDialect;
36 class MLIRContext;
37 class OptionalParseResult;
38 class ParseResult;
39 
40 namespace detail {
41 struct DynamicAttrStorage;
42 struct DynamicTypeStorage;
43 } // namespace detail
44 
45 //===----------------------------------------------------------------------===//
46 // Dynamic attribute
47 //===----------------------------------------------------------------------===//
48 
49 /// The definition of a dynamic attribute. A dynamic attribute is an attribute
50 /// that is defined at runtime, and that can be registered at runtime by an
51 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
52 /// stores the parser, the printer, and the verifier of the attribute. Each
53 /// dynamic attribute definition refers to one instance of this class.
55 public:
56  using VerifierFn = llvm::unique_function<LogicalResult(
58  using ParserFn = llvm::unique_function<ParseResult(
60  const>;
61  using PrinterFn = llvm::unique_function<void(
62  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
63 
64  /// Create a new attribute definition at runtime. The attribute is registered
65  /// only after passing it to the dialect using registerDynamicAttr.
66  static std::unique_ptr<DynamicAttrDefinition>
67  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
68  static std::unique_ptr<DynamicAttrDefinition>
69  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
70  ParserFn &&parser, PrinterFn &&printer);
71 
72  /// Check that the attribute parameters are valid.
74  ArrayRef<Attribute> params) const {
75  return verifier(emitError, params);
76  }
77 
78  /// Return the MLIRContext in which the dynamic attributes are uniqued.
79  MLIRContext &getContext() const { return *ctx; }
80 
81  /// Return the name of the attribute, in the format 'attrname' and
82  /// not 'dialectname.attrname'.
83  StringRef getName() const { return name; }
84 
85  /// Return the dialect defining the attribute.
86  ExtensibleDialect *getDialect() const { return dialect; }
87 
88 private:
89  DynamicAttrDefinition(StringRef name, ExtensibleDialect *dialect,
90  VerifierFn &&verifier, ParserFn &&parser,
91  PrinterFn &&printer);
92 
93  /// This constructor should only be used when we need a pointer to
94  /// the DynamicAttrDefinition in the verifier, the parser, or the printer.
95  /// The verifier, parser, and printer need thus to be initialized after the
96  /// constructor.
97  DynamicAttrDefinition(ExtensibleDialect *dialect, StringRef name);
98 
99  /// Register the concrete attribute in the attribute Uniquer.
100  void registerInAttrUniquer();
101 
102  /// The name should be prefixed with the dialect name followed by '.'.
103  std::string name;
104 
105  /// Dialect in which this attribute is defined.
106  ExtensibleDialect *dialect;
107 
108  /// The attribute verifier. It checks that the attribute parameters satisfy
109  /// the invariants.
110  VerifierFn verifier;
111 
112  /// The attribute parameters parser. It parses only the parameters, and
113  /// expects the attribute name to have already been parsed.
115 
116  /// The attribute parameters printer. It prints only the parameters, and
117  /// expects the attribute name to have already been printed.
118  PrinterFn printer;
119 
120  /// Context in which the concrete attributes are uniqued.
121  MLIRContext *ctx;
122 
123  friend ExtensibleDialect;
124  friend DynamicAttr;
125 };
126 
127 /// This trait is used to determine if an attribute is a dynamic attribute or
128 /// not; it should only be implemented by dynamic attributes.
129 /// Note: This is only required because dynamic attributes do not have a
130 /// static/single TypeID.
131 namespace AttributeTrait {
132 template <typename ConcreteType>
133 class IsDynamicAttr : public TraitBase<ConcreteType, IsDynamicAttr> {};
134 } // namespace AttributeTrait
135 
136 /// A dynamic attribute instance. This is an attribute whose definition is
137 /// defined at runtime.
138 /// It is possible to check if an attribute is a dynamic attribute using
139 /// `my_attr.isa<DynamicAttr>()`, and getting the attribute definition of a
140 /// dynamic attribute using the `DynamicAttr::getAttrDef` method.
141 /// All dynamic attributes have the same storage, which is an array of
142 /// attributes.
143 
144 class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute,
145  detail::DynamicAttrStorage,
146  AttributeTrait::IsDynamicAttr> {
147 public:
148  // Inherit Base constructors.
149  using Base::Base;
150 
151  /// Return an instance of a dynamic attribute given a dynamic attribute
152  /// definition and attribute parameters.
153  /// This asserts that the attribute verifier succeeded.
154  static DynamicAttr get(DynamicAttrDefinition *attrDef,
155  ArrayRef<Attribute> params = {});
156 
157  /// Return an instance of a dynamic attribute given a dynamic attribute
158  /// definition and attribute parameters. If the parameters provided are
159  /// invalid, errors are emitted using the provided location and a null object
160  /// is returned.
162  DynamicAttrDefinition *attrDef,
163  ArrayRef<Attribute> params = {});
164 
165  /// Return the attribute definition of the concrete attribute.
166  DynamicAttrDefinition *getAttrDef();
167 
168  /// Return the attribute parameters.
169  ArrayRef<Attribute> getParams();
170 
171  /// Check if an attribute is a specific dynamic attribute.
172  static bool isa(Attribute attr, DynamicAttrDefinition *attrDef) {
173  return attr.getTypeID() == attrDef->getTypeID();
174  }
175 
176  /// Check if an attribute is a dynamic attribute.
177  static bool classof(Attribute attr);
178 
179  /// Parse the dynamic attribute parameters and construct the attribute.
180  /// The parameters are either empty, and nothing is parsed,
181  /// or they are in the format '<>' or '<attr (,attr)*>'.
182  static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef,
183  DynamicAttr &parsedAttr);
184 
185  /// Print the dynamic attribute with the format 'attrname' if there is no
186  /// parameters, or 'attrname<attr (,attr)*>'.
187  void print(AsmPrinter &printer);
188 };
189 
190 //===----------------------------------------------------------------------===//
191 // Dynamic type
192 //===----------------------------------------------------------------------===//
193 
194 /// The definition of a dynamic type. A dynamic type is a type that is
195 /// defined at runtime, and that can be registered at runtime by an
196 /// extensible dialect (a dialect inheriting ExtensibleDialect). This class
197 /// stores the parser, the printer, and the verifier of the type. Each dynamic
198 /// type definition refers to one instance of this class.
200 public:
201  using VerifierFn = llvm::unique_function<LogicalResult(
203  using ParserFn = llvm::unique_function<ParseResult(
205  const>;
206  using PrinterFn = llvm::unique_function<void(
207  AsmPrinter &printer, ArrayRef<Attribute> params) const>;
208 
209  /// Create a new dynamic type definition. The type is registered only after
210  /// passing it to the dialect using registerDynamicType.
211  static std::unique_ptr<DynamicTypeDefinition>
212  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
213  static std::unique_ptr<DynamicTypeDefinition>
214  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
215  ParserFn &&parser, PrinterFn &&printer);
216 
217  /// Check that the type parameters are valid.
219  ArrayRef<Attribute> params) const {
220  return verifier(emitError, params);
221  }
222 
223  /// Return the MLIRContext in which the dynamic types is uniqued.
224  MLIRContext &getContext() const { return *ctx; }
225 
226  /// Return the name of the type, in the format 'typename' and
227  /// not 'dialectname.typename'.
228  StringRef getName() const { return name; }
229 
230  /// Return the dialect defining the type.
231  ExtensibleDialect *getDialect() const { return dialect; }
232 
233 private:
234  DynamicTypeDefinition(StringRef name, ExtensibleDialect *dialect,
235  VerifierFn &&verifier, ParserFn &&parser,
236  PrinterFn &&printer);
237 
238  /// This constructor should only be used when we need a pointer to
239  /// the DynamicTypeDefinition in the verifier, the parser, or the printer.
240  /// The verifier, parser, and printer need thus to be initialized after the
241  /// constructor.
242  DynamicTypeDefinition(ExtensibleDialect *dialect, StringRef name);
243 
244  /// Register the concrete type in the type Uniquer.
245  void registerInTypeUniquer();
246 
247  /// The name should be prefixed with the dialect name followed by '.'.
248  std::string name;
249 
250  /// Dialect in which this type is defined.
251  ExtensibleDialect *dialect;
252 
253  /// The type verifier. It checks that the type parameters satisfy the
254  /// invariants.
255  VerifierFn verifier;
256 
257  /// The type parameters parser. It parses only the parameters, and expects the
258  /// type name to have already been parsed.
260 
261  /// The type parameters printer. It prints only the parameters, and expects
262  /// the type name to have already been printed.
263  PrinterFn printer;
264 
265  /// Context in which the concrete types are uniqued.
266  MLIRContext *ctx;
267 
268  friend ExtensibleDialect;
269  friend DynamicType;
270 };
271 
272 /// This trait is used to determine if a type is a dynamic type or not;
273 /// it should only be implemented by dynamic types.
274 /// Note: This is only required because dynamic type do not have a
275 /// static/single TypeID.
276 namespace TypeTrait {
277 template <typename ConcreteType>
278 class IsDynamicType : public TypeTrait::TraitBase<ConcreteType, IsDynamicType> {
279 };
280 } // namespace TypeTrait
281 
282 /// A dynamic type instance. This is a type whose definition is defined at
283 /// runtime.
284 /// It is possible to check if a type is a dynamic type using
285 /// `my_type.isa<DynamicType>()`, and getting the type definition of a dynamic
286 /// type using the `DynamicType::getTypeDef` method.
287 /// All dynamic types have the same storage, which is an array of attributes.
289  : public Type::TypeBase<DynamicType, Type, detail::DynamicTypeStorage,
290  TypeTrait::IsDynamicType> {
291 public:
292  // Inherit Base constructors.
293  using Base::Base;
294 
295  /// Return an instance of a dynamic type given a dynamic type definition and
296  /// type parameters.
297  /// This asserts that the type verifier succeeded.
298  static DynamicType get(DynamicTypeDefinition *typeDef,
299  ArrayRef<Attribute> params = {});
300 
301  /// Return an instance of a dynamic type given a dynamic type definition and
302  /// type parameters. If the parameters provided are invalid, errors are
303  /// emitted using the provided location and a null object is returned.
305  DynamicTypeDefinition *typeDef,
306  ArrayRef<Attribute> params = {});
307 
308  /// Return the type definition of the concrete type.
309  DynamicTypeDefinition *getTypeDef();
310 
311  /// Return the type parameters.
312  ArrayRef<Attribute> getParams();
313 
314  /// Check if a type is a specific dynamic type.
315  static bool isa(Type type, DynamicTypeDefinition *typeDef) {
316  return type.getTypeID() == typeDef->getTypeID();
317  }
318 
319  /// Check if a type is a dynamic type.
320  static bool classof(Type type);
321 
322  /// Parse the dynamic type parameters and construct the type.
323  /// The parameters are either empty, and nothing is parsed,
324  /// or they are in the format '<>' or '<attr (,attr)*>'.
325  static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef,
326  DynamicType &parsedType);
327 
328  /// Print the dynamic type with the format
329  /// 'type' or 'type<>' if there is no parameters, or 'type<attr (,attr)*>'.
330  void print(AsmPrinter &printer);
331 };
332 
333 //===----------------------------------------------------------------------===//
334 // Dynamic operation
335 //===----------------------------------------------------------------------===//
336 
337 /// The definition of a dynamic op. A dynamic op is an op that is defined at
338 /// runtime, and that can be registered at runtime by an extensible dialect (a
339 /// dialect inheriting ExtensibleDialect). This class stores the functions that
340 /// are in the OperationName class, and in addition defines the TypeID of the op
341 /// that will be defined.
342 /// Each dynamic operation definition refers to one instance of this class.
344 public:
345  /// Create a new op at runtime. The op is registered only after passing it to
346  /// the dialect using registerDynamicOp.
347  static std::unique_ptr<DynamicOpDefinition>
348  get(StringRef name, ExtensibleDialect *dialect,
350  OperationName::VerifyRegionInvariantsFn &&verifyRegionFn);
351  static std::unique_ptr<DynamicOpDefinition>
352  get(StringRef name, ExtensibleDialect *dialect,
357  static std::unique_ptr<DynamicOpDefinition>
358  get(StringRef name, ExtensibleDialect *dialect,
363  OperationName::FoldHookFn &&foldHookFn,
365  &&getCanonicalizationPatternsFn,
366  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
367 
368  /// Returns the op typeID.
369  TypeID getTypeID() { return typeID; }
370 
371  /// Sets the verifier function for this operation. It should emits an error
372  /// message and returns failure if a problem is detected, or returns success
373  /// if everything is ok.
375  verifyFn = std::move(verify);
376  }
377 
378  /// Sets the region verifier function for this operation. It should emits an
379  /// error message and returns failure if a problem is detected, or returns
380  /// success if everything is ok.
382  verifyRegionFn = std::move(verify);
383  }
384 
385  /// Sets the static hook for parsing this op assembly.
387  parseFn = std::move(parse);
388  }
389 
390  /// Sets the static hook for printing this op assembly.
392  printFn = std::move(print);
393  }
394 
395  /// Sets the hook implementing a generalized folder for the op. See
396  /// `RegisteredOperationName::foldHook` for more details
398  foldHookFn = std::move(foldHook);
399  }
400 
401  /// Set the hook returning any canonicalization pattern rewrites that the op
402  /// supports, for use by the canonicalization pass.
403  void
405  &&getCanonicalizationPatterns) {
406  getCanonicalizationPatternsFn = std::move(getCanonicalizationPatterns);
407  }
408 
409  /// Set the hook populating default attributes.
411  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrs) {
412  populateDefaultAttrsFn = std::move(populateDefaultAttrs);
413  }
414 
415 private:
417  StringRef name, ExtensibleDialect *dialect,
422  OperationName::FoldHookFn &&foldHookFn,
424  &&getCanonicalizationPatternsFn,
425  OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
426 
427  /// Unique identifier for this operation.
428  TypeID typeID;
429 
430  /// Name of the operation.
431  /// The name is prefixed with the dialect name.
432  std::string name;
433 
434  /// Dialect defining this operation.
435  ExtensibleDialect *dialect;
436 
441  OperationName::FoldHookFn foldHookFn;
442  OperationName::GetCanonicalizationPatternsFn getCanonicalizationPatternsFn;
443  OperationName::PopulateDefaultAttrsFn populateDefaultAttrsFn;
444 
445  friend ExtensibleDialect;
446 };
447 
448 //===----------------------------------------------------------------------===//
449 // Extensible dialect
450 //===----------------------------------------------------------------------===//
451 
452 /// A dialect that can be extended with new operations/types/attributes at
453 /// runtime.
455 public:
456  ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID);
457 
458  /// Add a new type defined at runtime to the dialect.
459  void registerDynamicType(std::unique_ptr<DynamicTypeDefinition> &&type);
460 
461  /// Add a new attribute defined at runtime to the dialect.
462  void registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> &&attr);
463 
464  /// Add a new operation defined at runtime to the dialect.
465  void registerDynamicOp(std::unique_ptr<DynamicOpDefinition> &&type);
466 
467  /// Check if the dialect is an extensible dialect.
468  static bool classof(const Dialect *dialect);
469 
470  /// Returns nullptr if the definition was not found.
472  auto it = nameToDynTypes.find(name);
473  if (it == nameToDynTypes.end())
474  return nullptr;
475  return it->second;
476  }
477 
478  /// Returns nullptr if the definition was not found.
480  auto it = dynTypes.find(id);
481  if (it == dynTypes.end())
482  return nullptr;
483  return it->second.get();
484  }
485 
486  /// Returns nullptr if the definition was not found.
488  auto it = nameToDynAttrs.find(name);
489  if (it == nameToDynAttrs.end())
490  return nullptr;
491  return it->second;
492  }
493 
494  /// Returns nullptr if the definition was not found.
496  auto it = dynAttrs.find(id);
497  if (it == dynAttrs.end())
498  return nullptr;
499  return it->second.get();
500  }
501 
502 protected:
503  /// Parse the dynamic type 'typeName' in the dialect 'dialect'.
504  /// typename should not be prefixed with the dialect name.
505  /// If the dynamic type does not exist, return no value.
506  /// Otherwise, parse it, and return the parse result.
507  /// If the parsing succeed, put the resulting type in 'resultType'.
508  OptionalParseResult parseOptionalDynamicType(StringRef typeName,
509  AsmParser &parser,
510  Type &resultType) const;
511 
512  /// If 'type' is a dynamic type, print it.
513  /// Returns success if the type was printed, and failure if the type was not a
514  /// dynamic type.
515  static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer);
516 
517  /// Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
518  /// attrname should not be prefixed with the dialect name.
519  /// If the dynamic attribute does not exist, return no value.
520  /// Otherwise, parse it, and return the parse result.
521  /// If the parsing succeed, put the resulting attribute in 'resultAttr'.
522  OptionalParseResult parseOptionalDynamicAttr(StringRef attrName,
523  AsmParser &parser,
524  Attribute &resultAttr) const;
525 
526  /// If 'attr' is a dynamic attribute, print it.
527  /// Returns success if the attribute was printed, and failure if the
528  /// attribute was not a dynamic attribute.
529  static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer);
530 
531 private:
532  /// The set of all dynamic types registered.
534 
535  /// This structure allows to get in O(1) a dynamic type given its name.
536  llvm::StringMap<DynamicTypeDefinition *> nameToDynTypes;
537 
538  /// The set of all dynamic attributes registered.
540 
541  /// This structure allows to get in O(1) a dynamic attribute given its name.
542  llvm::StringMap<DynamicAttrDefinition *> nameToDynAttrs;
543 
544  /// Give DynamicOpDefinition access to allocateTypeID.
545  friend DynamicOpDefinition;
546 
547  /// Allocates a type ID to uniquify operations.
548  TypeID allocateTypeID() { return typeIDAllocator.allocate(); }
549 
550  /// Owns the TypeID generated at runtime for operations.
551  TypeIDAllocator typeIDAllocator;
552 };
553 
554 //===----------------------------------------------------------------------===//
555 // Dynamic dialect
556 //===----------------------------------------------------------------------===//
557 
558 /// A dialect that can be defined at runtime. It can be extended with new
559 /// operations, types, and attributes at runtime.
561 public:
562  DynamicDialect(StringRef name, MLIRContext *ctx);
563 
565 
566  /// Check if the dialect is an extensible dialect.
567  static bool classof(const Dialect *dialect);
568 
569  virtual Type parseType(DialectAsmParser &parser) const override;
570  virtual void printType(Type type, DialectAsmPrinter &printer) const override;
571 
572  virtual Attribute parseAttribute(DialectAsmParser &parser,
573  Type type) const override;
574  virtual void printAttribute(Attribute attr,
575  DialectAsmPrinter &printer) const override;
576 };
577 } // namespace mlir
578 
579 namespace llvm {
580 /// Provide isa functionality for ExtensibleDialect.
581 /// This is to override the isa functionality for Dialect.
582 template <>
583 struct isa_impl<mlir::ExtensibleDialect, mlir::Dialect> {
584  static inline bool doit(const ::mlir::Dialect &dialect) {
585  return mlir::ExtensibleDialect::classof(&dialect);
586  }
587 };
588 
589 /// Provide isa functionality for DynamicDialect.
590 /// This is to override the isa functionality for Dialect.
591 template <>
592 struct isa_impl<mlir::DynamicDialect, mlir::Dialect> {
593  static inline bool doit(const ::mlir::Dialect &dialect) {
594  return mlir::DynamicDialect::classof(&dialect);
595  }
596 };
597 } // namespace llvm
598 
599 #endif // MLIR_IR_EXTENSIBLEDIALECT_H
Include the generated interface declarations.
Attribute parseAttribute(llvm::StringRef attrStr, MLIRContext *context)
This parses a single MLIR attribute to an MLIR context if it was valid.
void setVerifyRegionFn(OperationName::VerifyRegionInvariantsFn &&verify)
Sets the region verifier function for this operation.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
DynamicTypeDefinition * lookupTypeDefinition(TypeID id) 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:307
ExtensibleDialect * getDialect() const
Return the dialect defining the type.
StringRef getName() const
Return the name of the attribute, in the format &#39;attrname&#39; and not &#39;dialectname.attrname&#39;.
static bool isa(Type type, DynamicTypeDefinition *typeDef)
Check if a type is a specific dynamic type.
void printType(Type type, AsmPrinter &printer)
Prints an LLVM Dialect type.
TypeID getTypeID()
Returns the op typeID.
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &) const > ParseAssemblyFn
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
A dynamic type instance.
static std::unique_ptr< DynamicAttrDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new attribute definition at runtime.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
StringRef getName() const
Return the name of the type, in the format &#39;typename&#39; and not &#39;dialectname.typename&#39;.
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< LogicalResult(function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
Attributes are known-constant values of operations.
Definition: Attributes.h:25
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
ExtensibleDialect * getDialect() const
Return the dialect defining the attribute.
The definition of a dynamic type.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
llvm::unique_function< void(const RegisteredOperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
static std::unique_ptr< DynamicTypeDefinition > get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier)
Create a new dynamic type definition.
static bool doit(const ::mlir::Dialect &dialect)
A dynamic attribute instance.
llvm::unique_function< void(AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
Type parseType(llvm::StringRef typeStr, MLIRContext *context)
This parses a single MLIR type to an MLIR context if it was valid.
This base class exposes generic asm parser hooks, usable across the various derived parsers...
static bool doit(const ::mlir::Dialect &dialect)
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
The definition of a dynamic op.
void setParseFn(OperationName::ParseAssemblyFn &&parse)
Sets the static hook for parsing this op assembly.
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:37
A dialect that can be extended with new operations/types/attributes at runtime.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
TypeID getTypeID()
Return a unique identifier for the concrete type.
Definition: Types.h:115
The definition of a dynamic attribute.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
void setVerifyFn(OperationName::VerifyInvariantsFn &&verify)
Sets the verifier function for this operation.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs, on this operation and any nested operations.
Definition: Verifier.cpp:372
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
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.
This base class exposes generic asm printer hooks, usable across the various derived printers...
DynamicAttrDefinition * lookupAttrDefinition(TypeID id) const
Returns nullptr if the definition was not found.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
This class provides a way to define new TypeIDs at runtime.
Definition: TypeID.h:292
A dialect that can be defined at runtime.
Defines a TypeID for each instance of this class by using a pointer to the instance.
Definition: TypeID.h:312
void setFoldHookFn(OperationName::FoldHookFn &&foldHook)
Sets the hook implementing a generalized folder for the op.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
Helper class for implementing traits for storage classes.
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
This class represents success/failure for parsing-like operations that find it important to chain tog...
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition: TypeID.h:324
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
Definition: Attributes.h:68
llvm::unique_function< ParseResult(AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
void setGetCanonicalizationPatternsFn(OperationName::GetCanonicalizationPatternsFn &&getCanonicalizationPatterns)
Set the hook returning any canonicalization pattern rewrites that the op supports, for use by the canonicalization pass.
static bool classof(const Dialect *dialect)
Check if the dialect is an extensible dialect.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
static bool isa(Attribute attr, DynamicAttrDefinition *attrDef)
Check if an attribute is a specific dynamic attribute.