[llvm] [mlir] [mlir][emitc] Arith to EmitC conversion: constants (PR #83798)

Tina Jung via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 7 07:42:10 PST 2024


https://github.com/TinaAMD updated https://github.com/llvm/llvm-project/pull/83798

>From a595b17be7516f526f5954e901a1e045087c90e6 Mon Sep 17 00:00:00 2001
From: Tina Jung <tina.maria.jung at xilinx.com>
Date: Mon, 4 Mar 2024 08:52:50 +0000
Subject: [PATCH 1/3] [mlir][emitc] Arith to EmitC conversion: constants

* Add a conversion from `arith.constant` to `emitc.constant`.
* Drop the translation for `arith.constant`s.
---
 mlir/docs/Dialects/emitc.md                   |  2 -
 .../Conversion/ArithToEmitC/ArithToEmitC.cpp  | 16 ++++++++
 .../ArithToEmitC/ArithToEmitCPass.cpp         |  1 -
 mlir/lib/Target/Cpp/CMakeLists.txt            |  1 -
 mlir/lib/Target/Cpp/TranslateRegistration.cpp |  4 +-
 mlir/lib/Target/Cpp/TranslateToCpp.cpp        | 12 ------
 .../ArithToEmitC/arith-to-emitc.mlir          | 24 ++++++++++-
 mlir/test/Target/Cpp/call.mlir                |  2 +-
 mlir/test/Target/Cpp/for.mlir                 | 10 ++---
 mlir/test/Target/Cpp/if.mlir                  |  2 +-
 mlir/test/Target/Cpp/stdops.mlir              | 41 ++-----------------
 11 files changed, 50 insertions(+), 65 deletions(-)

diff --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md
index b227a8c4599a8f..1158bc683af060 100644
--- a/mlir/docs/Dialects/emitc.md
+++ b/mlir/docs/Dialects/emitc.md
@@ -30,5 +30,3 @@ translating the following operations:
     *   `func.call`
     *   `func.func`
     *   `func.return`
-*   'arith' Dialect
-    *   `arith.constant`
diff --git a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
index 6909534d4790fe..40dce001a3b224 100644
--- a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
+++ b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitC.cpp
@@ -24,6 +24,21 @@ using namespace mlir;
 //===----------------------------------------------------------------------===//
 
 namespace {
+class ArithConstantOpConversionPattern
+    : public OpConversionPattern<arith::ConstantOp> {
+public:
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(arith::ConstantOp arithConst,
+                  arith::ConstantOp::Adaptor adaptor,
+                  ConversionPatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<emitc::ConstantOp>(
+        arithConst, arithConst.getType(), adaptor.getValue());
+    return success();
+  }
+};
+
 template <typename ArithOp, typename EmitCOp>
 class ArithOpConversion final : public OpConversionPattern<ArithOp> {
 public:
@@ -51,6 +66,7 @@ void mlir::populateArithToEmitCPatterns(TypeConverter &typeConverter,
 
   // clang-format off
   patterns.add<
+    ArithConstantOpConversionPattern,
     ArithOpConversion<arith::AddFOp, emitc::AddOp>,
     ArithOpConversion<arith::DivFOp, emitc::DivOp>,
     ArithOpConversion<arith::MulFOp, emitc::MulOp>,
diff --git a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitCPass.cpp b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitCPass.cpp
index b377c063a7aa0e..45a088ed144f17 100644
--- a/mlir/lib/Conversion/ArithToEmitC/ArithToEmitCPass.cpp
+++ b/mlir/lib/Conversion/ArithToEmitC/ArithToEmitCPass.cpp
@@ -38,7 +38,6 @@ void ConvertArithToEmitC::runOnOperation() {
 
   target.addLegalDialect<emitc::EmitCDialect>();
   target.addIllegalDialect<arith::ArithDialect>();
-  target.addLegalOp<arith::ConstantOp>();
 
   RewritePatternSet patterns(&getContext());
 
diff --git a/mlir/lib/Target/Cpp/CMakeLists.txt b/mlir/lib/Target/Cpp/CMakeLists.txt
index 5521e7909a8ab8..d8f372cf162453 100644
--- a/mlir/lib/Target/Cpp/CMakeLists.txt
+++ b/mlir/lib/Target/Cpp/CMakeLists.txt
@@ -6,7 +6,6 @@ add_mlir_translation_library(MLIRTargetCpp
   ${EMITC_MAIN_INCLUDE_DIR}/emitc/Target/Cpp
 
   LINK_LIBS PUBLIC
-  MLIRArithDialect
   MLIRControlFlowDialect
   MLIREmitCDialect
   MLIRFuncDialect
diff --git a/mlir/lib/Target/Cpp/TranslateRegistration.cpp b/mlir/lib/Target/Cpp/TranslateRegistration.cpp
index b486e5429ea6a8..4104b177d7d9af 100644
--- a/mlir/lib/Target/Cpp/TranslateRegistration.cpp
+++ b/mlir/lib/Target/Cpp/TranslateRegistration.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h"
 #include "mlir/Dialect/EmitC/IR/EmitC.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -41,8 +40,7 @@ void registerToCppTranslation() {
       },
       [](DialectRegistry &registry) {
         // clang-format off
-        registry.insert<arith::ArithDialect,
-                        cf::ControlFlowDialect,
+        registry.insert<cf::ControlFlowDialect,
                         emitc::EmitCDialect,
                         func::FuncDialect,
                         math::MathDialect,
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 4bc707c43ad92f..7268d41738eff3 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
 #include "mlir/Dialect/EmitC/IR/EmitC.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -323,14 +322,6 @@ static LogicalResult printOperation(CppEmitter &emitter,
   return printConstantOp(emitter, operation, value);
 }
 
-static LogicalResult printOperation(CppEmitter &emitter,
-                                    arith::ConstantOp constantOp) {
-  Operation *operation = constantOp.getOperation();
-  Attribute value = constantOp.getValue();
-
-  return printConstantOp(emitter, operation, value);
-}
-
 static LogicalResult printOperation(CppEmitter &emitter,
                                     emitc::AssignOp assignOp) {
   auto variableOp = cast<emitc::VariableOp>(assignOp.getVar().getDefiningOp());
@@ -1366,9 +1357,6 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
           // Func ops.
           .Case<func::CallOp, func::FuncOp, func::ReturnOp>(
               [&](auto op) { return printOperation(*this, op); })
-          // Arithmetic ops.
-          .Case<arith::ConstantOp>(
-              [&](auto op) { return printOperation(*this, op); })
           .Case<emitc::LiteralOp>([&](auto op) { return success(); })
           .Default([&](Operation *) {
             return op.emitOpError("unable to find printer for op");
diff --git a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
index 6a56474a5c48b2..2886810c01e917 100644
--- a/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
+++ b/mlir/test/Conversion/ArithToEmitC/arith-to-emitc.mlir
@@ -1,4 +1,26 @@
-// RUN: mlir-opt -convert-arith-to-emitc %s | FileCheck %s
+// RUN: mlir-opt -split-input-file -convert-arith-to-emitc %s | FileCheck %s
+
+// CHECK-LABEL: arith_constants
+func.func @arith_constants() {
+  // CHECK: emitc.constant
+  // CHECK-SAME: value = 0 : index
+  %c_index = arith.constant 0 : index
+  // CHECK: emitc.constant
+  // CHECK-SAME: value = 0 : i32
+  %c_signless_int_32 = arith.constant 0 : i32
+  // CHECK: emitc.constant
+  // CHECK-SAME: value = 0.{{0+}}e+00 : f32
+  %c_float_32 = arith.constant 0.0 : f32
+  // CHECK: emitc.constant
+  // CHECK-SAME: value = dense<0> : tensor<i32>
+  %c_tensor_single_value = arith.constant dense<0> : tensor<i32>
+  // CHECK: emitc.constant
+  // CHECK-SAME: value{{.*}}[1, 2], [-3, 9], [0, 0], [2, -1]{{.*}}tensor<4x2xi64>
+  %c_tensor_value = arith.constant dense<[[1, 2], [-3, 9], [0, 0], [2, -1]]> : tensor<4x2xi64>
+  return
+}
+
+// -----
 
 func.func @arith_ops(%arg0: f32, %arg1: f32) {
   // CHECK: [[V0:[^ ]*]] = emitc.add %arg0, %arg1 : (f32, f32) -> f32
diff --git a/mlir/test/Target/Cpp/call.mlir b/mlir/test/Target/Cpp/call.mlir
index 2bcdc87205184f..e3ac392f30b625 100644
--- a/mlir/test/Target/Cpp/call.mlir
+++ b/mlir/test/Target/Cpp/call.mlir
@@ -18,7 +18,7 @@ func.func @emitc_call_opaque() {
 
 
 func.func @emitc_call_opaque_two_results() {
-  %0 = arith.constant 0 : index
+  %0 = "emitc.constant"() <{value = 0 : index}> : () -> index
   %1:2 = emitc.call_opaque "two_results" () : () -> (i32, i32)
   return
 }
diff --git a/mlir/test/Target/Cpp/for.mlir b/mlir/test/Target/Cpp/for.mlir
index b9bd3d98465a23..5225f3ddaff259 100644
--- a/mlir/test/Target/Cpp/for.mlir
+++ b/mlir/test/Target/Cpp/for.mlir
@@ -33,12 +33,12 @@ func.func @test_for(%arg0 : index, %arg1 : index, %arg2 : index) {
 // CPP-DECLTOP-NEXT: return;
 
 func.func @test_for_yield() {
-  %start = arith.constant 0 : index
-  %stop = arith.constant 10 : index
-  %step = arith.constant 1 : index
+  %start = "emitc.constant"() <{value = 0 : index}> : () -> index
+  %stop = "emitc.constant"() <{value = 10 : index}> : () -> index
+  %step = "emitc.constant"() <{value = 1 : index}> : () -> index
 
-  %s0 = arith.constant 0 : i32
-  %p0 = arith.constant 1.0 : f32
+  %s0 = "emitc.constant"() <{value = 0 : i32}> : () -> i32
+  %p0 = "emitc.constant"() <{value = 1.0 : f32}> : () -> f32
 
   %0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32
   %1 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f32
diff --git a/mlir/test/Target/Cpp/if.mlir b/mlir/test/Target/Cpp/if.mlir
index 743f8ad396882d..7b0e2da85d0eb2 100644
--- a/mlir/test/Target/Cpp/if.mlir
+++ b/mlir/test/Target/Cpp/if.mlir
@@ -49,7 +49,7 @@ func.func @test_if_else(%arg0: i1, %arg1: f32) {
 
 
 func.func @test_if_yield(%arg0: i1, %arg1: f32) {
-  %0 = arith.constant 0 : i8
+  %0 = "emitc.constant"() <{value = 0 : i8}> : () -> i8
   %x = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> i32
   %y = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> f64
   emitc.if %arg0 {
diff --git a/mlir/test/Target/Cpp/stdops.mlir b/mlir/test/Target/Cpp/stdops.mlir
index 0723188a62c68e..cc6bdbe3769847 100644
--- a/mlir/test/Target/Cpp/stdops.mlir
+++ b/mlir/test/Target/Cpp/stdops.mlir
@@ -1,37 +1,6 @@
 // RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s -check-prefix=CPP-DEFAULT
 // RUN: mlir-translate -mlir-to-cpp -declare-variables-at-top %s | FileCheck %s -check-prefix=CPP-DECLTOP
 
-func.func @std_constant() {
-  %c0 = arith.constant 0 : i32
-  %c1 = arith.constant 2 : index
-  %c2 = arith.constant 2.0 : f32
-  %c3 = arith.constant dense<0> : tensor<i32>
-  %c4 = arith.constant dense<[0, 1]> : tensor<2xindex>
-  %c5 = arith.constant dense<[[0.0, 1.0], [2.0, 3.0]]> : tensor<2x2xf32>
-  return
-}
-// CPP-DEFAULT: void std_constant() {
-// CPP-DEFAULT-NEXT: int32_t [[V0:[^ ]*]] = 0;
-// CPP-DEFAULT-NEXT: size_t [[V1:[^ ]*]] = 2;
-// CPP-DEFAULT-NEXT: float [[V2:[^ ]*]] = (float)2.000000000e+00;
-// CPP-DEFAULT-NEXT: Tensor<int32_t> [[V3:[^ ]*]] = {0};
-// CPP-DEFAULT-NEXT: Tensor<size_t, 2> [[V4:[^ ]*]] = {0, 1};
-// CPP-DEFAULT-NEXT: Tensor<float, 2, 2> [[V5:[^ ]*]] = {(float)0.0e+00, (float)1.000000000e+00, (float)2.000000000e+00, (float)3.000000000e+00};
-
-// CPP-DECLTOP: void std_constant() {
-// CPP-DECLTOP-NEXT: int32_t [[V0:[^ ]*]];
-// CPP-DECLTOP-NEXT: size_t [[V1:[^ ]*]];
-// CPP-DECLTOP-NEXT: float [[V2:[^ ]*]];
-// CPP-DECLTOP-NEXT: Tensor<int32_t> [[V3:[^ ]*]];
-// CPP-DECLTOP-NEXT: Tensor<size_t, 2> [[V4:[^ ]*]];
-// CPP-DECLTOP-NEXT: Tensor<float, 2, 2> [[V5:[^ ]*]];
-// CPP-DECLTOP-NEXT: [[V0]] = 0;
-// CPP-DECLTOP-NEXT: [[V1]] = 2;
-// CPP-DECLTOP-NEXT: [[V2]] = (float)2.000000000e+00;
-// CPP-DECLTOP-NEXT: [[V3]] = {0};
-// CPP-DECLTOP-NEXT: [[V4]] = {0, 1};
-// CPP-DECLTOP-NEXT: [[V5]] = {(float)0.0e+00, (float)1.000000000e+00, (float)2.000000000e+00, (float)3.000000000e+00};
-
 func.func @std_call() {
   %0 = call @one_result () : () -> i32
   %1 = call @one_result () : () -> i32
@@ -49,13 +18,11 @@ func.func @std_call() {
 
 
 func.func @std_call_two_results() {
-  %c = arith.constant 0 : i8
   %0:2 = call @two_results () : () -> (i32, f32)
   %1:2 = call @two_results () : () -> (i32, f32)
   return
 }
 // CPP-DEFAULT: void std_call_two_results() {
-// CPP-DEFAULT-NEXT: int8_t  [[V0:[^ ]*]] = 0;
 // CPP-DEFAULT-NEXT: int32_t [[V1:[^ ]*]];
 // CPP-DEFAULT-NEXT: float [[V2:[^ ]*]];
 // CPP-DEFAULT-NEXT: std::tie([[V1]], [[V2]]) = two_results();
@@ -64,18 +31,16 @@ func.func @std_call_two_results() {
 // CPP-DEFAULT-NEXT: std::tie([[V3]], [[V4]]) = two_results();
 
 // CPP-DECLTOP: void std_call_two_results() {
-// CPP-DECLTOP-NEXT: int8_t [[V0:[^ ]*]];
 // CPP-DECLTOP-NEXT: int32_t [[V1:[^ ]*]];
 // CPP-DECLTOP-NEXT: float [[V2:[^ ]*]];
 // CPP-DECLTOP-NEXT: int32_t [[V3:[^ ]*]];
 // CPP-DECLTOP-NEXT: float [[V4:[^ ]*]];
-// CPP-DECLTOP-NEXT: [[V0]] = 0;
 // CPP-DECLTOP-NEXT: std::tie([[V1]], [[V2]]) = two_results();
 // CPP-DECLTOP-NEXT: std::tie([[V3]], [[V4]]) = two_results();
 
 
 func.func @one_result() -> i32 {
-  %0 = arith.constant 0 : i32
+  %0 = "emitc.constant"() <{value = 0 : i32}> : () -> i32
   return %0 : i32
 }
 // CPP-DEFAULT: int32_t one_result() {
@@ -89,8 +54,8 @@ func.func @one_result() -> i32 {
 
 
 func.func @two_results() -> (i32, f32) {
-  %0 = arith.constant 0 : i32
-  %1 = arith.constant 1.0 : f32
+  %0 = "emitc.constant"() <{value = 0 : i32}> : () -> i32
+  %1 = "emitc.constant"() <{value = 1.0 : f32}> : () -> f32
   return %0, %1 : i32, f32
 }
 // CPP-DEFAULT: std::tuple<int32_t, float> two_results() {

>From b357a21718856d918bcd1ca26b0bc3b75e704518 Mon Sep 17 00:00:00 2001
From: Tina Jung <tina.maria.jung at xilinx.com>
Date: Thu, 7 Mar 2024 15:13:13 +0000
Subject: [PATCH 2/3] Drop arith dependency in bazel build

---
 utils/bazel/llvm-project-overlay/mlir/BUILD.bazel | 1 -
 1 file changed, 1 deletion(-)

diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 9d6ca4ed932fe4..9ff54c70530a57 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -1768,7 +1768,6 @@ cc_library(
     ]),
     hdrs = glob(["include/mlir/Target/Cpp/*.h"]),
     deps = [
-        ":ArithDialect",
         ":ControlFlowDialect",
         ":EmitCDialect",
         ":FuncDialect",

>From cc76a04941c981bec2f7c929881e97186b24e02a Mon Sep 17 00:00:00 2001
From: Tina Jung <tina.maria.jung at xilinx.com>
Date: Thu, 7 Mar 2024 15:38:25 +0000
Subject: [PATCH 3/3] Move tests for float/tensor/index constants

Add tests for float/tensor/index types to the `emitc.constant` tests (they were previously tested on `arith.constant`s).
---
 mlir/test/Target/Cpp/const.mlir | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/mlir/test/Target/Cpp/const.mlir b/mlir/test/Target/Cpp/const.mlir
index 28a547909a0ac6..524d564b3b943e 100644
--- a/mlir/test/Target/Cpp/const.mlir
+++ b/mlir/test/Target/Cpp/const.mlir
@@ -8,6 +8,11 @@ func.func @emitc_constant() {
   %c3 = "emitc.constant"(){value = -1 : si8} : () -> si8
   %c4 = "emitc.constant"(){value = 255 : ui8} : () -> ui8
   %c5 = "emitc.constant"(){value = #emitc.opaque<"CHAR_MIN">} : () -> !emitc.opaque<"char">
+  %c6 = "emitc.constant"(){value = 2 : index} : () -> index
+  %c7 = "emitc.constant"(){value = 2.0 : f32} : () -> f32
+  %c8 = "emitc.constant"(){value = dense<0> : tensor<i32>} : () -> tensor<i32>
+  %c9 = "emitc.constant"(){value = dense<[0, 1]> : tensor<2xindex>} : () -> tensor<2xindex>
+  %c10 = "emitc.constant"(){value = dense<[[0.0, 1.0], [2.0, 3.0]]> : tensor<2x2xf32>} : () -> tensor<2x2xf32>
   return
 }
 // CPP-DEFAULT: void emitc_constant() {
@@ -17,6 +22,11 @@ func.func @emitc_constant() {
 // CPP-DEFAULT-NEXT: int8_t [[V3:[^ ]*]] = -1;
 // CPP-DEFAULT-NEXT: uint8_t [[V4:[^ ]*]] = 255;
 // CPP-DEFAULT-NEXT: char [[V5:[^ ]*]] = CHAR_MIN;
+// CPP-DEFAULT-NEXT: size_t [[V6:[^ ]*]] = 2;
+// CPP-DEFAULT-NEXT: float [[V7:[^ ]*]] = (float)2.000000000e+00;
+// CPP-DEFAULT-NEXT: Tensor<int32_t> [[V8:[^ ]*]] = {0};
+// CPP-DEFAULT-NEXT: Tensor<size_t, 2> [[V9:[^ ]*]] = {0, 1};
+// CPP-DEFAULT-NEXT: Tensor<float, 2, 2> [[V10:[^ ]*]] = {(float)0.0e+00, (float)1.000000000e+00, (float)2.000000000e+00, (float)3.000000000e+00};
 
 // CPP-DECLTOP: void emitc_constant() {
 // CPP-DECLTOP-NEXT: int32_t [[V0:[^ ]*]];
@@ -25,9 +35,19 @@ func.func @emitc_constant() {
 // CPP-DECLTOP-NEXT: int8_t [[V3:[^ ]*]];
 // CPP-DECLTOP-NEXT: uint8_t [[V4:[^ ]*]];
 // CPP-DECLTOP-NEXT: char [[V5:[^ ]*]];
+// CPP-DECLTOP-NEXT: size_t [[V6:[^ ]*]];
+// CPP-DECLTOP-NEXT: float [[V7:[^ ]*]];
+// CPP-DECLTOP-NEXT: Tensor<int32_t> [[V8:[^ ]*]];
+// CPP-DECLTOP-NEXT: Tensor<size_t, 2> [[V9:[^ ]*]];
+// CPP-DECLTOP-NEXT: Tensor<float, 2, 2> [[V10:[^ ]*]];
 // CPP-DECLTOP-NEXT: [[V0]] = INT_MAX;
 // CPP-DECLTOP-NEXT: [[V1]] = 42;
 // CPP-DECLTOP-NEXT: [[V2]] = -1;
 // CPP-DECLTOP-NEXT: [[V3]] = -1;
 // CPP-DECLTOP-NEXT: [[V4]] = 255;
 // CPP-DECLTOP-NEXT: [[V5]] = CHAR_MIN;
+// CPP-DECLTOP-NEXT: [[V6]] = 2;
+// CPP-DECLTOP-NEXT: [[V7]] = (float)2.000000000e+00;
+// CPP-DECLTOP-NEXT: [[V8]] = {0};
+// CPP-DECLTOP-NEXT: [[V9]] = {0, 1};
+// CPP-DECLTOP-NEXT: [[V10]] = {(float)0.0e+00, (float)1.000000000e+00, (float)2.000000000e+00, (float)3.000000000e+00};



More information about the llvm-commits mailing list