[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:58 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 &registry);
+
+  /// 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
----------------
ilovepi wrote:

Typo?
```suggestion
/// `ConvertToEmitCPatternInterface` dialect interface to delegate to dialects
```

https://github.com/llvm/llvm-project/pull/117549


More information about the Mlir-commits mailing list