MLIR 23.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/// Base class of traits for dynamic-defined operations.
359public:
360 virtual LogicalResult verifyTrait(Operation *op) const { return success(); };
361 virtual LogicalResult verifyRegionTrait(Operation *op) const {
362 return success();
363 };
364
365 /// Returns the TypeID of the trait.
366 /// It must be equal to the TypeID of corresponding static trait
367 /// which will be used in `hasTrait(TypeID)`.
368 virtual TypeID getTypeID() const = 0;
369 virtual ~DynamicOpTrait() = default;
370};
371
372/// This class holds a list of traits for dynamic-defined operations.
374public:
375 bool insert(std::unique_ptr<DynamicOpTrait> trait) {
376 return traits.try_emplace(trait->getTypeID(), std::move(trait)).second;
377 }
378
379 bool contains(TypeID id) const { return traits.contains(id); }
380
381 LogicalResult verifyTraits(Operation *op) const {
382 for (const auto &[_, trait] : traits) {
383 if (failed(trait->verifyTrait(op)))
384 return failure();
385 }
386 return success();
387 }
388
389 LogicalResult verifyRegionTraits(Operation *op) const {
390 for (const auto &[_, trait] : traits) {
391 if (failed(trait->verifyRegionTrait(op)))
392 return failure();
393 }
394 return success();
395 }
396
397private:
399};
400
401template <template <typename T> class Trait>
403public:
404 TypeID getTypeID() const override { return TypeID::get<Trait>(); }
405};
406
408
409class IsTerminator : public DynamicOpTraitImpl<OpTrait::IsTerminator> {
410public:
411 LogicalResult verifyTrait(Operation *op) const override {
413 }
414};
415
416class NoTerminator : public DynamicOpTraitImpl<OpTrait::NoTerminator> {};
417
418} // namespace DynamicOpTraits
419
420//===----------------------------------------------------------------------===//
421// Dynamic operation
422//===----------------------------------------------------------------------===//
423
424/// The definition of a dynamic op. A dynamic op is an op that is defined at
425/// runtime, and that can be registered at runtime by an extensible dialect (a
426/// dialect inheriting ExtensibleDialect). This class implements the method
427/// exposed by the OperationName class, and in addition defines the TypeID of
428/// the op that will be defined. Each dynamic operation definition refers to one
429/// instance of this class.
430class DynamicOpDefinition : public OperationName::Impl {
431public:
433 llvm::unique_function<void(RewritePatternSet &, MLIRContext *) const>;
434
435 /// Create a new op at runtime. The op is registered only after passing it to
436 /// the dialect using registerDynamicOp.
437 static std::unique_ptr<DynamicOpDefinition>
438 get(StringRef name, ExtensibleDialect *dialect,
441 static std::unique_ptr<DynamicOpDefinition>
442 get(StringRef name, ExtensibleDialect *dialect,
447 static std::unique_ptr<DynamicOpDefinition>
448 get(StringRef name, ExtensibleDialect *dialect,
453 OperationName::FoldHookFn &&foldHookFn,
454 GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
455 OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
456
457 /// Returns the op typeID.
458 TypeID getTypeID() { return typeID; }
459
460 /// Sets the verifier function for this operation. It should emits an error
461 /// message and returns failure if a problem is detected, or returns success
462 /// if everything is ok.
464 verifyFn = std::move(verify);
465 }
466
467 /// Sets the region verifier function for this operation. It should emits an
468 /// error message and returns failure if a problem is detected, or returns
469 /// success if everything is ok.
471 verifyRegionFn = std::move(verify);
472 }
473
474 /// Sets the static hook for parsing this op assembly.
476 parseFn = std::move(parse);
477 }
478
479 /// Sets the static hook for printing this op assembly.
481 printFn = std::move(print);
482 }
483
484 /// Sets the hook implementing a generalized folder for the op. See
485 /// `RegisteredOperationName::foldHook` for more details
487 foldHookFn = std::move(foldHook);
488 }
489
490 /// Set the hook returning any canonicalization pattern rewrites that the op
491 /// supports, for use by the canonicalization pass.
496
497 /// Set the hook populating default attributes.
502
503 /// Attach a trait to this dynamic-defined op.
504 bool addTrait(std::unique_ptr<DynamicOpTrait> trait) {
505 return traits.insert(std::move(trait));
506 }
507
508 LogicalResult foldHook(Operation *op, ArrayRef<Attribute> attrs,
509 SmallVectorImpl<OpFoldResult> &results) final {
510 return foldHookFn(op, attrs, results);
511 }
513 MLIRContext *context) final {
514 getCanonicalizationPatternsFn(set, context);
515 }
516 bool hasTrait(TypeID id) final { return traits.contains(id); }
518 return [&](OpAsmParser &parser, OperationState &state) {
519 return parseFn(parser, state);
520 };
521 }
523 NamedAttrList &attrs) final {
524 populateDefaultAttrsFn(name, attrs);
525 }
527 StringRef name) final {
528 printFn(op, printer, name);
529 }
530 LogicalResult verifyInvariants(Operation *op) final {
531 return failure(failed(traits.verifyTraits(op)) || failed(verifyFn(op)));
532 }
533 LogicalResult verifyRegionInvariants(Operation *op) final {
534 return failure(failed(traits.verifyRegionTraits(op)) ||
535 failed(verifyRegionFn(op)));
536 }
537
538 /// Implementation for properties (unsupported right now here).
539 std::optional<Attribute> getInherentAttr(Operation *op,
540 StringRef name) final {
541 llvm::report_fatal_error("Unsupported getInherentAttr on Dynamic dialects");
542 }
543 void setInherentAttr(Operation *op, StringAttr name, Attribute value) final {
544 llvm::report_fatal_error("Unsupported setInherentAttr on Dynamic dialects");
545 }
547 LogicalResult
550 return success();
551 }
552 int getOpPropertyByteSize() final { return 0; }
554 OpaqueProperties init) final {}
557 OpaqueProperties properties) final {}
558
559 LogicalResult
561 Attribute attr,
563 emitError() << "extensible Dialects don't support properties";
564 return failure();
565 }
566 Attribute getPropertiesAsAttr(Operation *op) final { return {}; }
569 return false;
570 }
571 llvm::hash_code hashProperties(OpaqueProperties prop) final { return {}; }
572
573private:
575 StringRef name, ExtensibleDialect *dialect,
580 OperationName::FoldHookFn &&foldHookFn,
581 GetCanonicalizationPatternsFn &&getCanonicalizationPatternsFn,
582 OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn);
583
584 /// Dialect defining this operation.
585 ExtensibleDialect *getdialect();
586
591 OperationName::FoldHookFn foldHookFn;
592 GetCanonicalizationPatternsFn getCanonicalizationPatternsFn;
593 OperationName::PopulateDefaultAttrsFn populateDefaultAttrsFn;
594 DynamicOpTraitList traits;
595
596 friend ExtensibleDialect;
597};
598
599//===----------------------------------------------------------------------===//
600// Extensible dialect
601//===----------------------------------------------------------------------===//
602
603/// A dialect that can be extended with new operations/types/attributes at
604/// runtime.
606public:
607 ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID);
608
609 /// Add a new type defined at runtime to the dialect.
610 void registerDynamicType(std::unique_ptr<DynamicTypeDefinition> &&type);
611
612 /// Add a new attribute defined at runtime to the dialect.
613 void registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> &&attr);
614
615 /// Add a new operation defined at runtime to the dialect.
616 void registerDynamicOp(std::unique_ptr<DynamicOpDefinition> &&type);
617
618 /// Check if the dialect is an extensible dialect.
619 static bool classof(const Dialect *dialect);
620
621 /// Returns nullptr if the definition was not found.
623 return nameToDynTypes.lookup(name);
624 }
625
626 /// Returns nullptr if the definition was not found.
628 auto it = dynTypes.find(id);
629 if (it == dynTypes.end())
630 return nullptr;
631 return it->second.get();
632 }
633
634 /// Returns nullptr if the definition was not found.
636 return nameToDynAttrs.lookup(name);
637 }
638
639 /// Returns nullptr if the definition was not found.
641 auto it = dynAttrs.find(id);
642 if (it == dynAttrs.end())
643 return nullptr;
644 return it->second.get();
645 }
646
647protected:
648 /// Parse the dynamic type 'typeName' in the dialect 'dialect'.
649 /// typename should not be prefixed with the dialect name.
650 /// If the dynamic type does not exist, return no value.
651 /// Otherwise, parse it, and return the parse result.
652 /// If the parsing succeed, put the resulting type in 'resultType'.
654 AsmParser &parser,
655 Type &resultType) const;
656
657 /// If 'type' is a dynamic type, print it.
658 /// Returns success if the type was printed, and failure if the type was not a
659 /// dynamic type.
660 static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer);
661
662 /// Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
663 /// attrname should not be prefixed with the dialect name.
664 /// If the dynamic attribute does not exist, return no value.
665 /// Otherwise, parse it, and return the parse result.
666 /// If the parsing succeed, put the resulting attribute in 'resultAttr'.
668 AsmParser &parser,
669 Attribute &resultAttr) const;
670
671 /// If 'attr' is a dynamic attribute, print it.
672 /// Returns success if the attribute was printed, and failure if the
673 /// attribute was not a dynamic attribute.
674 static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer);
675
676private:
677 /// The set of all dynamic types registered.
679
680 /// This structure allows to get in O(1) a dynamic type given its name.
681 llvm::StringMap<DynamicTypeDefinition *> nameToDynTypes;
682
683 /// The set of all dynamic attributes registered.
685
686 /// This structure allows to get in O(1) a dynamic attribute given its name.
687 llvm::StringMap<DynamicAttrDefinition *> nameToDynAttrs;
688
689 /// Give DynamicOpDefinition access to allocateTypeID.
690 friend DynamicOpDefinition;
691
692 /// Allocates a type ID to uniquify operations.
693 TypeID allocateTypeID() { return typeIDAllocator.allocate(); }
694
695 /// Owns the TypeID generated at runtime for operations.
696 TypeIDAllocator typeIDAllocator;
697};
698
699//===----------------------------------------------------------------------===//
700// Dynamic dialect
701//===----------------------------------------------------------------------===//
702
703/// A dialect that can be defined at runtime. It can be extended with new
704/// operations, types, and attributes at runtime.
706public:
707 DynamicDialect(StringRef name, MLIRContext *ctx);
708
710
711 /// Check if the dialect is an extensible dialect.
712 static bool classof(const Dialect *dialect);
713
714 virtual Type parseType(DialectAsmParser &parser) const override;
715 virtual void printType(Type type, DialectAsmPrinter &printer) const override;
716
718 Type type) const override;
719 virtual void printAttribute(Attribute attr,
720 DialectAsmPrinter &printer) const override;
721};
722} // namespace mlir
723
724namespace llvm {
725/// Provide isa functionality for ExtensibleDialect.
726/// This is to override the isa functionality for Dialect.
727template <>
728struct isa_impl<mlir::ExtensibleDialect, mlir::Dialect> {
729 static inline bool doit(const ::mlir::Dialect &dialect) {
730 return mlir::ExtensibleDialect::classof(&dialect);
731 }
732};
733
734/// Provide isa functionality for DynamicDialect.
735/// This is to override the isa functionality for Dialect.
736template <>
737struct isa_impl<mlir::DynamicDialect, mlir::Dialect> {
738 static inline bool doit(const ::mlir::Dialect &dialect) {
739 return mlir::DynamicDialect::classof(&dialect);
740 }
741};
742} // namespace llvm
743
744#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
bool addTrait(std::unique_ptr< DynamicOpTrait > trait)
Attach a trait to this dynamic-defined op.
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
TypeID getTypeID() const override
Returns the TypeID of the trait.
This class holds a list of traits for dynamic-defined operations.
bool contains(TypeID id) const
LogicalResult verifyRegionTraits(Operation *op) const
LogicalResult verifyTraits(Operation *op) const
bool insert(std::unique_ptr< DynamicOpTrait > trait)
Base class of traits for dynamic-defined operations.
virtual LogicalResult verifyRegionTrait(Operation *op) const
virtual TypeID getTypeID() const =0
Returns the TypeID of the trait.
virtual LogicalResult verifyTrait(Operation *op) const
virtual ~DynamicOpTrait()=default
LogicalResult verifyTrait(Operation *op) const override
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
static TypeID get()
Construct a type info object for the given type T.
Definition TypeID.h:245
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
LogicalResult verifyIsTerminator(Operation *op)
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:118
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:144
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.