//===- DialectConversion.h - MLIR dialect conversion pass -------*- 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 // //===----------------------------------------------------------------------===// // // This file declares a generic pass for converting between MLIR dialects. // //===----------------------------------------------------------------------===// #ifndef MLIR_TRANSFORMS_DIALECTCONVERSION_H_ #define MLIR_TRANSFORMS_DIALECTCONVERSION_H_ #include "mlir/Config/mlir-config.h" #include "mlir/Rewrite/FrozenRewritePatternSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringMap.h" #include <type_traits> namespace mlir { // Forward declarations. class Attribute; class Block; struct ConversionConfig; class ConversionPatternRewriter; class MLIRContext; class Operation; struct OperationConverter; class Type; class Value; //===----------------------------------------------------------------------===// // Type Conversion //===----------------------------------------------------------------------===// /// Type conversion class. Specific conversions and materializations can be /// registered using addConversion and addMaterialization, respectively. class TypeConverter { … }; //===----------------------------------------------------------------------===// // Conversion Patterns //===----------------------------------------------------------------------===// /// Base class for the conversion patterns. This pattern class enables type /// conversions, and other uses specific to the conversion framework. As such, /// patterns of this type can only be used with the 'apply*' methods below. class ConversionPattern : public RewritePattern { … }; /// OpConversionPattern is a wrapper around ConversionPattern that allows for /// matching and rewriting against an instance of a derived operation class as /// opposed to a raw Operation. template <typename SourceOp> class OpConversionPattern : public ConversionPattern { … }; /// OpInterfaceConversionPattern is a wrapper around ConversionPattern that /// allows for matching and rewriting against an instance of an OpInterface /// class as opposed to a raw Operation. template <typename SourceOp> class OpInterfaceConversionPattern : public ConversionPattern { … }; /// OpTraitConversionPattern is a wrapper around ConversionPattern that allows /// for matching and rewriting against instances of an operation that possess a /// given trait. template <template <typename> class TraitType> class OpTraitConversionPattern : public ConversionPattern { … }; /// Generic utility to convert op result types according to type converter /// without knowing exact op type. /// Clones existing op with new result types and returns it. FailureOr<Operation *> convertOpResultTypes(Operation *op, ValueRange operands, const TypeConverter &converter, ConversionPatternRewriter &rewriter); /// Add a pattern to the given pattern list to convert the signature of a /// FunctionOpInterface op with the given type converter. This only supports /// ops which use FunctionType to represent their type. void populateFunctionOpInterfaceTypeConversionPattern( StringRef functionLikeOpName, RewritePatternSet &patterns, const TypeConverter &converter); template <typename FuncOpT> void populateFunctionOpInterfaceTypeConversionPattern( RewritePatternSet &patterns, const TypeConverter &converter) { … } void populateAnyFunctionOpInterfaceTypeConversionPattern( RewritePatternSet &patterns, const TypeConverter &converter); //===----------------------------------------------------------------------===// // Conversion PatternRewriter //===----------------------------------------------------------------------===// namespace detail { struct ConversionPatternRewriterImpl; } // namespace detail /// This class implements a pattern rewriter for use with ConversionPatterns. It /// extends the base PatternRewriter and provides special conversion specific /// hooks. class ConversionPatternRewriter final : public PatternRewriter { … }; //===----------------------------------------------------------------------===// // ConversionTarget //===----------------------------------------------------------------------===// /// This class describes a specific conversion target. class ConversionTarget { … }; #if MLIR_ENABLE_PDL_IN_PATTERNMATCH //===----------------------------------------------------------------------===// // PDL Configuration //===----------------------------------------------------------------------===// /// A PDL configuration that is used to supported dialect conversion /// functionality. class PDLConversionConfig final : public PDLPatternConfigBase<PDLConversionConfig> { … }; /// Register the dialect conversion PDL functions with the given pattern set. void registerConversionPDLFunctions(RewritePatternSet &patterns); #else // Stubs for when PDL in rewriting is not enabled. inline void registerConversionPDLFunctions(RewritePatternSet &patterns) {} class PDLConversionConfig final { public: PDLConversionConfig(const TypeConverter * /*converter*/) {} }; #endif // MLIR_ENABLE_PDL_IN_PATTERNMATCH //===----------------------------------------------------------------------===// // ConversionConfig //===----------------------------------------------------------------------===// /// Dialect conversion configuration. struct ConversionConfig { … }; //===----------------------------------------------------------------------===// // Reconcile Unrealized Casts //===----------------------------------------------------------------------===// /// Try to reconcile all given UnrealizedConversionCastOps and store the /// left-over ops in `remainingCastOps` (if provided). /// /// This function processes cast ops in a worklist-driven fashion. For each /// cast op, if the chain of input casts eventually reaches a cast op where the /// input types match the output types of the matched op, replace the matched /// op with the inputs. /// /// Example: /// %1 = unrealized_conversion_cast %0 : !A to !B /// %2 = unrealized_conversion_cast %1 : !B to !C /// %3 = unrealized_conversion_cast %2 : !C to !A /// /// In the above example, %0 can be used instead of %3 and all cast ops are /// folded away. void reconcileUnrealizedCasts( ArrayRef<UnrealizedConversionCastOp> castOps, SmallVectorImpl<UnrealizedConversionCastOp> *remainingCastOps = nullptr); //===----------------------------------------------------------------------===// // Op Conversion Entry Points //===----------------------------------------------------------------------===// /// Below we define several entry points for operation conversion. It is /// important to note that the patterns provided to the conversion framework may /// have additional constraints. See the `PatternRewriter Hooks` section of the /// ConversionPatternRewriter, to see what additional constraints are imposed on /// the use of the PatternRewriter. /// Apply a partial conversion on the given operations and all nested /// operations. This method converts as many operations to the target as /// possible, ignoring operations that failed to legalize. This method only /// returns failure if there ops explicitly marked as illegal. LogicalResult applyPartialConversion(ArrayRef<Operation *> ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); LogicalResult applyPartialConversion(Operation *op, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); /// Apply a complete conversion on the given operations, and all nested /// operations. This method returns failure if the conversion of any operation /// fails, or if there are unreachable blocks in any of the regions nested /// within 'ops'. LogicalResult applyFullConversion(ArrayRef<Operation *> ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); LogicalResult applyFullConversion(Operation *op, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); /// Apply an analysis conversion on the given operations, and all nested /// operations. This method analyzes which operations would be successfully /// converted to the target if a conversion was applied. All operations that /// were found to be legalizable to the given 'target' are placed within the /// provided 'config.legalizableOps' set; note that no actual rewrites are /// applied to the operations on success. This method only returns failure if /// there are unreachable blocks in any of the regions nested within 'ops'. LogicalResult applyAnalysisConversion(ArrayRef<Operation *> ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); LogicalResult applyAnalysisConversion(Operation *op, ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config = ConversionConfig()); } // namespace mlir #endif // MLIR_TRANSFORMS_DIALECTCONVERSION_H_