[Mlir-commits] [mlir] [mlir][EmitC] Add pass that combines all available emitc conversions (PR #117549)
Simon Camphausen
llvmlistbot at llvm.org
Fri Mar 28 08:55:53 PDT 2025
https://github.com/simon-camp updated https://github.com/llvm/llvm-project/pull/117549
>From 75382a90724c07ed3d5be9e1494ff2b35d8fb426 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simon.camphausen at iml.fraunhofer.de>
Date: Fri, 22 Nov 2024 13:59:49 +0000
Subject: [PATCH 01/11] [mlir][EmitC] Add pass that combines all available
emitc conversions
---
.../ConvertToEmitC/ConvertToEmitCPass.h | 22 ++++++
mlir/include/mlir/Conversion/Passes.h | 1 +
mlir/include/mlir/Conversion/Passes.td | 14 ++++
mlir/lib/Conversion/CMakeLists.txt | 1 +
.../Conversion/ConvertToEmitC/CMakeLists.txt | 25 ++++++
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 77 +++++++++++++++++++
.../ConvertToEmitC/func-signature.mlir | 19 +++++
mlir/test/Conversion/ConvertToEmitC/tosa.mlir | 46 +++++++++++
8 files changed, 205 insertions(+)
create mode 100644 mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
create mode 100644 mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
create mode 100644 mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
create mode 100644 mlir/test/Conversion/ConvertToEmitC/func-signature.mlir
create mode 100644 mlir/test/Conversion/ConvertToEmitC/tosa.mlir
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
new file mode 100644
index 0000000000000..e6244276e6e68
--- /dev/null
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
@@ -0,0 +1,22 @@
+//===- ConvertToEmitCPass.h - 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITCPASS_H
+#define MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITCPASS_H
+
+#include <memory>
+
+namespace mlir {
+class Pass;
+
+#define GEN_PASS_DECL_CONVERTTOEMITCPASS
+#include "mlir/Conversion/Passes.h.inc"
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITCPASS_H
diff --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h
index ccd862f67c068..c9d2a54433736 100644
--- a/mlir/include/mlir/Conversion/Passes.h
+++ b/mlir/include/mlir/Conversion/Passes.h
@@ -29,6 +29,7 @@
#include "mlir/Conversion/ControlFlowToSCF/ControlFlowToSCF.h"
#include "mlir/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.h"
#include "mlir/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRVPass.h"
+#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMPass.h"
#include "mlir/Conversion/FuncToEmitC/FuncToEmitCPass.h"
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h"
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index bbba495e613b2..95eed946fe0fd 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -12,6 +12,20 @@
include "mlir/Pass/PassBase.td"
include "mlir/Dialect/Vector/Transforms/VectorTransformsBase.td"
+//===----------------------------------------------------------------------===//
+// ToEmitC
+//===----------------------------------------------------------------------===//
+
+def ConvertToEmitCPass : Pass<"convert-to-emitc"> {
+ let summary = "Convert to EmitC dialect";
+ let description = [{
+ This is a generic pass to convert to the EmitC dialect.
+ }];
+ let dependentDialects = [
+ "emitc::EmitCDialect",
+ ];
+}
+
//===----------------------------------------------------------------------===//
// ToLLVM
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt
index b6c21440c571c..e4b4974600577 100644
--- a/mlir/lib/Conversion/CMakeLists.txt
+++ b/mlir/lib/Conversion/CMakeLists.txt
@@ -19,6 +19,7 @@ add_subdirectory(ComplexToStandard)
add_subdirectory(ControlFlowToLLVM)
add_subdirectory(ControlFlowToSCF)
add_subdirectory(ControlFlowToSPIRV)
+add_subdirectory(ConvertToEmitC)
add_subdirectory(ConvertToLLVM)
add_subdirectory(FuncToEmitC)
add_subdirectory(FuncToLLVM)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
new file mode 100644
index 0000000000000..3846f5a279a8a
--- /dev/null
+++ b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
@@ -0,0 +1,25 @@
+set(LLVM_OPTIONAL_SOURCES
+ ConvertToEmitCPass.cpp
+)
+
+add_mlir_conversion_library(MLIRConvertToEmitCPass
+ ConvertToEmitCPass.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/ConvertToEmitC
+
+ DEPENDS
+ MLIRConversionPassIncGen
+
+ LINK_LIBS PUBLIC
+ MLIRArithToEmitC
+ MLIRFuncToEmitC
+ MLIRIR
+ MLIRMemRefToEmitC
+ MLIRPass
+ MLIRRewrite
+ MLIRSCFToEmitC
+ MLIRSupport
+ MLIRTransforms
+ MLIRTransformUtils
+ )
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
new file mode 100644
index 0000000000000..aeadb63e5faa2
--- /dev/null
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -0,0 +1,77 @@
+//===- ConvertToEmitCPass.cpp - MLIR EmitC Conversion ---------------------===//
+//
+// 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 "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
+#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
+#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
+#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/SCF/IR/SCF.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Rewrite/FrozenRewritePatternSet.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+#define DEBUG_TYPE "convert-to-emitc"
+
+namespace mlir {
+#define GEN_PASS_DEF_CONVERTTOEMITCPASS
+#include "mlir/Conversion/Passes.h.inc"
+} // namespace mlir
+
+using namespace mlir;
+
+namespace {
+
+/// Populate patterns for each dialect.
+void populateConvertToEmitCPatterns(TypeConverter &typeConverter,
+ RewritePatternSet &patterns) {
+ populateArithToEmitCPatterns(typeConverter, patterns);
+ populateFuncToEmitCPatterns(patterns);
+ populateMemRefToEmitCTypeConversion(typeConverter);
+ populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
+ populateSCFToEmitCConversionPatterns(patterns);
+ populateFunctionOpInterfaceTypeConversionPattern<emitc::FuncOp>(
+ patterns, typeConverter);
+}
+
+/// A pass to perform the SPIR-V conversion.
+struct ConvertToEmitCPass final
+ : impl::ConvertToEmitCPassBase<ConvertToEmitCPass> {
+ using ConvertToEmitCPassBase::ConvertToEmitCPassBase;
+
+ void runOnOperation() override {
+ Operation *op = getOperation();
+ MLIRContext *context = &getContext();
+
+ RewritePatternSet patterns(context);
+ TypeConverter typeConverter;
+ typeConverter.addConversion([](Type type) { return type; });
+
+ ConversionTarget target(*context);
+ target.addIllegalDialect<arith::ArithDialect, func::FuncDialect,
+ memref::MemRefDialect, scf::SCFDialect>();
+ target.addLegalDialect<emitc::EmitCDialect>();
+ target.addDynamicallyLegalOp<emitc::FuncOp>(
+ [&typeConverter](emitc::FuncOp op) {
+ return typeConverter.isSignatureLegal(op.getFunctionType());
+ });
+
+ populateConvertToEmitCPatterns(typeConverter, patterns);
+ if (failed(applyPartialConversion(op, target, std::move(patterns))))
+ return signalPassFailure();
+ return;
+ }
+};
+
+} // namespace
diff --git a/mlir/test/Conversion/ConvertToEmitC/func-signature.mlir b/mlir/test/Conversion/ConvertToEmitC/func-signature.mlir
new file mode 100644
index 0000000000000..40b898919a7c2
--- /dev/null
+++ b/mlir/test/Conversion/ConvertToEmitC/func-signature.mlir
@@ -0,0 +1,19 @@
+// RUN: mlir-opt -convert-to-emitc %s | FileCheck %s
+
+// CHECK-LABEL emitc.func @int(%[[ARG:.*]]: i32)
+func.func @int(%arg0: i32) {
+ // CHECK: return
+ return
+}
+
+// CHECK-LABEL emitc.func @index(%[[ARG:.*]]: !emitc.size_t)
+func.func @index(%arg0: index) {
+ // CHECK: return
+ return
+}
+
+// CHECK-LABEL emitc.func @memref(%[[ARG:.*]]: !emitc.array<1xf32>)
+func.func @memref(%arg0: memref<1xf32>) {
+ // CHECK: return
+ return
+}
diff --git a/mlir/test/Conversion/ConvertToEmitC/tosa.mlir b/mlir/test/Conversion/ConvertToEmitC/tosa.mlir
new file mode 100644
index 0000000000000..4a7466bd04ba8
--- /dev/null
+++ b/mlir/test/Conversion/ConvertToEmitC/tosa.mlir
@@ -0,0 +1,46 @@
+// DEFINE: %{pipeline} = "builtin.module(\
+// DEFINE: func.func(\
+// DEFINE: tosa-to-linalg\
+// DEFINE: ),\
+// DEFINE: one-shot-bufferize{\
+// DEFINE: bufferize-function-boundaries\
+// DEFINE: function-boundary-type-conversion=identity-layout-map\
+// DEFINE: buffer-alignment=0\
+// DEFINE: },\
+// DEFINE: buffer-results-to-out-params{\
+// DEFINE: hoist-static-allocs=true\
+// DEFINE: },\
+// DEFINE: func.func(\
+// DEFINE: convert-linalg-to-loops\
+// DEFINE: ),\
+// DEFINE: canonicalize,\
+// DEFINE: convert-to-emitc\
+// DEFINE: )"
+
+// RUN: mlir-opt --pass-pipeline=%{pipeline} %s | FileCheck %s
+
+// -----
+
+// CHECK: emitc.func @main(%[[ARG0:.*]]: !emitc.array<2xf32>, %[[ARG1:.*]]: !emitc.array<2xf32>, %[[RES:.*]]: !emitc.array<2xf32>) {
+// CHECK-DAG: %[[C0:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
+// CHECK-DAG: %[[C1:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> !emitc.size_t
+// CHECK-DAG: %[[C2:.*]] = "emitc.constant"() <{value = 2 : index}> : () -> !emitc.size_t
+// CHECK-DAG: %[[I0:.*]] = builtin.unrealized_conversion_cast %[[C0]] : !emitc.size_t to index
+// CHECK-DAG: %[[I1:.*]] = builtin.unrealized_conversion_cast %[[C1]] : !emitc.size_t to index
+// CHECK-DAG: %[[I2:.*]] = builtin.unrealized_conversion_cast %[[C2]] : !emitc.size_t to index
+// CHECK-NEXT: for %[[INDEX:.*]] = %[[I0]] to %[[I2]] step %[[I1]] {
+// CHECK-NEXT: %[[INDEX_S:.*]] = builtin.unrealized_conversion_cast %[[INDEX]] : index to !emitc.size_t
+// CHECK-NEXT: %[[V0_LVALUE:.*]] = emitc.subscript %[[ARG0]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: %[[V0:.*]] = emitc.load %[[V0_LVALUE]] : <f32>
+// CHECK-NEXT: %[[V1_LVALUE:.*]] = emitc.subscript %[[ARG1]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: %[[V1:.*]] = emitc.load %[[V1_LVALUE]] : <f32>
+// CHECK-NEXT: %[[VADD:.*]] = emitc.add %[[V0]], %[[V1]] : (f32, f32) -> f32
+// CHECK-NEXT: %[[RES_LVALUE:.*]] = emitc.subscript %[[RES]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: emitc.assign %[[VADD]] : f32 to %[[RES_LVALUE]] : <f32>
+// CHECK-NEXT: }
+// CHECK-NEXT: return
+// CHECK-NEXT: }
+func.func @main(%arg0: tensor<2xf32>, %arg1: tensor<2xf32>) -> tensor<2xf32> {
+ %0 = tosa.add %arg0, %arg1 : (tensor<2xf32>, tensor<2xf32>) -> tensor<2xf32>
+ return %0 : tensor<2xf32>
+}
>From 3fa45970991374e29de91e2dd357545bf6b3c1fc Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simon.camphausen at iml.fraunhofer.de>
Date: Mon, 25 Nov 2024 14:52:05 +0000
Subject: [PATCH 02/11] Review comments
---
.../Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index aeadb63e5faa2..e176f93e3ebd5 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -33,19 +33,23 @@ using namespace mlir;
namespace {
+void populateConvertToEmitCTypeConverter(TypeConverter &typeConverter) {
+ typeConverter.addConversion([](Type type) { return type; });
+ populateMemRefToEmitCTypeConversion(typeConverter);
+}
+
/// Populate patterns for each dialect.
void populateConvertToEmitCPatterns(TypeConverter &typeConverter,
RewritePatternSet &patterns) {
populateArithToEmitCPatterns(typeConverter, patterns);
populateFuncToEmitCPatterns(patterns);
- populateMemRefToEmitCTypeConversion(typeConverter);
populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
populateSCFToEmitCConversionPatterns(patterns);
populateFunctionOpInterfaceTypeConversionPattern<emitc::FuncOp>(
patterns, typeConverter);
}
-/// A pass to perform the SPIR-V conversion.
+/// A pass to perform the EmitC conversion.
struct ConvertToEmitCPass final
: impl::ConvertToEmitCPassBase<ConvertToEmitCPass> {
using ConvertToEmitCPassBase::ConvertToEmitCPassBase;
@@ -56,7 +60,6 @@ struct ConvertToEmitCPass final
RewritePatternSet patterns(context);
TypeConverter typeConverter;
- typeConverter.addConversion([](Type type) { return type; });
ConversionTarget target(*context);
target.addIllegalDialect<arith::ArithDialect, func::FuncDialect,
@@ -67,7 +70,9 @@ struct ConvertToEmitCPass final
return typeConverter.isSignatureLegal(op.getFunctionType());
});
+ populateConvertToEmitCTypeConverter(typeConverter);
populateConvertToEmitCPatterns(typeConverter, patterns);
+
if (failed(applyPartialConversion(op, target, std::move(patterns))))
return signalPassFailure();
return;
>From 31fe821d441bb3e6ad138c4ed63495ca0a31e4af Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simon.camphausen at iml.fraunhofer.de>
Date: Mon, 25 Nov 2024 15:50:37 +0000
Subject: [PATCH 03/11] Review comment
---
.../ConvertToEmitC/ConvertToEmitC.h | 23 ++++++++++
.../ConvertToEmitC/ConvertToEmitCPass.h | 2 +-
mlir/include/mlir/Conversion/Passes.td | 2 +-
.../Conversion/ConvertToEmitC/CMakeLists.txt | 11 +----
.../ConvertToEmitC/ConvertToEmitC.cpp | 43 +++++++++++++++++++
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 32 +++-----------
6 files changed, 76 insertions(+), 37 deletions(-)
create mode 100644 mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
create mode 100644 mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
new file mode 100644
index 0000000000000..47a8d694ada14
--- /dev/null
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
@@ -0,0 +1,23 @@
+//===- ConvertToEmitC.h - Convert to EmitC Patterns -------------*- 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_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
+#define MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
+
+namespace mlir {
+class RewritePatternSet;
+class TypeConverter;
+
+void populateConvertToEmitCPatterns(TypeConverter &typeConverter,
+ RewritePatternSet &patterns);
+
+void populateConvertToEmitCTypeConverter(TypeConverter &typeConverter);
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
index e6244276e6e68..5986136a68d45 100644
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
@@ -14,7 +14,7 @@
namespace mlir {
class Pass;
-#define GEN_PASS_DECL_CONVERTTOEMITCPASS
+#define GEN_PASS_DECL_CONVERTTOEMITC
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 95eed946fe0fd..bc77b48e8dba1 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -16,7 +16,7 @@ include "mlir/Dialect/Vector/Transforms/VectorTransformsBase.td"
// ToEmitC
//===----------------------------------------------------------------------===//
-def ConvertToEmitCPass : Pass<"convert-to-emitc"> {
+def ConvertToEmitC : Pass<"convert-to-emitc"> {
let summary = "Convert to EmitC dialect";
let description = [{
This is a generic pass to convert to the EmitC dialect.
diff --git a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
index 3846f5a279a8a..b036b050263bc 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
+++ b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
@@ -1,9 +1,6 @@
-set(LLVM_OPTIONAL_SOURCES
- ConvertToEmitCPass.cpp
-)
-
-add_mlir_conversion_library(MLIRConvertToEmitCPass
+add_mlir_conversion_library(MLIRConvertToEmitC
ConvertToEmitCPass.cpp
+ ConvertToEmitC.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/ConvertToEmitC
@@ -14,12 +11,8 @@ add_mlir_conversion_library(MLIRConvertToEmitCPass
LINK_LIBS PUBLIC
MLIRArithToEmitC
MLIRFuncToEmitC
- MLIRIR
MLIRMemRefToEmitC
MLIRPass
- MLIRRewrite
MLIRSCFToEmitC
- MLIRSupport
- MLIRTransforms
MLIRTransformUtils
)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
new file mode 100644
index 0000000000000..2781f4c675de3
--- /dev/null
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
@@ -0,0 +1,43 @@
+//===- ConvertToEmitC.cpp - Convert to EmitC Patterns -----------*- 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/ConvertToEmitC.h"
+#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
+#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
+#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
+#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/SCF/IR/SCF.h"
+#include "mlir/IR/PatternMatch.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Rewrite/FrozenRewritePatternSet.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+#define DEBUG_TYPE "convert-to-emitc"
+
+using namespace mlir;
+
+void mlir::populateConvertToEmitCTypeConverter(TypeConverter &typeConverter) {
+ typeConverter.addConversion([](Type type) { return type; });
+ populateMemRefToEmitCTypeConversion(typeConverter);
+}
+
+/// Populate patterns for each dialect.
+void mlir::populateConvertToEmitCPatterns(TypeConverter &typeConverter,
+ RewritePatternSet &patterns) {
+ populateArithToEmitCPatterns(typeConverter, patterns);
+ populateFuncToEmitCPatterns(patterns);
+ populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
+ populateSCFToEmitCConversionPatterns(patterns);
+ populateFunctionOpInterfaceTypeConversionPattern<emitc::FuncOp>(
+ patterns, typeConverter);
+}
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index e176f93e3ebd5..230cdc3004632 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -1,4 +1,4 @@
-//===- ConvertToEmitCPass.cpp - MLIR EmitC Conversion ---------------------===//
+//===- 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.
@@ -7,10 +7,9 @@
//===----------------------------------------------------------------------===//
#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h"
+
#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
-#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
-#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
-#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
+#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -22,10 +21,8 @@
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
-#define DEBUG_TYPE "convert-to-emitc"
-
namespace mlir {
-#define GEN_PASS_DEF_CONVERTTOEMITCPASS
+#define GEN_PASS_DEF_CONVERTTOEMITC
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir
@@ -33,26 +30,9 @@ using namespace mlir;
namespace {
-void populateConvertToEmitCTypeConverter(TypeConverter &typeConverter) {
- typeConverter.addConversion([](Type type) { return type; });
- populateMemRefToEmitCTypeConversion(typeConverter);
-}
-
-/// Populate patterns for each dialect.
-void populateConvertToEmitCPatterns(TypeConverter &typeConverter,
- RewritePatternSet &patterns) {
- populateArithToEmitCPatterns(typeConverter, patterns);
- populateFuncToEmitCPatterns(patterns);
- populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
- populateSCFToEmitCConversionPatterns(patterns);
- populateFunctionOpInterfaceTypeConversionPattern<emitc::FuncOp>(
- patterns, typeConverter);
-}
-
/// A pass to perform the EmitC conversion.
-struct ConvertToEmitCPass final
- : impl::ConvertToEmitCPassBase<ConvertToEmitCPass> {
- using ConvertToEmitCPassBase::ConvertToEmitCPassBase;
+struct ConvertToEmitC final : impl::ConvertToEmitCBase<ConvertToEmitC> {
+ using ConvertToEmitCBase::ConvertToEmitCBase;
void runOnOperation() override {
Operation *op = getOperation();
>From bc6ecd305126b7d6948b077502613a80c020d016 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simon.camphausen at iml.fraunhofer.de>
Date: Tue, 26 Nov 2024 08:22:27 +0000
Subject: [PATCH 04/11] Use TypeConverter in FuncToEmitC conversion
---
.../mlir/Conversion/FuncToEmitC/FuncToEmitC.h | 4 ++-
.../ConvertToEmitC/ConvertToEmitC.cpp | 4 +--
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 4 ---
.../Conversion/FuncToEmitC/FuncToEmitC.cpp | 36 ++++++++++++++++---
.../FuncToEmitC/FuncToEmitCPass.cpp | 6 +++-
.../ConvertToEmitC/func-failed.mlir | 10 ++++++
.../{func-signature.mlir => func.mlir} | 0
7 files changed, 50 insertions(+), 14 deletions(-)
create mode 100644 mlir/test/Conversion/ConvertToEmitC/func-failed.mlir
rename mlir/test/Conversion/ConvertToEmitC/{func-signature.mlir => func.mlir} (100%)
diff --git a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
index 5c7f87e470306..10b1a4cb76586 100644
--- a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
+++ b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
@@ -11,8 +11,10 @@
namespace mlir {
class RewritePatternSet;
+class TypeConverter;
-void populateFuncToEmitCPatterns(RewritePatternSet &patterns);
+void populateFuncToEmitCPatterns(const TypeConverter &typeConverter,
+ RewritePatternSet &patterns);
} // namespace mlir
#endif // MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
index 2781f4c675de3..4a9a5037e982a 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
@@ -35,9 +35,7 @@ void mlir::populateConvertToEmitCTypeConverter(TypeConverter &typeConverter) {
void mlir::populateConvertToEmitCPatterns(TypeConverter &typeConverter,
RewritePatternSet &patterns) {
populateArithToEmitCPatterns(typeConverter, patterns);
- populateFuncToEmitCPatterns(patterns);
+ populateFuncToEmitCPatterns(typeConverter, patterns);
populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
populateSCFToEmitCConversionPatterns(patterns);
- populateFunctionOpInterfaceTypeConversionPattern<emitc::FuncOp>(
- patterns, typeConverter);
}
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index 230cdc3004632..f00c4e89d29cf 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -45,10 +45,6 @@ struct ConvertToEmitC final : impl::ConvertToEmitCBase<ConvertToEmitC> {
target.addIllegalDialect<arith::ArithDialect, func::FuncDialect,
memref::MemRefDialect, scf::SCFDialect>();
target.addLegalDialect<emitc::EmitCDialect>();
- target.addDynamicallyLegalOp<emitc::FuncOp>(
- [&typeConverter](emitc::FuncOp op) {
- return typeConverter.isSignatureLegal(op.getFunctionType());
- });
populateConvertToEmitCTypeConverter(typeConverter);
populateConvertToEmitCPatterns(typeConverter, patterns);
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index 53b79839da04c..6622b19972c00 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -51,14 +51,34 @@ class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
LogicalResult
matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
+ FunctionType fnType = funcOp.getFunctionType();
- if (funcOp.getFunctionType().getNumResults() > 1)
+ if (fnType.getNumResults() > 1)
return rewriter.notifyMatchFailure(
funcOp, "only functions with zero or one result can be converted");
+ TypeConverter::SignatureConversion signatureConverter(
+ fnType.getNumInputs());
+ for (const auto &argType : enumerate(fnType.getInputs())) {
+ auto convertedType = getTypeConverter()->convertType(argType.value());
+ if (!convertedType)
+ return failure();
+ signatureConverter.addInputs(argType.index(), convertedType);
+ }
+
+ Type resultType;
+ if (fnType.getNumResults() == 1) {
+ resultType = getTypeConverter()->convertType(fnType.getResult(0));
+ if (!resultType)
+ return failure();
+ }
+
// Create the converted `emitc.func` op.
emitc::FuncOp newFuncOp = rewriter.create<emitc::FuncOp>(
- funcOp.getLoc(), funcOp.getName(), funcOp.getFunctionType());
+ funcOp.getLoc(), funcOp.getName(),
+ FunctionType::get(rewriter.getContext(),
+ signatureConverter.getConvertedTypes(),
+ resultType ? TypeRange(resultType) : TypeRange()));
// Copy over all attributes other than the function name and type.
for (const auto &namedAttr : funcOp->getAttrs()) {
@@ -80,9 +100,13 @@ class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
newFuncOp.setSpecifiersAttr(specifiers);
}
- if (!funcOp.isDeclaration())
+ if (!funcOp.isDeclaration()) {
rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
newFuncOp.end());
+ if (failed(rewriter.convertRegionTypes(
+ &newFuncOp.getBody(), *getTypeConverter(), &signatureConverter)))
+ return failure();
+ }
rewriter.eraseOp(funcOp);
return success();
@@ -112,8 +136,10 @@ class ReturnOpConversion final : public OpConversionPattern<func::ReturnOp> {
// Pattern population
//===----------------------------------------------------------------------===//
-void mlir::populateFuncToEmitCPatterns(RewritePatternSet &patterns) {
+void mlir::populateFuncToEmitCPatterns(const TypeConverter &typeConverter,
+ RewritePatternSet &patterns) {
MLIRContext *ctx = patterns.getContext();
- patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(ctx);
+ patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(
+ typeConverter, ctx);
}
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
index 0b97f2641ad08..5b59e7675d7c6 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitCPass.cpp
@@ -39,7 +39,11 @@ void ConvertFuncToEmitC::runOnOperation() {
target.addIllegalOp<func::CallOp, func::FuncOp, func::ReturnOp>();
RewritePatternSet patterns(&getContext());
- populateFuncToEmitCPatterns(patterns);
+
+ TypeConverter typeConverter;
+ typeConverter.addConversion([](Type type) { return type; });
+
+ populateFuncToEmitCPatterns(typeConverter, patterns);
if (failed(
applyPartialConversion(getOperation(), target, std::move(patterns))))
diff --git a/mlir/test/Conversion/ConvertToEmitC/func-failed.mlir b/mlir/test/Conversion/ConvertToEmitC/func-failed.mlir
new file mode 100644
index 0000000000000..a5a20b57d4997
--- /dev/null
+++ b/mlir/test/Conversion/ConvertToEmitC/func-failed.mlir
@@ -0,0 +1,10 @@
+// RUN: mlir-opt -convert-to-emitc %s -split-input-file -verify-diagnostics
+
+func.func @block_args(%arg0: i1, %arg1: index, %arg2: index) -> index {
+ // expected-error @+1 {{type mismatch for bb argument #0 of successor #0}}
+ cf.cond_br %arg0, ^bb1(%arg1: index), ^bb2(%arg2: index)
+^bb1(%0: index):
+ return %0 : index
+^bb2(%1: index):
+ return %1 : index
+}
diff --git a/mlir/test/Conversion/ConvertToEmitC/func-signature.mlir b/mlir/test/Conversion/ConvertToEmitC/func.mlir
similarity index 100%
rename from mlir/test/Conversion/ConvertToEmitC/func-signature.mlir
rename to mlir/test/Conversion/ConvertToEmitC/func.mlir
>From 29366fc97ddf34c2f85ce59ac2e4cc2a689bae49 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simon.camphausen at iml.fraunhofer.de>
Date: Tue, 26 Nov 2024 10:57:45 +0000
Subject: [PATCH 05/11] Drop unused includes and fix header format
---
.../Conversion/ConvertToEmitC/ConvertToEmitCPass.h | 2 +-
mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp | 11 +----------
.../Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp | 6 +-----
3 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
index 5986136a68d45..19334f702fcf1 100644
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
@@ -1,4 +1,4 @@
-//===- ConvertToEmitCPass.h - Conversion to EmitC pass ----*- C++ -*-=========//
+//===- ConvertToEmitCPass.h - 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.
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
index 4a9a5037e982a..8b4055c275b2c 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
@@ -7,22 +7,13 @@
//===----------------------------------------------------------------------===//
#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h"
+
#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
-#include "mlir/Dialect/Arith/IR/Arith.h"
-#include "mlir/Dialect/EmitC/IR/EmitC.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-#include "mlir/Dialect/MemRef/IR/MemRef.h"
-#include "mlir/Dialect/SCF/IR/SCF.h"
-#include "mlir/IR/PatternMatch.h"
-#include "mlir/Pass/Pass.h"
#include "mlir/Rewrite/FrozenRewritePatternSet.h"
#include "mlir/Transforms/DialectConversion.h"
-#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
-
-#define DEBUG_TYPE "convert-to-emitc"
using namespace mlir;
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index f00c4e89d29cf..08fe563665162 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -1,4 +1,4 @@
-//===- ConvertToEmitCPass.cpp - Conversion to EmitC pass --*- C++ -*-=========//
+//===- 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.
@@ -8,18 +8,14 @@
#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h"
-#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
-#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"
-#include "mlir/Rewrite/FrozenRewritePatternSet.h"
#include "mlir/Transforms/DialectConversion.h"
-#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
namespace mlir {
#define GEN_PASS_DEF_CONVERTTOEMITC
>From 7a6e2400e47f29cbeff9833310097cc8e41914e1 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Mon, 10 Feb 2025 17:51:44 +0100
Subject: [PATCH 06/11] Fix errors after rebase
---
.../ConvertToEmitC/ConvertToEmitC.cpp | 2 +-
mlir/test/Conversion/ConvertToEmitC/tosa.mlir | 21 +++++++------------
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
index 8b4055c275b2c..8bd8620f9a925 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
@@ -28,5 +28,5 @@ void mlir::populateConvertToEmitCPatterns(TypeConverter &typeConverter,
populateArithToEmitCPatterns(typeConverter, patterns);
populateFuncToEmitCPatterns(typeConverter, patterns);
populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
- populateSCFToEmitCConversionPatterns(patterns);
+ populateSCFToEmitCConversionPatterns(patterns, typeConverter);
}
diff --git a/mlir/test/Conversion/ConvertToEmitC/tosa.mlir b/mlir/test/Conversion/ConvertToEmitC/tosa.mlir
index 4a7466bd04ba8..8ced05eced4b9 100644
--- a/mlir/test/Conversion/ConvertToEmitC/tosa.mlir
+++ b/mlir/test/Conversion/ConvertToEmitC/tosa.mlir
@@ -18,25 +18,20 @@
// DEFINE: )"
// RUN: mlir-opt --pass-pipeline=%{pipeline} %s | FileCheck %s
-
// -----
// CHECK: emitc.func @main(%[[ARG0:.*]]: !emitc.array<2xf32>, %[[ARG1:.*]]: !emitc.array<2xf32>, %[[RES:.*]]: !emitc.array<2xf32>) {
// CHECK-DAG: %[[C0:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
// CHECK-DAG: %[[C1:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> !emitc.size_t
// CHECK-DAG: %[[C2:.*]] = "emitc.constant"() <{value = 2 : index}> : () -> !emitc.size_t
-// CHECK-DAG: %[[I0:.*]] = builtin.unrealized_conversion_cast %[[C0]] : !emitc.size_t to index
-// CHECK-DAG: %[[I1:.*]] = builtin.unrealized_conversion_cast %[[C1]] : !emitc.size_t to index
-// CHECK-DAG: %[[I2:.*]] = builtin.unrealized_conversion_cast %[[C2]] : !emitc.size_t to index
-// CHECK-NEXT: for %[[INDEX:.*]] = %[[I0]] to %[[I2]] step %[[I1]] {
-// CHECK-NEXT: %[[INDEX_S:.*]] = builtin.unrealized_conversion_cast %[[INDEX]] : index to !emitc.size_t
-// CHECK-NEXT: %[[V0_LVALUE:.*]] = emitc.subscript %[[ARG0]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
-// CHECK-NEXT: %[[V0:.*]] = emitc.load %[[V0_LVALUE]] : <f32>
-// CHECK-NEXT: %[[V1_LVALUE:.*]] = emitc.subscript %[[ARG1]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
-// CHECK-NEXT: %[[V1:.*]] = emitc.load %[[V1_LVALUE]] : <f32>
-// CHECK-NEXT: %[[VADD:.*]] = emitc.add %[[V0]], %[[V1]] : (f32, f32) -> f32
-// CHECK-NEXT: %[[RES_LVALUE:.*]] = emitc.subscript %[[RES]][%[[INDEX_S]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
-// CHECK-NEXT: emitc.assign %[[VADD]] : f32 to %[[RES_LVALUE]] : <f32>
+// CHECK-NEXT: for %[[INDEX:.*]] = %[[C0]] to %[[C2]] step %[[C1]] : !emitc.size_t {
+// CHECK-NEXT: %[[V0_LVALUE:.*]] = subscript %[[ARG0]][%[[INDEX]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: %[[V0:.*]] = load %[[V0_LVALUE]] : <f32>
+// CHECK-NEXT: %[[V1_LVALUE:.*]] = subscript %[[ARG1]][%[[INDEX]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: %[[V1:.*]] = load %[[V1_LVALUE]] : <f32>
+// CHECK-NEXT: %[[VADD:.*]] = add %[[V0]], %[[V1]] : (f32, f32) -> f32
+// CHECK-NEXT: %[[RES_LVALUE:.*]] = subscript %[[RES]][%[[INDEX]]] : (!emitc.array<2xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+// CHECK-NEXT: assign %[[VADD]] : f32 to %[[RES_LVALUE]] : <f32>
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
>From 3e82694f3e6d03eb2189fc8369f426d32cc7d102 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Wed, 12 Feb 2025 20:21:53 +0100
Subject: [PATCH 07/11] Add interfaces for conversion
---
.../Conversion/ArithToEmitC/ArithToEmitC.h | 3 +
.../ConvertToEmitC/ConvertToEmitC.h | 23 --
.../ConvertToEmitC/ConvertToEmitCPass.h | 2 +
.../ConvertToEmitC/ToEmitCInterface.h | 52 +++++
.../mlir/Conversion/FuncToEmitC/FuncToEmitC.h | 3 +
.../Conversion/MemRefToEmitC/MemRefToEmitC.h | 3 +
mlir/include/mlir/Conversion/Passes.td | 5 +-
.../mlir/Conversion/SCFToEmitC/SCFToEmitC.h | 3 +
mlir/include/mlir/InitAllExtensions.h | 8 +
.../Conversion/ArithToEmitC/ArithToEmitC.cpp | 28 +++
.../Conversion/ConvertToEmitC/CMakeLists.txt | 1 -
.../ConvertToEmitC/ConvertToEmitC.cpp | 32 ---
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 214 ++++++++++++++++--
.../Conversion/FuncToEmitC/FuncToEmitC.cpp | 28 +++
.../MemRefToEmitC/MemRefToEmitC.cpp | 45 ++++
.../MemRefToEmitC/MemRefToEmitCPass.cpp | 13 --
mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp | 28 +++
mlir/lib/Dialect/Arith/IR/ArithDialect.cpp | 2 +
mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 2 +-
mlir/lib/Dialect/Func/IR/FuncOps.cpp | 2 +
mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp | 2 +
mlir/lib/Dialect/SCF/IR/SCF.cpp | 2 +
.../ArithToEmitC/arith-to-emitc-failed.mlir | 1 +
.../arith-to-emitc-unsupported.mlir | 1 +
.../ArithToEmitC/arith-to-emitc.mlir | 1 +
.../Conversion/FuncToEmitC/func-to-emitc.mlir | 2 +
.../MemRefToEmitC/memref-to-emitc-failed.mlir | 1 +
.../MemRefToEmitC/memref-to-emitc.mlir | 1 +
mlir/test/Conversion/SCFToEmitC/for.mlir | 1 +
mlir/test/Conversion/SCFToEmitC/if.mlir | 1 +
mlir/test/Conversion/SCFToEmitC/switch.mlir | 1 +
31 files changed, 418 insertions(+), 93 deletions(-)
delete mode 100644 mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
create mode 100644 mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
delete mode 100644 mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
diff --git a/mlir/include/mlir/Conversion/ArithToEmitC/ArithToEmitC.h b/mlir/include/mlir/Conversion/ArithToEmitC/ArithToEmitC.h
index 9cb43689d1ce6..0dfd141214180 100644
--- a/mlir/include/mlir/Conversion/ArithToEmitC/ArithToEmitC.h
+++ b/mlir/include/mlir/Conversion/ArithToEmitC/ArithToEmitC.h
@@ -10,11 +10,14 @@
#define MLIR_CONVERSION_ARITHTOEMITC_ARITHTOEMITC_H
namespace mlir {
+class DialectRegistry;
class RewritePatternSet;
class TypeConverter;
void populateArithToEmitCPatterns(TypeConverter &typeConverter,
RewritePatternSet &patterns);
+
+void registerConvertArithToEmitCInterface(DialectRegistry ®istry);
} // namespace mlir
#endif // MLIR_CONVERSION_ARITHTOEMITC_ARITHTOEMITC_H
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
deleted file mode 100644
index 47a8d694ada14..0000000000000
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//===- ConvertToEmitC.h - Convert to EmitC Patterns -------------*- 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_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
-#define MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
-
-namespace mlir {
-class RewritePatternSet;
-class TypeConverter;
-
-void populateConvertToEmitCPatterns(TypeConverter &typeConverter,
- RewritePatternSet &patterns);
-
-void populateConvertToEmitCTypeConverter(TypeConverter &typeConverter);
-
-} // namespace mlir
-
-#endif // MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITC_H
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
index 19334f702fcf1..8b4a5483816b7 100644
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h
@@ -9,6 +9,8 @@
#ifndef MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITCPASS_H
#define MLIR_CONVERSION_CONVERTTOEMITC_CONVERTTOEMITCPASS_H
+#include "llvm/ADT/SmallVector.h"
+
#include <memory>
namespace mlir {
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
new file mode 100644
index 0000000000000..cfaeafb546733
--- /dev/null
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
@@ -0,0 +1,52 @@
+//===- ToEmitCInterface.h - Conversion to EmitC iface ---*- 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_CONVERSION_CONVERTTOEMITC_TOEMITCINTERFACE_H
+#define MLIR_CONVERSION_CONVERTTOEMITC_TOEMITCINTERFACE_H
+
+#include "mlir/IR/DialectInterface.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OpDefinition.h"
+
+namespace mlir {
+class ConversionTarget;
+class TypeConverter;
+class MLIRContext;
+class Operation;
+class RewritePatternSet;
+class AnalysisManager;
+
+class ConvertToEmitCPatternInterface
+ : public DialectInterface::Base<ConvertToEmitCPatternInterface> {
+public:
+ ConvertToEmitCPatternInterface(Dialect *dialect) : Base(dialect) {}
+
+ /// Hook for derived dialect interface to load the dialects they
+ /// target. The EmitC dialect is implicitly already loaded, but this
+ /// method allows to load other intermediate dialects used in the
+ /// conversion, or target dialects like NVVM for example.
+ virtual void loadDependentDialects(MLIRContext *context) const {}
+
+ /// Hook for derived dialect interface to provide conversion patterns
+ /// and mark dialect legal for the conversion target.
+ virtual void populateConvertToEmitCConversionPatterns(
+ ConversionTarget &target, TypeConverter &typeConverter,
+ RewritePatternSet &patterns) const = 0;
+};
+
+/// Recursively walk the IR and collect all dialects implementing the interface,
+/// and populate the conversion patterns.
+void populateConversionTargetFromOperation(Operation *op,
+ ConversionTarget &target,
+ TypeConverter &typeConverter,
+ RewritePatternSet &patterns);
+
+} // namespace mlir
+
+
+#endif // MLIR_CONVERSION_CONVERTTOEMITC_TOEMITCINTERFACE_H
diff --git a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
index 10b1a4cb76586..be6b6cfe5a6db 100644
--- a/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
+++ b/mlir/include/mlir/Conversion/FuncToEmitC/FuncToEmitC.h
@@ -10,11 +10,14 @@
#define MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
namespace mlir {
+class DialectRegistry;
class RewritePatternSet;
class TypeConverter;
void populateFuncToEmitCPatterns(const TypeConverter &typeConverter,
RewritePatternSet &patterns);
+
+void registerConvertFuncToEmitCInterface(DialectRegistry ®istry);
} // namespace mlir
#endif // MLIR_CONVERSION_FUNCTOEMITC_FUNCTOEMITC_H
diff --git a/mlir/include/mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h b/mlir/include/mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h
index 950d50229bac1..364a70ce6469b 100644
--- a/mlir/include/mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h
+++ b/mlir/include/mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h
@@ -9,6 +9,7 @@
#define MLIR_CONVERSION_MEMREFTOEMITC_MEMREFTOEMITC_H
namespace mlir {
+class DialectRegistry;
class RewritePatternSet;
class TypeConverter;
@@ -16,6 +17,8 @@ void populateMemRefToEmitCTypeConversion(TypeConverter &typeConverter);
void populateMemRefToEmitCConversionPatterns(RewritePatternSet &patterns,
const TypeConverter &converter);
+
+void registerConvertMemRefToEmitCInterface(DialectRegistry ®istry);
} // namespace mlir
#endif // MLIR_CONVERSION_MEMREFTOEMITC_MEMREFTOEMITC_H
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index bc77b48e8dba1..b0149a6428a27 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -21,8 +21,9 @@ def ConvertToEmitC : Pass<"convert-to-emitc"> {
let description = [{
This is a generic pass to convert to the EmitC dialect.
}];
- let dependentDialects = [
- "emitc::EmitCDialect",
+ let options = [
+ ListOption<"filterDialects", "filter-dialects", "std::string",
+ "Test conversion patterns of only the specified dialects">,
];
}
diff --git a/mlir/include/mlir/Conversion/SCFToEmitC/SCFToEmitC.h b/mlir/include/mlir/Conversion/SCFToEmitC/SCFToEmitC.h
index acc39e6acf726..493da54e5294f 100644
--- a/mlir/include/mlir/Conversion/SCFToEmitC/SCFToEmitC.h
+++ b/mlir/include/mlir/Conversion/SCFToEmitC/SCFToEmitC.h
@@ -13,6 +13,7 @@
#include <memory>
namespace mlir {
+class DialectRegistry;
class Pass;
class RewritePatternSet;
@@ -22,6 +23,8 @@ class RewritePatternSet;
/// Collect a set of patterns to convert SCF operations to the EmitC dialect.
void populateSCFToEmitCConversionPatterns(RewritePatternSet &patterns,
TypeConverter &typeConverter);
+
+void registerConvertSCFToEmitCInterface(DialectRegistry ®istry);
} // namespace mlir
#endif // MLIR_CONVERSION_SCFTOEMITC_SCFTOEMITC_H
diff --git a/mlir/include/mlir/InitAllExtensions.h b/mlir/include/mlir/InitAllExtensions.h
index 373644d31a46c..37e4904cb48ed 100644
--- a/mlir/include/mlir/InitAllExtensions.h
+++ b/mlir/include/mlir/InitAllExtensions.h
@@ -14,18 +14,22 @@
#ifndef MLIR_INITALLEXTENSIONS_H_
#define MLIR_INITALLEXTENSIONS_H_
+#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
#include "mlir/Conversion/ComplexToLLVM/ComplexToLLVM.h"
#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
+#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
#include "mlir/Conversion/GPUCommon/GPUToLLVM.h"
#include "mlir/Conversion/GPUToNVVM/GPUToNVVM.h"
#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
#include "mlir/Conversion/MPIToLLVM/MPIToLLVM.h"
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
+#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
#include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h"
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
+#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
#include "mlir/Conversion/UBToLLVM/UBToLLVM.h"
#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
#include "mlir/Dialect/AMX/Transforms.h"
@@ -63,18 +67,22 @@ namespace mlir {
/// pipelines and transformations you are using.
inline void registerAllExtensions(DialectRegistry ®istry) {
// Register all conversions to LLVM extensions.
+ registerConvertArithToEmitCInterface(registry);
arith::registerConvertArithToLLVMInterface(registry);
registerConvertComplexToLLVMInterface(registry);
cf::registerConvertControlFlowToLLVMInterface(registry);
func::registerAllExtensions(registry);
tensor::registerAllExtensions(registry);
+ registerConvertFuncToEmitCInterface(registry);
registerConvertFuncToLLVMInterface(registry);
index::registerConvertIndexToLLVMInterface(registry);
registerConvertMathToLLVMInterface(registry);
mpi::registerConvertMPIToLLVMInterface(registry);
+ registerConvertMemRefToEmitCInterface(registry);
registerConvertMemRefToLLVMInterface(registry);
registerConvertNVVMToLLVMInterface(registry);
registerConvertOpenMPToLLVMInterface(registry);
+ registerConvertSCFToEmitCInterface(registry);
ub::registerConvertUBToLLVMInterface(registry);
registerConvertAMXToLLVMInterface(registry);
gpu::registerConvertGpuToLLVMInterface(registry);
diff --git a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
index 359d7b2279639..a4954b294d09c 100644
--- a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
+++ b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
@@ -13,6 +13,7 @@
#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
@@ -22,10 +23,37 @@
using namespace mlir;
+namespace {
+/// Implement the interface to convert Arith to EmitC.
+struct ArithToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
+ using ConvertToEmitCPatternInterface::ConvertToEmitCPatternInterface;
+ void loadDependentDialects(MLIRContext *context) const final {
+ context->loadDialect<emitc::EmitCDialect>();
+ }
+
+ /// Hook for derived dialect interface to provide conversion patterns
+ /// and mark dialect legal for the conversion target.
+ void populateConvertToEmitCConversionPatterns(
+ ConversionTarget &target, TypeConverter &typeConverter,
+ RewritePatternSet &patterns) const final {
+ populateArithToEmitCPatterns(typeConverter, patterns);
+ }
+};
+} // namespace
+
+void mlir::registerConvertArithToEmitCInterface(
+ DialectRegistry ®istry) {
+ registry.addExtension(+[](MLIRContext *ctx, arith::ArithDialect *dialect) {
+ dialect->addInterfaces<ArithToEmitCDialectInterface>();
+ });
+}
+
+
//===----------------------------------------------------------------------===//
// Conversion Patterns
//===----------------------------------------------------------------------===//
+
namespace {
class ArithConstantOpConversionPattern
: public OpConversionPattern<arith::ConstantOp> {
diff --git a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
index b036b050263bc..e0d766570d5eb 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
+++ b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
@@ -1,6 +1,5 @@
add_mlir_conversion_library(MLIRConvertToEmitC
ConvertToEmitCPass.cpp
- ConvertToEmitC.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/ConvertToEmitC
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
deleted file mode 100644
index 8bd8620f9a925..0000000000000
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitC.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===- ConvertToEmitC.cpp - Convert to EmitC Patterns -----------*- 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/ConvertToEmitC.h"
-
-#include "mlir/Conversion/ArithToEmitC/ArithToEmitC.h"
-#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
-#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
-#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
-#include "mlir/Rewrite/FrozenRewritePatternSet.h"
-#include "mlir/Transforms/DialectConversion.h"
-
-using namespace mlir;
-
-void mlir::populateConvertToEmitCTypeConverter(TypeConverter &typeConverter) {
- typeConverter.addConversion([](Type type) { return type; });
- populateMemRefToEmitCTypeConversion(typeConverter);
-}
-
-/// Populate patterns for each dialect.
-void mlir::populateConvertToEmitCPatterns(TypeConverter &typeConverter,
- RewritePatternSet &patterns) {
- populateArithToEmitCPatterns(typeConverter, patterns);
- populateFuncToEmitCPatterns(typeConverter, patterns);
- populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
- populateSCFToEmitCConversionPatterns(patterns, typeConverter);
-}
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index 08fe563665162..6010b9871b6f8 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -8,15 +8,18 @@
#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitCPass.h"
-#include "mlir/Conversion/ConvertToEmitC/ConvertToEmitC.h"
-#include "mlir/Dialect/Arith/IR/Arith.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/Dialect/Func/IR/FuncOps.h"
-#include "mlir/Dialect/MemRef/IR/MemRef.h"
-#include "mlir/Dialect/SCF/IR/SCF.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"
@@ -25,30 +28,199 @@ 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=*/{}) {}
-/// A pass to perform the EmitC conversion.
-struct ConvertToEmitC final : impl::ConvertToEmitCBase<ConvertToEmitC> {
- using ConvertToEmitCBase::ConvertToEmitCBase;
+ 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);
+ }
+ }
- void runOnOperation() override {
- Operation *op = getOperation();
- MLIRContext *context = &getContext();
+ /// Return a copy of this extension.
+ std::unique_ptr<DialectExtensionBase> clone() const final {
+ return std::make_unique<LoadDependentDialectExtension>(*this);
+ }
+};
- RewritePatternSet patterns(context);
- TypeConverter typeConverter;
+//===----------------------------------------------------------------------===//
+// StaticConvertToEmitC
+//===----------------------------------------------------------------------===//
- ConversionTarget target(*context);
- target.addIllegalDialect<arith::ArithDialect, func::FuncDialect,
- memref::MemRefDialect, scf::SCFDialect>();
- target.addLegalDialect<emitc::EmitCDialect>();
+/// 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;
- populateConvertToEmitCTypeConverter(typeConverter);
- populateConvertToEmitCPatterns(typeConverter, patterns);
+ /// Configure the conversion to EmitC at pass initialization.
+ LogicalResult initialize() final {
+ auto target = std::make_shared<ConversionTarget>(*context);
+ auto typeConverter = std::make_shared<TypeConverter>();
- if (failed(applyPartialConversion(op, target, std::move(patterns))))
+ // 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.
+class ConvertToEmitC
+ : public impl::ConvertToEmitCBase<ConvertToEmitC> {
+ std::shared_ptr<const ConvertToEmitCPassInterface> impl;
+
+public:
+ using impl::ConvertToEmitCBase<ConvertToEmitC>::ConvertToEmitCBase;
+ void getDependentDialects(DialectRegistry ®istry) const final {
+ ConvertToEmitCPassInterface::getDependentDialects(registry);
+ }
+
+ LogicalResult initialize(MLIRContext *context) final {
+ std::shared_ptr<ConvertToEmitCPassInterface> impl;
+ impl = std::make_shared<StaticConvertToEmitC>(context, filterDialects);
+ if (failed(impl->initialize()))
+ return failure();
+ this->impl = impl;
+ return success();
+ }
+
+ void runOnOperation() final {
+ if (failed(impl->transform(getOperation(), getAnalysisManager())))
return signalPassFailure();
- return;
}
};
} // namespace
+
+//===----------------------------------------------------------------------===//
+// ConvertToEmitCPassInterface
+//===----------------------------------------------------------------------===//
+
+ConvertToEmitCPassInterface::ConvertToEmitCPassInterface(
+ MLIRContext *context, ArrayRef<std::string> filterDialects)
+ : context(context), filterDialects(filterDialects) {}
+
+void ConvertToEmitCPassInterface::getDependentDialects(
+ DialectRegistry ®istry) {
+ registry.insert<emitc::EmitCDialect>();
+ registry.addExtensions<LoadDependentDialectExtension>();
+}
+
+LogicalResult ConvertToEmitCPassInterface::visitInterfaces(
+ llvm::function_ref<void(ConvertToEmitCPatternInterface *)> visitor) {
+ if (!filterDialects.empty()) {
+ // Test mode: Populate only patterns from the specified dialects. Produce
+ // an error if the dialect is not loaded or does not implement the
+ // interface.
+ for (StringRef dialectName : filterDialects) {
+ Dialect *dialect = context->getLoadedDialect(dialectName);
+ if (!dialect)
+ return emitError(UnknownLoc::get(context))
+ << "dialect not loaded: " << dialectName << "\n";
+ auto *iface = dyn_cast<ConvertToEmitCPatternInterface>(dialect);
+ if (!iface)
+ return emitError(UnknownLoc::get(context))
+ << "dialect does not implement ConvertToEmitCPatternInterface: "
+ << dialectName << "\n";
+ visitor(iface);
+ }
+ } else {
+ // Normal mode: Populate all patterns from all dialects that implement the
+ // interface.
+ for (Dialect *dialect : context->getLoadedDialects()) {
+ // First time we encounter this dialect: if it implements the interface,
+ // let's populate patterns !
+ auto *iface = dyn_cast<ConvertToEmitCPatternInterface>(dialect);
+ if (!iface)
+ continue;
+ visitor(iface);
+ }
+ }
+ return success();
+}
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index 6622b19972c00..4cff06ef951cd 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -13,12 +13,40 @@
#include "mlir/Conversion/FuncToEmitC/FuncToEmitC.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Transforms/DialectConversion.h"
using namespace mlir;
+namespace {
+
+/// Implement the interface to convert Func to EmitC.
+struct FuncToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
+ using ConvertToEmitCPatternInterface::ConvertToEmitCPatternInterface;
+ void loadDependentDialects(MLIRContext *context) const final {
+ context->loadDialect<emitc::EmitCDialect>();
+ }
+
+ /// Hook for derived dialect interface to provide conversion patterns
+ /// and mark dialect legal for the conversion target.
+ void populateConvertToEmitCConversionPatterns(
+ ConversionTarget &target, TypeConverter &typeConverter,
+ RewritePatternSet &patterns) const final {
+ populateFuncToEmitCPatterns(typeConverter, patterns);
+ }
+};
+} // namespace
+
+void mlir::registerConvertFuncToEmitCInterface(
+ DialectRegistry ®istry) {
+ registry.addExtension(+[](MLIRContext *ctx, func::FuncDialect *dialect) {
+ dialect->addInterfaces<FuncToEmitCDialectInterface>();
+ });
+}
+
+
//===----------------------------------------------------------------------===//
// Conversion Patterns
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
index 39532d34f616e..b19ce7bacefac 100644
--- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
+++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
@@ -12,6 +12,7 @@
#include "mlir/Conversion/MemRefToEmitC/MemRefToEmitC.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/IR/Builders.h"
@@ -20,6 +21,37 @@
using namespace mlir;
+namespace {
+/// Implement the interface to convert MemRef to EmitC.
+struct MemRefToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
+ using ConvertToEmitCPatternInterface::ConvertToEmitCPatternInterface;
+ void loadDependentDialects(MLIRContext *context) const final {
+ context->loadDialect<emitc::EmitCDialect>();
+ }
+
+ /// Hook for derived dialect interface to provide conversion patterns
+ /// and mark dialect legal for the conversion target.
+ void populateConvertToEmitCConversionPatterns(
+ ConversionTarget &target, TypeConverter &typeConverter,
+ RewritePatternSet &patterns) const final {
+ populateMemRefToEmitCTypeConversion(typeConverter);
+ populateMemRefToEmitCConversionPatterns(patterns, typeConverter);
+ }
+};
+} // namespace
+
+void mlir::registerConvertMemRefToEmitCInterface(
+ DialectRegistry ®istry) {
+ registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) {
+ dialect->addInterfaces<MemRefToEmitCDialectInterface>();
+ });
+}
+
+
+//===----------------------------------------------------------------------===//
+// Conversion Patterns
+//===----------------------------------------------------------------------===//
+
namespace {
struct ConvertAlloca final : public OpConversionPattern<memref::AllocaOp> {
using OpConversionPattern::OpConversionPattern;
@@ -179,6 +211,19 @@ void mlir::populateMemRefToEmitCTypeConversion(TypeConverter &typeConverter) {
return emitc::ArrayType::get(memRefType.getShape(),
convertedElementType);
});
+
+ auto materializeAsUnrealizedCast = [](OpBuilder &builder, Type resultType,
+ ValueRange inputs,
+ Location loc) -> Value {
+ if (inputs.size() != 1)
+ return Value();
+
+ return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
+ .getResult(0);
+ };
+
+ typeConverter.addSourceMaterialization(materializeAsUnrealizedCast);
+ typeConverter.addTargetMaterialization(materializeAsUnrealizedCast);
}
void mlir::populateMemRefToEmitCConversionPatterns(
diff --git a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
index 33097c71e70b1..cf25c09a2c2f3 100644
--- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
+++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitCPass.cpp
@@ -40,19 +40,6 @@ struct ConvertMemRefToEmitCPass
populateMemRefToEmitCTypeConversion(converter);
- auto materializeAsUnrealizedCast = [](OpBuilder &builder, Type resultType,
- ValueRange inputs,
- Location loc) -> Value {
- if (inputs.size() != 1)
- return Value();
-
- return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
- .getResult(0);
- };
-
- converter.addSourceMaterialization(materializeAsUnrealizedCast);
- converter.addTargetMaterialization(materializeAsUnrealizedCast);
-
RewritePatternSet patterns(&getContext());
populateMemRefToEmitCConversionPatterns(patterns, converter);
diff --git a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
index d81e92c842369..1bbfc8dd6d3ed 100644
--- a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
+++ b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
@@ -12,6 +12,7 @@
#include "mlir/Conversion/SCFToEmitC/SCFToEmitC.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
@@ -34,6 +35,33 @@ using namespace mlir::scf;
namespace {
+/// Implement the interface to convert SCF to EmitC.
+struct SCFToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
+ using ConvertToEmitCPatternInterface::ConvertToEmitCPatternInterface;
+ void loadDependentDialects(MLIRContext *context) const final {
+ context->loadDialect<emitc::EmitCDialect>();
+ }
+
+ /// Hook for derived dialect interface to provide conversion patterns
+ /// and mark dialect legal for the conversion target.
+ void populateConvertToEmitCConversionPatterns(
+ ConversionTarget &target, TypeConverter &typeConverter,
+ RewritePatternSet &patterns) const final {
+ populateEmitCSizeTTypeConversions(typeConverter);
+ populateSCFToEmitCConversionPatterns(patterns, typeConverter);
+ }
+};
+} // namespace
+
+void mlir::registerConvertSCFToEmitCInterface(
+ DialectRegistry ®istry) {
+ registry.addExtension(+[](MLIRContext *ctx, scf::SCFDialect *dialect) {
+ dialect->addInterfaces<SCFToEmitCDialectInterface>();
+ });
+}
+
+namespace {
+
struct SCFToEmitCPass : public impl::SCFToEmitCBase<SCFToEmitCPass> {
void runOnOperation() override;
};
diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
index 042acf6100900..ebcb951cf3518 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
@@ -48,6 +49,7 @@ void arith::ArithDialect::initialize() {
#include "mlir/Dialect/Arith/IR/ArithOpsAttributes.cpp.inc"
>();
addInterfaces<ArithInlinerInterface>();
+ declarePromisedInterface<ConvertToEmitCPatternInterface, ArithDialect>();
declarePromisedInterface<ConvertToLLVMPatternInterface, ArithDialect>();
declarePromisedInterface<bufferization::BufferDeallocationOpInterface,
SelectOp>();
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index b4d7482554fbc..535512c6933e8 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -1044,7 +1044,7 @@ Type emitc::ArrayType::parse(AsmParser &parser) {
// Check that array is formed from allowed types.
if (!isValidElementType(elementType))
- return parser.emitError(typeLoc, "invalid array element type"), Type();
+ return parser.emitError(typeLoc, "invalid array element type '") << elementType << "'", Type();
if (parser.parseGreater())
return Type();
return parser.getChecked<ArrayType>(dimensions, elementType);
diff --git a/mlir/lib/Dialect/Func/IR/FuncOps.cpp b/mlir/lib/Dialect/Func/IR/FuncOps.cpp
index ba7b84f27d6a8..aa068966ba607 100644
--- a/mlir/lib/Dialect/Func/IR/FuncOps.cpp
+++ b/mlir/lib/Dialect/Func/IR/FuncOps.cpp
@@ -8,6 +8,7 @@
#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
#include "mlir/IR/BuiltinOps.h"
@@ -41,6 +42,7 @@ void FuncDialect::initialize() {
#define GET_OP_LIST
#include "mlir/Dialect/Func/IR/FuncOps.cpp.inc"
>();
+ declarePromisedInterface<ConvertToEmitCPatternInterface, FuncDialect>();
declarePromisedInterface<DialectInlinerInterface, FuncDialect>();
declarePromisedInterface<ConvertToLLVMPatternInterface, FuncDialect>();
declarePromisedInterfaces<bufferization::BufferizableOpInterface, CallOp,
diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
index 3a8bd12ba2586..6d0ac8a650776 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Bufferization/IR/AllocationOpInterface.h"
@@ -47,6 +48,7 @@ void mlir::memref::MemRefDialect::initialize() {
#include "mlir/Dialect/MemRef/IR/MemRefOps.cpp.inc"
>();
addInterfaces<MemRefInlinerInterface>();
+ declarePromisedInterface<ConvertToEmitCPatternInterface, MemRefDialect>();
declarePromisedInterface<ConvertToLLVMPatternInterface, MemRefDialect>();
declarePromisedInterfaces<bufferization::AllocationOpInterface, AllocOp,
AllocaOp, ReallocOp>();
diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp
index 344941da260fe..b4d1cdbab479e 100644
--- a/mlir/lib/Dialect/SCF/IR/SCF.cpp
+++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Arith/Utils/Utils.h"
@@ -73,6 +74,7 @@ void SCFDialect::initialize() {
#include "mlir/Dialect/SCF/IR/SCFOps.cpp.inc"
>();
addInterfaces<SCFInlinerInterface>();
+ declarePromisedInterface<ConvertToEmitCPatternInterface, SCFDialect>();
declarePromisedInterfaces<bufferization::BufferDeallocationOpInterface,
InParallelOp, ReduceReturnOp>();
declarePromisedInterfaces<bufferization::BufferizableOpInterface, ConditionOp,
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
index 30abd81f3d447..15c9076c6c997 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -convert-arith-to-emitc %s -split-input-file -verify-diagnostics
+// RUN: mlir-opt -convert-to-emitc="filter-dialects=arith" -split-input-file -verify-diagnostics
func.func @bool(%arg0: i1, %arg1: i1) {
// expected-error at +1 {{failed to legalize operation 'arith.addi'}}
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
index 9850f336b5ad6..083e6bac40ab1 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -split-input-file -convert-arith-to-emitc -verify-diagnostics %s
+// RUN: mlir-opt -split-input-file -convert-to-emitc="filter-dialects=arith" -verify-diagnostics %s
func.func @arith_cast_tensor(%arg0: tensor<5xf32>) -> tensor<5xi32> {
// expected-error @+1 {{failed to legalize operation 'arith.fptosi'}}
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
index cb1d092918f03..1382f3cc13a3b 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -split-input-file -convert-arith-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -split-input-file -convert-to-emitc="filter-dialects=arith" %s | FileCheck %s
// CHECK-LABEL: arith_constants
func.func @arith_constants() {
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index bd48886ed739e..7657dd3fb9286 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -1,4 +1,6 @@
// RUN: mlir-opt -split-input-file -convert-func-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -split-input-file -convert-to-emitc="filter-dialects=func" %s | FileCheck %s
+
// CHECK-LABEL: emitc.func @foo()
// CHECK-NEXT: return
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
index fda01974d3fc8..e6eba5b223efa 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -convert-memref-to-emitc %s -split-input-file -verify-diagnostics
+// RUN: mlir-opt -convert-to-emitc="filter-dialects=memref" %s -split-input-file -verify-diagnostics
func.func @memref_op(%arg0 : memref<2x4xf32>) {
// expected-error at +1 {{failed to legalize operation 'memref.copy'}}
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
index f5ef821cc9c05..d37fd1de90add 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -convert-memref-to-emitc %s -split-input-file | FileCheck %s
+// RUN: mlir-opt -convert-to-emitc="filter-dialects=memref" %s -split-input-file | FileCheck %s
// CHECK-LABEL: alloca()
func.func @alloca() {
diff --git a/mlir/test/Conversion/SCFToEmitC/for.mlir b/mlir/test/Conversion/SCFToEmitC/for.mlir
index 232a0fb2e8252..571517fe7bf19 100644
--- a/mlir/test/Conversion/SCFToEmitC/for.mlir
+++ b/mlir/test/Conversion/SCFToEmitC/for.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect -convert-to-emitc="filter-dialects=scf" %s | FileCheck %s
func.func @simple_std_for_loop(%arg0 : index, %arg1 : index, %arg2 : index) {
scf.for %i0 = %arg0 to %arg1 step %arg2 {
diff --git a/mlir/test/Conversion/SCFToEmitC/if.mlir b/mlir/test/Conversion/SCFToEmitC/if.mlir
index 9acd9b0783d21..596a4872b3030 100644
--- a/mlir/test/Conversion/SCFToEmitC/if.mlir
+++ b/mlir/test/Conversion/SCFToEmitC/if.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect -convert-to-emitc="filter-dialects=scf" %s | FileCheck %s
func.func @test_if(%arg0: i1, %arg1: f32) {
scf.if %arg0 {
diff --git a/mlir/test/Conversion/SCFToEmitC/switch.mlir b/mlir/test/Conversion/SCFToEmitC/switch.mlir
index 3f0793ccd7e3b..0dab98c8cc341 100644
--- a/mlir/test/Conversion/SCFToEmitC/switch.mlir
+++ b/mlir/test/Conversion/SCFToEmitC/switch.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-opt -allow-unregistered-dialect -convert-scf-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect -convert-to-emitc="filter-dialects=scf" %s | FileCheck %s
// CHECK-LABEL: func.func @switch_no_result(
// CHECK-SAME: %[[ARG_0:.*]]: index) {
>From d619ac56b38a1a0ea5c10d5524ae7cbae6dd6204 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Sun, 23 Feb 2025 09:59:54 +0100
Subject: [PATCH 08/11] Fix formatting errors
---
.../ConvertToEmitC/ToEmitCInterface.h | 1 -
.../Conversion/ArithToEmitC/ArithToEmitC.cpp | 5 +---
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 24 +++++++++----------
.../Conversion/FuncToEmitC/FuncToEmitC.cpp | 4 +---
.../MemRefToEmitC/MemRefToEmitC.cpp | 24 +++++++++----------
mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp | 3 +--
mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 4 +++-
mlir/lib/Dialect/SCF/IR/SCF.cpp | 2 +-
8 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
index cfaeafb546733..6dd1796958118 100644
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
@@ -48,5 +48,4 @@ void populateConversionTargetFromOperation(Operation *op,
} // namespace mlir
-
#endif // MLIR_CONVERSION_CONVERTTOEMITC_TOEMITCINTERFACE_H
diff --git a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
index a4954b294d09c..d8be8b987af12 100644
--- a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
+++ b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
@@ -41,19 +41,16 @@ struct ArithToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
};
} // namespace
-void mlir::registerConvertArithToEmitCInterface(
- DialectRegistry ®istry) {
+void mlir::registerConvertArithToEmitCInterface(DialectRegistry ®istry) {
registry.addExtension(+[](MLIRContext *ctx, arith::ArithDialect *dialect) {
dialect->addInterfaces<ArithToEmitCDialectInterface>();
});
}
-
//===----------------------------------------------------------------------===//
// Conversion Patterns
//===----------------------------------------------------------------------===//
-
namespace {
class ArithConstantOpConversionPattern
: public OpConversionPattern<arith::ConstantOp> {
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index 6010b9871b6f8..7f7fac403742f 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -8,13 +8,13 @@
#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 "llvm/Support/Debug.h"
#include <memory>
@@ -33,7 +33,7 @@ namespace {
class ConvertToEmitCPassInterface {
public:
ConvertToEmitCPassInterface(MLIRContext *context,
- ArrayRef<std::string> filterDialects);
+ ArrayRef<std::string> filterDialects);
virtual ~ConvertToEmitCPassInterface() = default;
/// Get the dependent dialects used by `convert-to-emitc`.
@@ -44,11 +44,11 @@ class ConvertToEmitCPassInterface {
/// 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.
+ /// 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;
@@ -68,7 +68,8 @@ class ConvertToEmitCPassInterface {
/// `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.
+/// 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)
@@ -98,8 +99,8 @@ class LoadDependentDialectExtension : public DialectExtensionBase {
// StaticConvertToEmitC
//===----------------------------------------------------------------------===//
-/// Static implementation of the `convert-to-emitc` pass. This version only looks
-/// at dialect interfaces to configure the conversion process.
+/// 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;
@@ -151,8 +152,7 @@ struct StaticConvertToEmitC : public ConvertToEmitCPassInterface {
/// 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.
-class ConvertToEmitC
- : public impl::ConvertToEmitCBase<ConvertToEmitC> {
+class ConvertToEmitC : public impl::ConvertToEmitCBase<ConvertToEmitC> {
std::shared_ptr<const ConvertToEmitCPassInterface> impl;
public:
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index 4cff06ef951cd..f998b8465eb69 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -39,14 +39,12 @@ struct FuncToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
};
} // namespace
-void mlir::registerConvertFuncToEmitCInterface(
- DialectRegistry ®istry) {
+void mlir::registerConvertFuncToEmitCInterface(DialectRegistry ®istry) {
registry.addExtension(+[](MLIRContext *ctx, func::FuncDialect *dialect) {
dialect->addInterfaces<FuncToEmitCDialectInterface>();
});
}
-
//===----------------------------------------------------------------------===//
// Conversion Patterns
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
index b19ce7bacefac..15b760c9d7925 100644
--- a/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
+++ b/mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp
@@ -40,14 +40,12 @@ struct MemRefToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
};
} // namespace
-void mlir::registerConvertMemRefToEmitCInterface(
- DialectRegistry ®istry) {
+void mlir::registerConvertMemRefToEmitCInterface(DialectRegistry ®istry) {
registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) {
dialect->addInterfaces<MemRefToEmitCDialectInterface>();
});
}
-
//===----------------------------------------------------------------------===//
// Conversion Patterns
//===----------------------------------------------------------------------===//
@@ -212,18 +210,18 @@ void mlir::populateMemRefToEmitCTypeConversion(TypeConverter &typeConverter) {
convertedElementType);
});
- auto materializeAsUnrealizedCast = [](OpBuilder &builder, Type resultType,
- ValueRange inputs,
- Location loc) -> Value {
- if (inputs.size() != 1)
- return Value();
+ auto materializeAsUnrealizedCast = [](OpBuilder &builder, Type resultType,
+ ValueRange inputs,
+ Location loc) -> Value {
+ if (inputs.size() != 1)
+ return Value();
- return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
- .getResult(0);
- };
+ return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
+ .getResult(0);
+ };
- typeConverter.addSourceMaterialization(materializeAsUnrealizedCast);
- typeConverter.addTargetMaterialization(materializeAsUnrealizedCast);
+ typeConverter.addSourceMaterialization(materializeAsUnrealizedCast);
+ typeConverter.addTargetMaterialization(materializeAsUnrealizedCast);
}
void mlir::populateMemRefToEmitCConversionPatterns(
diff --git a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
index 1bbfc8dd6d3ed..1a360507acb3e 100644
--- a/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
+++ b/mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp
@@ -53,8 +53,7 @@ struct SCFToEmitCDialectInterface : public ConvertToEmitCPatternInterface {
};
} // namespace
-void mlir::registerConvertSCFToEmitCInterface(
- DialectRegistry ®istry) {
+void mlir::registerConvertSCFToEmitCInterface(DialectRegistry ®istry) {
registry.addExtension(+[](MLIRContext *ctx, scf::SCFDialect *dialect) {
dialect->addInterfaces<SCFToEmitCDialectInterface>();
});
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 535512c6933e8..0c68086b7cd17 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -1044,7 +1044,9 @@ Type emitc::ArrayType::parse(AsmParser &parser) {
// Check that array is formed from allowed types.
if (!isValidElementType(elementType))
- return parser.emitError(typeLoc, "invalid array element type '") << elementType << "'", Type();
+ return parser.emitError(typeLoc, "invalid array element type '")
+ << elementType << "'",
+ Type();
if (parser.parseGreater())
return Type();
return parser.getChecked<ArrayType>(dimensions, elementType);
diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp
index b4d1cdbab479e..48726db9a3fa3 100644
--- a/mlir/lib/Dialect/SCF/IR/SCF.cpp
+++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
+#include "mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Arith/Utils/Utils.h"
#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
>From c207678550d4530ecfb4315f393770c17dcb3f43 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Sun, 23 Feb 2025 10:10:48 +0100
Subject: [PATCH 09/11] Address review comments
---
.../mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h | 2 +-
mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp | 6 +++---
mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir | 1 -
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
index 6dd1796958118..a8857547fc6e8 100644
--- a/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
+++ b/mlir/include/mlir/Conversion/ConvertToEmitC/ToEmitCInterface.h
@@ -29,7 +29,7 @@ class ConvertToEmitCPatternInterface
/// Hook for derived dialect interface to load the dialects they
/// target. The EmitC dialect is implicitly already loaded, but this
/// method allows to load other intermediate dialects used in the
- /// conversion, or target dialects like NVVM for example.
+ /// conversion.
virtual void loadDependentDialects(MLIRContext *context) const {}
/// Hook for derived dialect interface to provide conversion patterns
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index 7f7fac403742f..606a6ad019ead 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -149,9 +149,9 @@ struct StaticConvertToEmitC : public ConvertToEmitCPassInterface {
// 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.
+/// This is a generic pass to convert to the EmitC dialect. It uses the
+/// `ConvertToEmitCPatternInterface` dialect interface to delegate the injection
+/// of conversion patterns to dialects.
class ConvertToEmitC : public impl::ConvertToEmitCBase<ConvertToEmitC> {
std::shared_ptr<const ConvertToEmitCPassInterface> impl;
diff --git a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
index 7657dd3fb9286..6824a64dda3ef 100644
--- a/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
+++ b/mlir/test/Conversion/FuncToEmitC/func-to-emitc.mlir
@@ -1,7 +1,6 @@
// RUN: mlir-opt -split-input-file -convert-func-to-emitc %s | FileCheck %s
// RUN: mlir-opt -split-input-file -convert-to-emitc="filter-dialects=func" %s | FileCheck %s
-
// CHECK-LABEL: emitc.func @foo()
// CHECK-NEXT: return
func.func @foo() {
>From cd6e5c94ec8fa60969b3b0519a088da127c16ef9 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Tue, 18 Mar 2025 10:17:25 +0100
Subject: [PATCH 10/11] Don't run failure tests with the interface based
conversion pass
---
.../ConvertToEmitC/ConvertToEmitCPass.cpp | 2 +-
.../lib/Conversion/FuncToEmitC/FuncToEmitC.cpp | 4 ++--
.../ArithToEmitC/arith-to-emitc-failed.mlir | 1 -
.../arith-to-emitc-unsupported.mlir | 1 -
mlir/test/Conversion/ConvertToEmitC/func.mlir | 18 ++++++------------
.../MemRefToEmitC/memref-to-emitc-failed.mlir | 1 -
6 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
index 606a6ad019ead..ffa46a9b001e7 100644
--- a/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp
@@ -115,7 +115,7 @@ struct StaticConvertToEmitC : public ConvertToEmitCPassInterface {
auto target = std::make_shared<ConversionTarget>(*context);
auto typeConverter = std::make_shared<TypeConverter>();
- // Add fallback identity converison
+ // Add fallback identity converison.
typeConverter->addConversion([](Type type) -> std::optional<Type> {
if (emitc::isSupportedEmitCType(type))
return type;
diff --git a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
index f998b8465eb69..3dbb537fb82c1 100644
--- a/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
+++ b/mlir/lib/Conversion/FuncToEmitC/FuncToEmitC.cpp
@@ -88,7 +88,7 @@ class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
for (const auto &argType : enumerate(fnType.getInputs())) {
auto convertedType = getTypeConverter()->convertType(argType.value());
if (!convertedType)
- return failure();
+ return rewriter.notifyMatchFailure(funcOp, "argument type conversion failed");
signatureConverter.addInputs(argType.index(), convertedType);
}
@@ -96,7 +96,7 @@ class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
if (fnType.getNumResults() == 1) {
resultType = getTypeConverter()->convertType(fnType.getResult(0));
if (!resultType)
- return failure();
+ return rewriter.notifyMatchFailure(funcOp, "result type conversion failed");
}
// Create the converted `emitc.func` op.
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
index 15c9076c6c997..30abd81f3d447 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-failed.mlir
@@ -1,5 +1,4 @@
// RUN: mlir-opt -convert-arith-to-emitc %s -split-input-file -verify-diagnostics
-// RUN: mlir-opt -convert-to-emitc="filter-dialects=arith" -split-input-file -verify-diagnostics
func.func @bool(%arg0: i1, %arg1: i1) {
// expected-error at +1 {{failed to legalize operation 'arith.addi'}}
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
index 083e6bac40ab1..9850f336b5ad6 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc-unsupported.mlir
@@ -1,5 +1,4 @@
// RUN: mlir-opt -split-input-file -convert-arith-to-emitc -verify-diagnostics %s
-// RUN: mlir-opt -split-input-file -convert-to-emitc="filter-dialects=arith" -verify-diagnostics %s
func.func @arith_cast_tensor(%arg0: tensor<5xf32>) -> tensor<5xi32> {
// expected-error @+1 {{failed to legalize operation 'arith.fptosi'}}
diff --git a/mlir/test/Conversion/ConvertToEmitC/func.mlir b/mlir/test/Conversion/ConvertToEmitC/func.mlir
index 40b898919a7c2..4f2518401581f 100644
--- a/mlir/test/Conversion/ConvertToEmitC/func.mlir
+++ b/mlir/test/Conversion/ConvertToEmitC/func.mlir
@@ -1,19 +1,13 @@
// RUN: mlir-opt -convert-to-emitc %s | FileCheck %s
-// CHECK-LABEL emitc.func @int(%[[ARG:.*]]: i32)
-func.func @int(%arg0: i32) {
+// CHECK-LABEL emitc.func @int(%[[ARG:.*]]: i32) -> i32
+func.func @int(%arg0: i32) -> i32 {
// CHECK: return
- return
+ return %arg0 : i32
}
-// CHECK-LABEL emitc.func @index(%[[ARG:.*]]: !emitc.size_t)
-func.func @index(%arg0: index) {
+// CHECK-LABEL emitc.func @index(%[[ARG:.*]]: !emitc.size_t) -> !emitc.size_t
+func.func @index(%arg0: index) -> index {
// CHECK: return
- return
-}
-
-// CHECK-LABEL emitc.func @memref(%[[ARG:.*]]: !emitc.array<1xf32>)
-func.func @memref(%arg0: memref<1xf32>) {
- // CHECK: return
- return
+ return %arg0 : index
}
diff --git a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
index e6eba5b223efa..fda01974d3fc8 100644
--- a/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
+++ b/mlir/test/Conversion/MemRefToEmitC/memref-to-emitc-failed.mlir
@@ -1,5 +1,4 @@
// RUN: mlir-opt -convert-memref-to-emitc %s -split-input-file -verify-diagnostics
-// RUN: mlir-opt -convert-to-emitc="filter-dialects=memref" %s -split-input-file -verify-diagnostics
func.func @memref_op(%arg0 : memref<2x4xf32>) {
// expected-error at +1 {{failed to legalize operation 'memref.copy'}}
>From 452c8a85141588a28438ec8d81e12619eb0ff2e9 Mon Sep 17 00:00:00 2001
From: Simon Camphausen <simoncamphausen at gmail.com>
Date: Fri, 28 Mar 2025 15:39:29 +0100
Subject: [PATCH 11/11] Update pass description
---
mlir/include/mlir/Conversion/Passes.td | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index b0149a6428a27..ed88ada9778d2 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -17,9 +17,11 @@ include "mlir/Dialect/Vector/Transforms/VectorTransformsBase.td"
//===----------------------------------------------------------------------===//
def ConvertToEmitC : Pass<"convert-to-emitc"> {
- let summary = "Convert to EmitC dialect";
+ let summary = "Convert to EmitC dialect via dialect interfaces";
let description = [{
- This is a generic pass to convert to the EmitC dialect.
+ This is a generic pass to convert to the EmitC dialect, it uses the
+ `ConvertToEmitCPatternInterface` dialect interface to delegate to dialects
+ the injection of conversion patterns.
}];
let options = [
ListOption<"filterDialects", "filter-dialects", "std::string",
More information about the Mlir-commits
mailing list