//===- TransformDialect.h - Transform Dialect Definition --------*- C++ -*-===// // // Part of the LLVM Project, 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 // //===----------------------------------------------------------------------===// #ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMDIALECT_H #define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMDIALECT_H #include "mlir/IR/Dialect.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Support/LLVM.h" #include "mlir/Support/TypeID.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include <optional> namespace mlir { namespace transform { namespace detail { /// Concrete base class for CRTP TransformDialectDataBase. Must not be used /// directly. class TransformDialectDataBase { … }; } // namespace detail /// Base class for additional data owned by the Transform dialect. Extensions /// may communicate with each other using this data. The data object is /// identified by the TypeID of the specific data subclass, querying the data of /// the same subclass returns a reference to the same object. When a Transform /// dialect extension is initialized, it can populate the data in the specific /// subclass. When a Transform op is applied, it can read (but not mutate) the /// data in the specific subclass, including the data provided by other /// extensions. /// /// This follows CRTP: derived classes must list themselves as template /// argument. template <typename DerivedTy> class TransformDialectData : public detail::TransformDialectDataBase { … }; #ifndef NDEBUG namespace detail { /// Asserts that the operations provided as template arguments implement the /// TransformOpInterface and MemoryEffectsOpInterface. This must be a dynamic /// assertion since interface implementations may be registered at runtime. void checkImplementsTransformOpInterface(StringRef name, MLIRContext *context); /// Asserts that the type provided as template argument implements the /// TransformHandleTypeInterface. This must be a dynamic assertion since /// interface implementations may be registered at runtime. void checkImplementsTransformHandleTypeInterface(TypeID typeID, MLIRContext *context); } // namespace detail #endif // NDEBUG } // namespace transform } // namespace mlir #include "mlir/Dialect/Transform/IR/TransformDialect.h.inc" namespace mlir { namespace transform { /// Base class for extensions of the Transform dialect that supports injecting /// operations into the Transform dialect at load time. Concrete extensions are /// expected to derive this class and register operations in the constructor. /// They can be registered with the DialectRegistry and automatically applied /// to the Transform dialect when it is loaded. /// /// Derived classes are expected to define a `void init()` function in which /// they can call various protected methods of the base class to register /// extension operations and declare their dependencies. /// /// By default, the extension is configured both for construction of the /// Transform IR and for its application to some payload. If only the /// construction is desired, the extension can be switched to "build-only" mode /// that avoids loading the dialects that are only necessary for transforming /// the payload. To perform the switch, the extension must be wrapped into the /// `BuildOnly` class template (see below) when it is registered, as in: /// /// dialectRegistry.addExtension<BuildOnly<MyTransformDialectExt>>(); /// /// instead of: /// /// dialectRegistry.addExtension<MyTransformDialectExt>(); /// /// Derived classes must reexport the constructor of this class or otherwise /// forward its boolean argument to support this behavior. template <typename DerivedTy, typename... ExtraDialects> class TransformDialectExtension : public DialectExtension<DerivedTy, TransformDialect, ExtraDialects...> { … }; template <typename OpTy> void TransformDialect::addOperationIfNotRegistered() { … } template <typename Type> void TransformDialect::addTypeIfNotRegistered() { … } template <typename DataTy> DataTy &TransformDialect::getOrCreateExtraData() { … } /// A wrapper for transform dialect extensions that forces them to be /// constructed in the build-only mode. template <typename DerivedTy> class BuildOnly : public DerivedTy { … }; } // namespace transform } // namespace mlir #endif // MLIR_DIALECT_TRANSFORM_IR_TRANSFORMDIALECT_H