[Mlir-commits] [mlir] [mlir][emitC] Add support to emitter for `classop`, `fieldop` and `getfieldop` (PR #145605)
Mircea Trofin
llvmlistbot at llvm.org
Thu Jun 26 10:13:09 PDT 2025
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/145605
>From 0ab534fc3722b3244df74d0eacf8476087df81bd Mon Sep 17 00:00:00 2001
From: Jaddyen <ajaden at google.com>
Date: Tue, 24 Jun 2025 21:54:11 +0000
Subject: [PATCH 1/4] add trnalsation for classops, fieldops and getfieldops
---
mlir/lib/Target/Cpp/TranslateToCpp.cpp | 58 +++++++++++++++++++-
mlir/test/mlir-translate/emitc_classops.mlir | 31 +++++++++++
2 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 mlir/test/mlir-translate/emitc_classops.mlir
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 067a0470b14e4..9cd30eae8d36d 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -997,6 +997,61 @@ static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) {
return success();
}
+static LogicalResult printOperation(CppEmitter &emitter, ClassOp classOp) {
+ CppEmitter::Scope classScope(emitter);
+ raw_indented_ostream &os = emitter.ostream();
+ os << "class " << classOp.getSymName() << " final {\n";
+ os << "public:\n\n";
+
+ os.indent();
+ os << "const std::map<std::string, char*> _buffer_map {\n";
+ for (Operation &op : classOp) {
+ if (auto fieldOp = dyn_cast<FieldOp>(op))
+ os << " { \"" << fieldOp.getSymName() << "\", reinterpret_cast<char*>(&"
+ << fieldOp.getAttrs() << ") },\n";
+ }
+ os << "};\n";
+
+ os << "char* getBufferForName(const std::string& name) const {\n";
+ os << " auto it = _buffer_map.find(name);\n";
+ os << " return (it == _buffer_map.end()) ? nullptr : it->second;\n";
+ os << "}\n\n";
+ for (Operation &op : classOp) {
+ if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
+ return failure();
+ }
+
+ os.unindent();
+ os << "};";
+ return success();
+}
+
+static LogicalResult printOperation(CppEmitter &emitter, FieldOp fieldOp) {
+ raw_ostream &os = emitter.ostream();
+ if (failed(emitter.emitType(fieldOp->getLoc(), fieldOp.getType())))
+ return failure();
+ os << " " << fieldOp.getSymName() << ";";
+ return success();
+}
+
+static LogicalResult printOperation(CppEmitter &emitter,
+ GetFieldOp getFieldOp) {
+ raw_indented_ostream &os = emitter.ostream();
+ Location loc = getFieldOp->getLoc();
+
+ if (getFieldOp->getNumResults() > 0) {
+ Value result = getFieldOp->getResult(0);
+ if (failed(emitter.emitType(loc, result.getType())))
+ return failure();
+ os << " ";
+ if (failed(emitter.emitOperand(result)))
+ return failure();
+ os << " = ";
+ }
+ os << getFieldOp.getFieldName().str();
+ return success();
+}
+
static LogicalResult printOperation(CppEmitter &emitter, FileOp file) {
if (!emitter.shouldEmitFile(file))
return success();
@@ -1612,7 +1667,8 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
emitc::LoadOp, emitc::LogicalAndOp, emitc::LogicalNotOp,
emitc::LogicalOrOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
emitc::SubOp, emitc::SwitchOp, emitc::UnaryMinusOp,
- emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp>(
+ emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp,
+ emitc::ClassOp, emitc::FieldOp, emitc::GetFieldOp>(
[&](auto op) { return printOperation(*this, op); })
// Func ops.
diff --git a/mlir/test/mlir-translate/emitc_classops.mlir b/mlir/test/mlir-translate/emitc_classops.mlir
new file mode 100644
index 0000000000000..339eaaeb5d7cd
--- /dev/null
+++ b/mlir/test/mlir-translate/emitc_classops.mlir
@@ -0,0 +1,31 @@
+// RUN: mlir-translate --mlir-to-cpp %s | FileCheck %s
+
+emitc.class @modelClass {
+ emitc.field @input_tensor : !emitc.array<1xf32>
+ emitc.func @execute() {
+ %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
+ %1 = get_field @input_tensor : !emitc.array<1xf32>
+ %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+ return
+ }
+}
+
+// CHECK: class modelClass final {
+// CHECK-NEXT: public:
+// CHECK-EMPTY:
+// CHECK-NEXT: const std::map<std::string, char*> _buffer_map {
+// CHECK-NEXT: { "input_tensor", reinterpret_cast<char*>(&None) },
+// CHECK-NEXT: };
+// CHECK-NEXT: char* getBufferForName(const std::string& name) const {
+// CHECK-NEXT: auto it = _buffer_map.find(name);
+// CHECK-NEXT: return (it == _buffer_map.end()) ? nullptr : it->second;
+// CHECK-NEXT: }
+// CHECK-EMPTY:
+// CHECK-NEXT: float[1] input_tensor;
+// CHECK-NEXT: void execute() {
+// CHECK-NEXT: size_t v1 = 0;
+// CHECK-NEXT: float[1] v2 = input_tensor;
+// CHECK-NEXT: return;
+// CHECK-NEXT: }
+// CHECK-EMPTY:
+// CHECK-NEXT: };
>From 0d0aeb301b5182402f31eb9c852708697923219c Mon Sep 17 00:00:00 2001
From: Jaddyen <ajaden at google.com>
Date: Tue, 24 Jun 2025 22:10:36 +0000
Subject: [PATCH 2/4] Added arg to test
---
mlir/test/mlir-translate/emitc_classops.mlir | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/mlir/test/mlir-translate/emitc_classops.mlir b/mlir/test/mlir-translate/emitc_classops.mlir
index 339eaaeb5d7cd..3232954f1149a 100644
--- a/mlir/test/mlir-translate/emitc_classops.mlir
+++ b/mlir/test/mlir-translate/emitc_classops.mlir
@@ -2,10 +2,12 @@
emitc.class @modelClass {
emitc.field @input_tensor : !emitc.array<1xf32>
+ emitc.field @some_feature : !emitc.array<1xf32> {emitc.opaque = ["some_feature"]}
emitc.func @execute() {
%0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
%1 = get_field @input_tensor : !emitc.array<1xf32>
- %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
+ %2 = get_field @some_feature : !emitc.array<1xf32>
+ %3 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
return
}
}
@@ -15,6 +17,7 @@ emitc.class @modelClass {
// CHECK-EMPTY:
// CHECK-NEXT: const std::map<std::string, char*> _buffer_map {
// CHECK-NEXT: { "input_tensor", reinterpret_cast<char*>(&None) },
+// CHECK-NEXT: { "some_feature", reinterpret_cast<char*>(&{emitc.opaque = ["some_feature"]}) },
// CHECK-NEXT: };
// CHECK-NEXT: char* getBufferForName(const std::string& name) const {
// CHECK-NEXT: auto it = _buffer_map.find(name);
@@ -22,9 +25,11 @@ emitc.class @modelClass {
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: float[1] input_tensor;
+// CHECK-NEXT: float[1] some_feature;
// CHECK-NEXT: void execute() {
// CHECK-NEXT: size_t v1 = 0;
// CHECK-NEXT: float[1] v2 = input_tensor;
+// CHECK-NEXT: float[1] v3 = some_feature;
// CHECK-NEXT: return;
// CHECK-NEXT: }
// CHECK-EMPTY:
>From 812d4783c239963eac96c9934e28ef4d782b7f3d Mon Sep 17 00:00:00 2001
From: Jaddyen <ajaden at google.com>
Date: Wed, 25 Jun 2025 20:48:34 +0000
Subject: [PATCH 3/4] Simplify the classop translation
---
mlir/lib/Target/Cpp/TranslateToCpp.cpp | 38 ++++++++------------
mlir/test/mlir-translate/emitc_classops.mlir | 28 +++++----------
2 files changed, 23 insertions(+), 43 deletions(-)
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 9cd30eae8d36d..f57c47d6b2fa4 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -9,6 +9,7 @@
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
@@ -1000,22 +1001,10 @@ static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) {
static LogicalResult printOperation(CppEmitter &emitter, ClassOp classOp) {
CppEmitter::Scope classScope(emitter);
raw_indented_ostream &os = emitter.ostream();
- os << "class " << classOp.getSymName() << " final {\n";
- os << "public:\n\n";
-
+ os << "class " << classOp.getSymName() << " {\n";
+ os << "public:\n";
os.indent();
- os << "const std::map<std::string, char*> _buffer_map {\n";
- for (Operation &op : classOp) {
- if (auto fieldOp = dyn_cast<FieldOp>(op))
- os << " { \"" << fieldOp.getSymName() << "\", reinterpret_cast<char*>(&"
- << fieldOp.getAttrs() << ") },\n";
- }
- os << "};\n";
-
- os << "char* getBufferForName(const std::string& name) const {\n";
- os << " auto it = _buffer_map.find(name);\n";
- os << " return (it == _buffer_map.end()) ? nullptr : it->second;\n";
- os << "}\n\n";
+
for (Operation &op : classOp) {
if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
return failure();
@@ -1660,15 +1649,16 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
emitc::BitwiseAndOp, emitc::BitwiseLeftShiftOp,
emitc::BitwiseNotOp, emitc::BitwiseOrOp,
emitc::BitwiseRightShiftOp, emitc::BitwiseXorOp, emitc::CallOp,
- emitc::CallOpaqueOp, emitc::CastOp, emitc::CmpOp,
- emitc::ConditionalOp, emitc::ConstantOp, emitc::DeclareFuncOp,
- emitc::DivOp, emitc::ExpressionOp, emitc::FileOp, emitc::ForOp,
- emitc::FuncOp, emitc::GlobalOp, emitc::IfOp, emitc::IncludeOp,
- emitc::LoadOp, emitc::LogicalAndOp, emitc::LogicalNotOp,
- emitc::LogicalOrOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
- emitc::SubOp, emitc::SwitchOp, emitc::UnaryMinusOp,
- emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp,
- emitc::ClassOp, emitc::FieldOp, emitc::GetFieldOp>(
+ emitc::CallOpaqueOp, emitc::CastOp, emitc::ClassOp,
+ emitc::CmpOp, emitc::ConditionalOp, emitc::ConstantOp,
+ emitc::DeclareFuncOp, emitc::DivOp, emitc::ExpressionOp,
+ emitc::FieldOp, emitc::FileOp, emitc::ForOp, emitc::FuncOp,
+ emitc::GetFieldOp, emitc::GlobalOp, emitc::IfOp,
+ emitc::IncludeOp, emitc::LoadOp, emitc::LogicalAndOp,
+ emitc::LogicalNotOp, emitc::LogicalOrOp, emitc::MulOp,
+ emitc::RemOp, emitc::ReturnOp, emitc::SubOp, emitc::SwitchOp,
+ emitc::UnaryMinusOp, emitc::UnaryPlusOp, emitc::VariableOp,
+ emitc::VerbatimOp>(
[&](auto op) { return printOperation(*this, op); })
// Func ops.
diff --git a/mlir/test/mlir-translate/emitc_classops.mlir b/mlir/test/mlir-translate/emitc_classops.mlir
index 3232954f1149a..e42844412860e 100644
--- a/mlir/test/mlir-translate/emitc_classops.mlir
+++ b/mlir/test/mlir-translate/emitc_classops.mlir
@@ -1,35 +1,25 @@
// RUN: mlir-translate --mlir-to-cpp %s | FileCheck %s
emitc.class @modelClass {
- emitc.field @input_tensor : !emitc.array<1xf32>
- emitc.field @some_feature : !emitc.array<1xf32> {emitc.opaque = ["some_feature"]}
+ emitc.field @fieldName0 : !emitc.array<1xf32>
+ emitc.field @fieldName1 : !emitc.array<1xf32>
emitc.func @execute() {
%0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
- %1 = get_field @input_tensor : !emitc.array<1xf32>
- %2 = get_field @some_feature : !emitc.array<1xf32>
+ %1 = get_field @fieldName0 : !emitc.array<1xf32>
+ %2 = get_field @fieldName1 : !emitc.array<1xf32>
%3 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
return
}
}
-// CHECK: class modelClass final {
+// CHECK: class modelClass {
// CHECK-NEXT: public:
-// CHECK-EMPTY:
-// CHECK-NEXT: const std::map<std::string, char*> _buffer_map {
-// CHECK-NEXT: { "input_tensor", reinterpret_cast<char*>(&None) },
-// CHECK-NEXT: { "some_feature", reinterpret_cast<char*>(&{emitc.opaque = ["some_feature"]}) },
-// CHECK-NEXT: };
-// CHECK-NEXT: char* getBufferForName(const std::string& name) const {
-// CHECK-NEXT: auto it = _buffer_map.find(name);
-// CHECK-NEXT: return (it == _buffer_map.end()) ? nullptr : it->second;
-// CHECK-NEXT: }
-// CHECK-EMPTY:
-// CHECK-NEXT: float[1] input_tensor;
-// CHECK-NEXT: float[1] some_feature;
+// CHECK-NEXT: float[1] fieldName0;
+// CHECK-NEXT: float[1] fieldName1;
// CHECK-NEXT: void execute() {
// CHECK-NEXT: size_t v1 = 0;
-// CHECK-NEXT: float[1] v2 = input_tensor;
-// CHECK-NEXT: float[1] v3 = some_feature;
+// CHECK-NEXT: float[1] v2 = fieldName0;
+// CHECK-NEXT: float[1] v3 = fieldName1;
// CHECK-NEXT: return;
// CHECK-NEXT: }
// CHECK-EMPTY:
>From d1e4a7ee1aff534b42f89b0fd357a14544d929fd Mon Sep 17 00:00:00 2001
From: Jaddyen <ajaden at google.com>
Date: Wed, 25 Jun 2025 20:51:31 +0000
Subject: [PATCH 4/4] Remove unnecessary include
---
mlir/lib/Target/Cpp/TranslateToCpp.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index f57c47d6b2fa4..15624934687b7 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -9,7 +9,6 @@
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
-#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
@@ -1004,7 +1003,7 @@ static LogicalResult printOperation(CppEmitter &emitter, ClassOp classOp) {
os << "class " << classOp.getSymName() << " {\n";
os << "public:\n";
os.indent();
-
+
for (Operation &op : classOp) {
if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
return failure();
More information about the Mlir-commits
mailing list