//===- ExtensibleDialect.h - Extensible dialect -----------------*- C++ -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the DynamicOpDefinition class, the DynamicTypeDefinition // class, and the DynamicAttrDefinition class, which represent respectively // operations, types, and attributes that can be defined at runtime. They can // be registered at runtime to an extensible dialect, using the // ExtensibleDialect class defined in this file. // // For a more complete documentation, see // https://mlir.llvm.org/docs/ExtensibleDialects/ . // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_EXTENSIBLEDIALECT_H #define MLIR_IR_EXTENSIBLEDIALECT_H #include "mlir/IR/Dialect.h" #include "mlir/IR/DialectInterface.h" #include "mlir/IR/MLIRContext.h" #include "mlir/IR/OpDefinition.h" #include "mlir/IR/OperationSupport.h" #include "mlir/Support/TypeID.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/ErrorHandling.h" #include <optional> namespace mlir { class AsmParser; class AsmPrinter; class DynamicAttr; class DynamicType; class ExtensibleDialect; class MLIRContext; class OptionalParseResult; namespace detail { struct DynamicAttrStorage; struct DynamicTypeStorage; } // namespace detail //===----------------------------------------------------------------------===// // Dynamic attribute //===----------------------------------------------------------------------===// /// The definition of a dynamic attribute. A dynamic attribute is an attribute /// that is defined at runtime, and that can be registered at runtime by an /// extensible dialect (a dialect inheriting ExtensibleDialect). This class /// stores the parser, the printer, and the verifier of the attribute. Each /// dynamic attribute definition refers to one instance of this class. class DynamicAttrDefinition : public SelfOwningTypeID { … }; /// This trait is used to determine if an attribute is a dynamic attribute or /// not; it should only be implemented by dynamic attributes. /// Note: This is only required because dynamic attributes do not have a /// static/single TypeID. namespace AttributeTrait { template <typename ConcreteType> class IsDynamicAttr : public TraitBase<ConcreteType, IsDynamicAttr> { … }; } // namespace AttributeTrait /// A dynamic attribute instance. This is an attribute whose definition is /// defined at runtime. /// It is possible to check if an attribute is a dynamic attribute using /// `my_attr.isa<DynamicAttr>()`, and getting the attribute definition of a /// dynamic attribute using the `DynamicAttr::getAttrDef` method. /// All dynamic attributes have the same storage, which is an array of /// attributes. class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute, detail::DynamicAttrStorage, AttributeTrait::IsDynamicAttr> { … }; //===----------------------------------------------------------------------===// // Dynamic type //===----------------------------------------------------------------------===// /// The definition of a dynamic type. A dynamic type is a type that is /// defined at runtime, and that can be registered at runtime by an /// extensible dialect (a dialect inheriting ExtensibleDialect). This class /// stores the parser, the printer, and the verifier of the type. Each dynamic /// type definition refers to one instance of this class. class DynamicTypeDefinition : public SelfOwningTypeID { … }; /// This trait is used to determine if a type is a dynamic type or not; /// it should only be implemented by dynamic types. /// Note: This is only required because dynamic type do not have a /// static/single TypeID. namespace TypeTrait { template <typename ConcreteType> class IsDynamicType : public TypeTrait::TraitBase<ConcreteType, IsDynamicType> { … }; } // namespace TypeTrait /// A dynamic type instance. This is a type whose definition is defined at /// runtime. /// It is possible to check if a type is a dynamic type using /// `my_type.isa<DynamicType>()`, and getting the type definition of a dynamic /// type using the `DynamicType::getTypeDef` method. /// All dynamic types have the same storage, which is an array of attributes. class DynamicType : public Type::TypeBase<DynamicType, Type, detail::DynamicTypeStorage, TypeTrait::IsDynamicType> { … }; //===----------------------------------------------------------------------===// // Dynamic operation //===----------------------------------------------------------------------===// /// The definition of a dynamic op. A dynamic op is an op that is defined at /// runtime, and that can be registered at runtime by an extensible dialect (a /// dialect inheriting ExtensibleDialect). This class implements the method /// exposed by the OperationName class, and in addition defines the TypeID of /// the op that will be defined. Each dynamic operation definition refers to one /// instance of this class. class DynamicOpDefinition : public OperationName::Impl { … }; //===----------------------------------------------------------------------===// // Extensible dialect //===----------------------------------------------------------------------===// /// A dialect that can be extended with new operations/types/attributes at /// runtime. class ExtensibleDialect : public mlir::Dialect { … }; //===----------------------------------------------------------------------===// // Dynamic dialect //===----------------------------------------------------------------------===// /// A dialect that can be defined at runtime. It can be extended with new /// operations, types, and attributes at runtime. class DynamicDialect : public SelfOwningTypeID, public ExtensibleDialect { … }; } // namespace mlir namespace llvm { /// Provide isa functionality for ExtensibleDialect. /// This is to override the isa functionality for Dialect. template <> struct isa_impl<mlir::ExtensibleDialect, mlir::Dialect> { … }; /// Provide isa functionality for DynamicDialect. /// This is to override the isa functionality for Dialect. template <> struct isa_impl<mlir::DynamicDialect, mlir::Dialect> { … }; } // namespace llvm #endif // MLIR_IR_EXTENSIBLEDIALECT_H