Skip to content

Commit 9e3863c

Browse files
Simon Camphausenmarbre
authored andcommitted
[mlir][EmitC] Add verbatim op (llvm#79584)
The `verbatim` operation produces no results and the value is emitted as is followed by a line break ('\n' character) during translation. 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. Co-authored-by: Marius Brehler <[email protected]>
1 parent 241a2ba commit 9e3863c

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

mlir/include/mlir/Dialect/EmitC/IR/EmitC.td

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,43 @@ def EmitC_VariableOp : EmitC_Op<"variable", []> {
544544
let hasVerifier = 1;
545545
}
546546

547+
def EmitC_VerbatimOp : EmitC_Op<"verbatim"> {
548+
let summary = "Verbatim operation";
549+
let description = [{
550+
The `verbatim` operation produces no results and the value is emitted as is
551+
followed by a line break ('\n' character) during translation.
552+
553+
Note: Use with caution. This operation can have arbitrary effects on the
554+
semantics of the emitted code. Use semantically more meaningful operations
555+
whenever possible. Additionally this op is *NOT* intended to be used to
556+
inject large snippets of code.
557+
558+
This operation can be used in situations where a more suitable operation is
559+
not yet implemented in the dialect or where preprocessor directives
560+
interfere with the structure of the code. One example of this is to declare
561+
the linkage of external symbols to make the generated code usable in both C
562+
and C++ contexts:
563+
564+
```c++
565+
#ifdef __cplusplus
566+
extern "C" {
567+
#endif
568+
569+
...
570+
571+
#ifdef __cplusplus
572+
}
573+
#endif
574+
```
575+
}];
576+
577+
let arguments = (ins
578+
StrAttr:$value,
579+
UnitAttr:$trailing_semicolon
580+
);
581+
let assemblyFormat = "$value attr-dict";
582+
}
583+
547584
def EmitC_AssignOp : EmitC_Op<"assign", []> {
548585
let summary = "Assign operation";
549586
let description = [{

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,15 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::CmpOp cmpOp) {
442442
return printBinaryOperation(emitter, operation, binaryOperator);
443443
}
444444

445+
static LogicalResult printOperation(CppEmitter &emitter,
446+
emitc::VerbatimOp verbatimOp) {
447+
raw_ostream &os = emitter.ostream();
448+
449+
os << verbatimOp.getValue();
450+
451+
return success();
452+
}
453+
445454
static LogicalResult printOperation(CppEmitter &emitter,
446455
cf::BranchOp branchOp) {
447456
raw_ostream &os = emitter.ostream();
@@ -825,11 +834,10 @@ static LogicalResult printOperation(CppEmitter &emitter,
825834
for (Operation &op : block.getOperations()) {
826835
// When generating code for an emitc.if or cf.cond_br op no semicolon
827836
// needs to be printed after the closing brace.
828-
// When generating code for an emitc.for op, printing a trailing semicolon
829-
// is handled within the printOperation function.
830-
bool trailingSemicolon =
831-
!isa<cf::CondBranchOp, emitc::ForOp, emitc::IfOp, emitc::LiteralOp>(
832-
op);
837+
// When generating code for an emitc.for and emitc.verbatim op, printing a
838+
// trailing semicolon is handled within the printOperation function.
839+
bool trailingSemicolon = !isa<cf::CondBranchOp, emitc::ForOp, emitc::IfOp,
840+
emitc::LiteralOp, emitc::VerbatimOp>(op);
833841

834842
if (failed(emitter.emitOperation(
835843
op, /*trailingSemicolon=*/trailingSemicolon)))
@@ -1175,7 +1183,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
11751183
emitc::ConstantOp, emitc::DivOp, emitc::ExpressionOp,
11761184
emitc::ForOp, emitc::IfOp, emitc::IncludeOp, emitc::MulOp,
11771185
emitc::RemOp, emitc::SubOp, emitc::SubscriptOp,
1178-
emitc::VariableOp>(
1186+
emitc::VariableOp, emitc::VerbatimOp>(
11791187
[&](auto op) { return printOperation(*this, op); })
11801188
// Func ops.
11811189
.Case<func::CallOp, func::ConstantOp, func::FuncOp, func::ReturnOp>(

mlir/test/Dialect/EmitC/ops.mlir

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,14 @@ func.func @test_subscript(%arg0: !emitc.array<4x8xf32>, %arg1: !emitc.array<3x5x
174174
emitc.assign %0 : f32 to %1 : f32
175175
return
176176
}
177+
178+
emitc.verbatim "#ifdef __cplusplus"
179+
emitc.verbatim "extern \"C\" {"
180+
emitc.verbatim "#endif // __cplusplus"
181+
182+
emitc.verbatim "#ifdef __cplusplus"
183+
emitc.verbatim "} // extern \"C\""
184+
emitc.verbatim "#endif // __cplusplus"
185+
186+
emitc.verbatim "typedef int32_t i32;"
187+
emitc.verbatim "typedef float f32;"

mlir/test/Target/Cpp/verbatim.mlir

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
2+
// RUN: mlir-translate -mlir-to-cpp -declare-variables-at-top %s | FileCheck %s
3+
4+
5+
emitc.verbatim "#ifdef __cplusplus"
6+
// CHECK: #ifdef __cplusplus
7+
emitc.verbatim "extern \"C\" {"
8+
// CHECK-NEXT: extern "C" {
9+
emitc.verbatim "#endif // __cplusplus"
10+
// CHECK-NEXT: #endif // __cplusplus
11+
emitc.verbatim "#ifdef __cplusplus"
12+
// CHECK-NEXT: #ifdef __cplusplus
13+
emitc.verbatim "} // extern \"C\""
14+
// CHECK-NEXT: } // extern "C"
15+
emitc.verbatim "#endif // __cplusplus"
16+
// CHECK-NEXT: #endif // __cplusplus
17+
18+
emitc.verbatim "typedef int32_t i32;"
19+
// CHECK-NEXT: typedef int32_t i32;
20+
emitc.verbatim "typedef float f32;"
21+
// CHECK-NEXT: typedef float f32;

0 commit comments

Comments
 (0)