[Mlir-commits] [mlir] [mlir][EmitC] Add pass that combines all available emitc conversions (PR #117549)
Paul Kirth
llvmlistbot at llvm.org
Thu Feb 13 14:05:59 PST 2025
================
@@ -0,0 +1,226 @@
+//===- ConvertToEmitCPass.cpp - Conversion to EmitC 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h"
+
+#include "llvm/Support/Debug.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
+#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
+#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
+#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+#include <memory>
+
+#define DEBUG_TYPE "convert-to-emitc"
+
+namespace mlir {
+#define GEN_PASS_DEF_CONVERTTOEMITC
+#include "mlir/Conversion/Passes.h.inc"
+} // namespace mlir
+
+using namespace mlir;
+
+namespace {
+/// Base class for creating the internal implementation of `convert-to-emitc`
+/// passes.
+class ConvertToEmitCPassInterface {
+public:
+ ConvertToEmitCPassInterface(MLIRContext *context,
+ ArrayRef<std::string> filterDialects);
+ virtual ~ConvertToEmitCPassInterface() = default;
+
+ /// Get the dependent dialects used by `convert-to-emitc`.
+ static void getDependentDialects(DialectRegistry ®istry);
+
+ /// Initialize the internal state of the `convert-to-emitc` pass
+ /// implementation. This method is invoked by `ConvertToEmitC::initialize`.
+ /// This method returns whether the initialization process failed.
+ virtual LogicalResult initialize() = 0;
+
+ /// Transform `op` to the EMitC dialect with the conversions available in the pass.
+ /// The analysis manager can be used to query analyzes like `DataLayoutAnalysis`
+ /// to further configure the conversion process. This method is invoked by
+ /// `ConvertToEmitC::runOnOperation`. This method returns whether the
+ /// transformation process failed.
+ virtual LogicalResult transform(Operation *op,
+ AnalysisManager manager) const = 0;
+
+protected:
+ /// Visit the `ConvertToEmitCPatternInterface` dialect interfaces and call
+ /// `visitor` with each of the interfaces. If `filterDialects` is non-empty,
+ /// then `visitor` is invoked only with the dialects in the `filterDialects`
+ /// list.
+ LogicalResult visitInterfaces(
+ llvm::function_ref<void(ConvertToEmitCPatternInterface *)> visitor);
+ MLIRContext *context;
+ /// List of dialects names to use as filters.
+ ArrayRef<std::string> filterDialects;
+};
+
+/// This DialectExtension can be attached to the context, which will invoke the
+/// `apply()` method for every loaded dialect. If a dialect implements the
+/// `ConvertToEmitCPatternInterface` interface, we load dependent dialects
+/// through the interface. This extension is loaded in the context before
+/// starting a pass pipeline that involves dialect conversion to tje EmitC dialect.
+class LoadDependentDialectExtension : public DialectExtensionBase {
+public:
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LoadDependentDialectExtension)
+
+ LoadDependentDialectExtension() : DialectExtensionBase(/*dialectNames=*/{}) {}
+
+ void apply(MLIRContext *context,
+ MutableArrayRef<Dialect *> dialects) const final {
+ LLVM_DEBUG(llvm::dbgs() << "Convert to EmitC extension load\n");
+ for (Dialect *dialect : dialects) {
+ auto *iface = dyn_cast<ConvertToEmitCPatternInterface>(dialect);
+ if (!iface)
+ continue;
+ LLVM_DEBUG(llvm::dbgs() << "Convert to EmitC found dialect interface for "
+ << dialect->getNamespace() << "\n");
+ iface->loadDependentDialects(context);
+ }
+ }
+
+ /// Return a copy of this extension.
+ std::unique_ptr<DialectExtensionBase> clone() const final {
+ return std::make_unique<LoadDependentDialectExtension>(*this);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// StaticConvertToEmitC
+//===----------------------------------------------------------------------===//
+
+/// Static implementation of the `convert-to-emitc` pass. This version only looks
+/// at dialect interfaces to configure the conversion process.
+struct StaticConvertToEmitC : public ConvertToEmitCPassInterface {
+ /// Pattern set with conversions to the EmitC dialect.
+ std::shared_ptr<const FrozenRewritePatternSet> patterns;
+ /// The conversion target.
+ std::shared_ptr<const ConversionTarget> target;
+ /// The type converter.
+ std::shared_ptr<const TypeConverter> typeConverter;
+ using ConvertToEmitCPassInterface::ConvertToEmitCPassInterface;
+
+ /// Configure the conversion to EmitC at pass initialization.
+ LogicalResult initialize() final {
+ auto target = std::make_shared<ConversionTarget>(*context);
+ auto typeConverter = std::make_shared<TypeConverter>();
+
+ // Add fallback identity converison
+ typeConverter->addConversion([](Type type) -> std::optional<Type> {
+ if (emitc::isSupportedEmitCType(type))
+ return type;
+ return std::nullopt;
+ });
+
+ RewritePatternSet tempPatterns(context);
+ target->addLegalDialect<emitc::EmitCDialect>();
+ // Populate the patterns with the dialect interface.
+ if (failed(visitInterfaces([&](ConvertToEmitCPatternInterface *iface) {
+ iface->populateConvertToEmitCConversionPatterns(
+ *target, *typeConverter, tempPatterns);
+ })))
+ return failure();
+ this->patterns =
+ std::make_unique<FrozenRewritePatternSet>(std::move(tempPatterns));
+ this->target = target;
+ this->typeConverter = typeConverter;
+ return success();
+ }
+
+ /// Apply the conversion driver.
+ LogicalResult transform(Operation *op, AnalysisManager manager) const final {
+ if (failed(applyPartialConversion(op, *target, *patterns)))
+ return failure();
+ return success();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ConvertToEmitC
+//===----------------------------------------------------------------------===//
+
+/// This is a generic pass to convert to the EmitC dialect, it uses the
+/// `ConvertToE;otCPatternInterface` dialect interface to delegate to dialects
+/// the injection of conversion patterns.
----------------
ilovepi wrote:
```suggestion
/// `ConvertToEmitCPatternInterface` dialect interface to delegate the injection of
/// of conversion patterns to dialects.
```
This reads a bit more naturally to me.
https://github.com/llvm/llvm-project/pull/117549
More information about the Mlir-commits
mailing list