[Mlir-commits] [mlir] [mlir][EmitC] Add pass that combines all available emitc conversions (PR #117549)

Simon Camphausen llvmlistbot at llvm.org
Tue Nov 26 02:42:41 PST 2024


https://github.com/simon-camp updated https://github.com/llvm/llvm-project/pull/117549

>From 08f51a61855cc5f35342d5e5f5f28e4371b214ba 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 1/4] [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 00000000000000..e6244276e6e680
--- /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 2ab32836c80b1c..c9698a9985aca4 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/ConvertToSPIRV/ConvertToSPIRVPass.h"
 #include "mlir/Conversion/FuncToEmitC/FuncToEmitCPass.h"
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 4d272ba219c6f1..167b78a683501a 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -12,6 +12,20 @@
 include "mlir/Pass/PassBase.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 6651d87162257f..bfee78a9624cb6 100644
--- a/mlir/lib/Conversion/CMakeLists.txt
+++ b/mlir/lib/Conversion/CMakeLists.txt
@@ -18,6 +18,7 @@ add_subdirectory(ComplexToStandard)
 add_subdirectory(ControlFlowToLLVM)
 add_subdirectory(ControlFlowToSCF)
 add_subdirectory(ControlFlowToSPIRV)
+add_subdirectory(ConvertToEmitC)
 add_subdirectory(ConvertToLLVM)
 add_subdirectory(ConvertToSPIRV)
 add_subdirectory(FuncToEmitC)
diff --git a/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt b/mlir/lib/Conversion/ConvertToEmitC/CMakeLists.txt
new file mode 100644
index 00000000000000..3846f5a279a8a2
--- /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 00000000000000..aeadb63e5faa2d
--- /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 00000000000000..40b898919a7c22
--- /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 00000000000000..4a7466bd04ba8b
--- /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 033713ebe4e1ff81cb940defe5384257a35e3978 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 2/4] 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 aeadb63e5faa2d..e176f93e3ebd5f 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 5e19b326da784f3d5d3b0221989c8cd1910a6623 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 3/4] 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 00000000000000..47a8d694ada145
--- /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 e6244276e6e680..5986136a68d451 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 167b78a683501a..be8391ee96ef4d 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -16,7 +16,7 @@ include "mlir/Pass/PassBase.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 3846f5a279a8a2..b036b050263bc6 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 00000000000000..2781f4c675de39
--- /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 e176f93e3ebd5f..230cdc30046329 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 2186c9809ce3924febe731f69e3c9d61d21878fe 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 4/4] 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 5c7f87e470306a..10b1a4cb765866 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 2781f4c675de39..4a9a5037e982a6 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 230cdc30046329..f00c4e89d29cfe 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 53b79839da04c3..6622b19972c00f 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 0b97f2641ad08d..5b59e7675d7c6c 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 00000000000000..a5a20b57d4997a
--- /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



More information about the Mlir-commits mailing list