[Mlir-commits] [mlir] [mlir][EmitC] Add `verbatim` op (PR #79584)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Jan 26 03:55:33 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-emitc
@llvm/pr-subscribers-mlir
Author: Simon Camphausen (simon-camp)
<details>
<summary>Changes</summary>
The `verbatim` operation produces no results and the value is emitted as is durung translation. If `trailing_semicolon` is present an additional semicolon is emitted.
Note: Use with caution. This operation can have arbitrary effects on the semantics of the emitted code. Use semantically more meaningful operations whenever possible. Additionally this op is *NOT* intended to be used to inject large snippets of code.
This operation can be used in situations where a more suitable operation is not yet implemented in the dialect or where preprocessor directives interfere with the structure of the code.
---
Full diff: https://github.com/llvm/llvm-project/pull/79584.diff
6 Files Affected:
- (modified) mlir/include/mlir/Dialect/EmitC/IR/EmitC.td (+39)
- (modified) mlir/lib/Dialect/EmitC/IR/EmitC.cpp (+11)
- (modified) mlir/lib/Target/Cpp/TranslateToCpp.cpp (+17-6)
- (modified) mlir/test/Dialect/EmitC/invalid_ops.mlir (+8)
- (modified) mlir/test/Dialect/EmitC/ops.mlir (+11)
- (added) mlir/test/Target/Cpp/verbatim.mlir (+21)
``````````diff
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index b8f8f1e2d818d5..4d3d6c20e9b2c3 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -544,6 +544,45 @@ def EmitC_VariableOp : EmitC_Op<"variable", []> {
let hasVerifier = 1;
}
+def EmitC_VerbatimOp : EmitC_Op<"verbatim"> {
+ let summary = "Verbatim operation";
+ let description = [{
+ The `verbatim` operation produces no results and the value is emitted as is
+ durung translation. If `trailing_semicolon` is present an additional
+ semicolon is emitted.
+
+ Note: Use with caution. This operation can have arbitrary effects on the
+ semantics of the emitted code. Use semantically more meaningful operations
+ whenever possible. Additionally this op is *NOT* intended to be used to
+ inject large snippets of code.
+
+ This operation can be used in situations where a more suitable operation is
+ not yet implemented in the dialect or where preprocessor directives
+ interfere with the structure of the code. One example of this is to declare
+ the linkage of external symbols to make the generated code usable in both C
+ and C++ contexts:
+
+ ```c++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ ...
+
+ #ifdef __cplusplus
+ }
+ #endif
+ ```
+ }];
+
+ let arguments = (ins
+ StrAttr:$value,
+ UnitAttr:$trailing_semicolon
+ );
+ let assemblyFormat = "$value (`trailing_semicolon` $trailing_semicolon^)? attr-dict";
+ let hasVerifier = 1;
+}
+
def EmitC_AssignOp : EmitC_Op<"assign", []> {
let summary = "Assign operation";
let description = [{
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 5f502f1f7a1714..921cce58294315 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -584,6 +584,17 @@ LogicalResult emitc::VariableOp::verify() {
return verifyInitializationAttribute(getOperation(), getValueAttr());
}
+//===----------------------------------------------------------------------===//
+// VerbatimOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult emitc::VerbatimOp::verify() {
+ if (getValue().back() == ';')
+ return emitOpError() << "';' not allowed as the last character, use the "
+ "`trailing_semicolon` attribute instead";
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// YieldOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index c32cb03caf9db6..657f6ae092aef8 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -429,6 +429,17 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::CmpOp cmpOp) {
return printBinaryOperation(emitter, operation, binaryOperator);
}
+static LogicalResult printOperation(CppEmitter &emitter,
+ emitc::VerbatimOp verbatimOp) {
+ raw_ostream &os = emitter.ostream();
+
+ os << verbatimOp.getValue();
+
+ if (verbatimOp.getTrailingSemicolon())
+ os << ";";
+ return success();
+}
+
static LogicalResult printOperation(CppEmitter &emitter,
cf::BranchOp branchOp) {
raw_ostream &os = emitter.ostream();
@@ -814,11 +825,10 @@ static LogicalResult printOperation(CppEmitter &emitter,
for (Operation &op : block.getOperations()) {
// When generating code for an emitc.if or cf.cond_br op no semicolon
// needs to be printed after the closing brace.
- // When generating code for an emitc.for op, printing a trailing semicolon
- // is handled within the printOperation function.
- bool trailingSemicolon =
- !isa<cf::CondBranchOp, emitc::ForOp, emitc::IfOp, emitc::LiteralOp>(
- op);
+ // When generating code for an emitc.for and emitc.verbatim op, printing a
+ // trailing semicolon is handled within the printOperation function.
+ bool trailingSemicolon = !isa<cf::CondBranchOp, emitc::ForOp, emitc::IfOp,
+ emitc::LiteralOp, emitc::VerbatimOp>(op);
if (failed(emitter.emitOperation(
op, /*trailingSemicolon=*/trailingSemicolon)))
@@ -1144,7 +1154,8 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
emitc::CallOpaqueOp, emitc::CastOp, emitc::CmpOp,
emitc::ConstantOp, emitc::DivOp, emitc::ExpressionOp,
emitc::ForOp, emitc::IfOp, emitc::IncludeOp, emitc::MulOp,
- emitc::RemOp, emitc::SubOp, emitc::VariableOp>(
+ emitc::RemOp, emitc::SubOp, emitc::VariableOp,
+ emitc::VerbatimOp>(
[&](auto op) { return printOperation(*this, op); })
// Func ops.
.Case<func::CallOp, func::ConstantOp, func::FuncOp, func::ReturnOp>(
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index 46eccb1c24eea2..2d98c505ac2435 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -289,3 +289,11 @@ func.func @test_expression_multiple_results(%arg0: i32) -> i32 {
}
return %r : i32
}
+
+// -----
+
+func.func @verbatim_trailing_semicolon() {
+ // expected-error @+1 {{'emitc.verbatim' op ';' not allowed as the last character, use the `trailing_semicolon` attribute instead}}
+ emitc.verbatim "typedef int32_t i32;"
+ return
+}
\ No newline at end of file
diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir
index 45ce2bcb99092c..a50883b38d14a2 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -166,3 +166,14 @@ func.func @test_for_not_index_induction(%arg0 : i16, %arg1 : i16, %arg2 : i16) {
}
return
}
+
+emitc.verbatim "#ifdef __cplusplus"
+emitc.verbatim "extern \"C\" {"
+emitc.verbatim "#endif // __cplusplus"
+
+emitc.verbatim "#ifdef __cplusplus"
+emitc.verbatim "} // extern \"C\""
+emitc.verbatim "#endif // __cplusplus"
+
+emitc.verbatim "typedef int32_t i32" {trailing_semicolon = unit}
+emitc.verbatim "typedef float f32" trailing_semicolon
diff --git a/mlir/test/Target/Cpp/verbatim.mlir b/mlir/test/Target/Cpp/verbatim.mlir
new file mode 100644
index 00000000000000..cf17486050f981
--- /dev/null
+++ b/mlir/test/Target/Cpp/verbatim.mlir
@@ -0,0 +1,21 @@
+// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
+// RUN: mlir-translate -mlir-to-cpp -declare-variables-at-top %s | FileCheck %s
+
+
+emitc.verbatim "#ifdef __cplusplus"
+// CHECK: #ifdef __cplusplus
+emitc.verbatim "extern \"C\" {"
+// CHECK-NEXT: extern "C" {
+emitc.verbatim "#endif // __cplusplus"
+// CHECK-NEXT: #endif // __cplusplus
+emitc.verbatim "#ifdef __cplusplus"
+// CHECK-NEXT: #ifdef __cplusplus
+emitc.verbatim "} // extern \"C\""
+// CHECK-NEXT: } // extern "C"
+emitc.verbatim "#endif // __cplusplus"
+// CHECK-NEXT: #endif // __cplusplus
+
+emitc.verbatim "typedef int32_t i32" {trailing_semicolon = unit}
+// CHECK-NEXT: typedef int32_t i32;
+emitc.verbatim "typedef float f32" trailing_semicolon
+// CHECK-NEXT: typedef float f32;
``````````
</details>
https://github.com/llvm/llvm-project/pull/79584
More information about the Mlir-commits
mailing list