MLIR 22.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"
28#include "mlir/Support/TypeID.h"
29#include "llvm/ADT/StringMap.h"
30#include "llvm/Support/ErrorHandling.h"
31#include <optional>
32
33namespace mlir {
34class AsmParser;
35class AsmPrinter;
36class DynamicAttr;
37class DynamicType;
39class MLIRContext;
41
42namespace detail {
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.
56class DynamicAttrDefinition : public SelfOwningTypeID {
57public:
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
101private:
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.
144namespace AttributeTrait {
145template <typename ConcreteType>
146class 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/// `isa<DynamicAttr>(myAttr)`, 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
157class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute,
158 detail::DynamicAttrStorage,
159 AttributeTrait::IsDynamicAttr> {
160public:
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.
212class DynamicTypeDefinition : public SelfOwningTypeID {
213public:
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
257private:
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.
300namespace TypeTrait {
301template <typename ConcreteType>
302class 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/// `isa<DynamicType>(myType)`, 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> {
315public:
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.
367class DynamicOpDefinition : public OperationName::Impl {
368public:
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,
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.
433
434 /// Set the hook populating default attributes.
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 }
476 LogicalResult
479 return success();
480 }
481 int getOpPropertyByteSize() final { return 0; }
483 OpaqueProperties init) 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 {}; }
498 llvm::hash_code hashProperties(OpaqueProperties prop) final { return {}; }
499
500private:
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.
532public:
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
573protected:
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
602private:
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.
632public:
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
644 Type type) const override;
645 virtual void printAttribute(Attribute attr,
646 DialectAsmPrinter &printer) const override;
647};
648} // namespace mlir
649
650namespace llvm {
651/// Provide isa functionality for ExtensibleDialect.
652/// This is to override the isa functionality for Dialect.
653template <>
654struct 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.
662template <>
663struct 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
return success()
lhs
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
detail::StorageUserBase< ConcreteType, BaseType, StorageType, detail::AttributeUniquer, Traits... > AttrBase
Utility class for implementing attributes.
Definition Attributes.h:30
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
Definition Attributes.h:52
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
friend class MLIRContext
Definition Dialect.h:371
Dialect(StringRef name, MLIRContext *context, TypeID id)
The constructor takes a unique namespace for this dialect as well as the context to bind to.
Definition Dialect.cpp:35
The definition of a dynamic attribute.
llvm::unique_function< void( AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
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.
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'.
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
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic attributes are uniqued.
ExtensibleDialect * getDialect() const
Return the dialect defining the attribute.
llvm::unique_function< LogicalResult( function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
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.
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.
std::optional< Attribute > getInherentAttr(Operation *op, StringRef name) final
Implementation for properties (unsupported right now here).
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
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
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
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.
llvm::unique_function< void( AsmPrinter &printer, ArrayRef< Attribute > params) const > PrinterFn
void setPrintFn(PrinterFn &&print)
Sets the static hook for printing this type assembly.
MLIRContext & getContext() const
Return the MLIRContext in which the dynamic types is uniqued.
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.
llvm::unique_function< ParseResult( AsmParser &parser, llvm::SmallVectorImpl< Attribute > &parsedAttributes) const > ParserFn
llvm::unique_function< LogicalResult( function_ref< InFlightDiagnostic()>, ArrayRef< Attribute >) const > VerifierFn
ExtensibleDialect * getDialect() const
Return the dialect defining the type.
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.
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.
void registerDynamicOp(std::unique_ptr< DynamicOpDefinition > &&type)
Add a new operation defined at runtime to the dialect.
DynamicTypeDefinition * lookupTypeDefinition(TypeID id) const
Returns nullptr if the definition was not found.
DynamicTypeDefinition * lookupTypeDefinition(StringRef name) const
Returns nullptr if the definition was not found.
static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer)
If 'type' is a dynamic type, print it.
DynamicAttrDefinition * lookupAttrDefinition(StringRef name) const
Returns nullptr if the definition was not found.
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'.
ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID)
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'.
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
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< void(const OperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &)> ParseAssemblyFn
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
llvm::unique_function< LogicalResult( Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
This class implements Optional functionality for ParseResult.
TypeID getTypeID() const
Return the TypeID owned by this object.
Definition TypeID.h:381
TypeID allocate()
Allocate a new TypeID, that is ensured to be unique for the lifetime of the TypeIDAllocator.
Definition TypeID.h:353
This class provides an efficient unique identifier for a specific C++ type.
Definition TypeID.h:107
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
detail::StorageUserBase< ConcreteType, BaseType, StorageType, detail::TypeUniquer, Traits... > TypeBase
Utility class for implementing types.
Definition Types.h:79
TypeID getTypeID()
Return a unique identifier for the concrete type.
Definition Types.h:101
StorageUserBase< ConcreteType, BaseType, StorageType, detail::TypeUniquer, Traits... > Base
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
detail::StorageUserTraitBase< ConcreteType, TraitType > TraitBase
This class represents the base of an attribute trait.
Definition Attributes.h:242
This trait is used to determine if a type is a dynamic type or not; it should only be implemented by ...
detail::StorageUserTraitBase< ConcreteType, TraitType > TraitBase
This class represents the base of a type trait.
Definition Types.h:249
AttrTypeReplacer.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
Definition LLVM.h:126
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition Verifier.cpp:423
llvm::function_ref< Fn > function_ref
Definition LLVM.h:152
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.