Skip to content

Commit cab7e24

Browse files
authored
Merge pull request #393 from Xilinx/matthias.emitc_tu
Add emitc.tu
2 parents ad4697c + a64ebcc commit cab7e24

File tree

5 files changed

+112
-9
lines changed

5 files changed

+112
-9
lines changed

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ include "mlir/Interfaces/CastInterfaces.td"
2121
include "mlir/Interfaces/ControlFlowInterfaces.td"
2222
include "mlir/Interfaces/FunctionInterfaces.td"
2323
include "mlir/Interfaces/SideEffectInterfaces.td"
24+
include "mlir/IR/OpAsmInterface.td"
2425
include "mlir/IR/RegionKindInterface.td"
26+
include "mlir/IR/BuiltinAttributes.td"
2527

2628
//===----------------------------------------------------------------------===//
2729
// EmitC op definitions
@@ -55,6 +57,47 @@ def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_s
5557
"integer, index or opaque type supported by EmitC">;
5658
def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>;
5759

60+
def EmitC_TranslationUnitOp : EmitC_Op<"tu",
61+
[IsolatedFromAbove, NoRegionArguments, SymbolTable,
62+
OpAsmOpInterface
63+
] # GraphRegionNoTerminator.traits> {
64+
let summary = "A translation unit container operation";
65+
let description = [{
66+
A `tu` represents a translation unit that can be emitted
67+
into a single C++ file.
68+
69+
`mlir-translate` emits only the translation unit selected via
70+
the `-translation-unit-id=id` flag. By default, no translation units are
71+
emitted.
72+
73+
Example:
74+
75+
```mlir
76+
emitc.tu "main" {
77+
emitc.func @func_one() {
78+
emitc.return
79+
}
80+
}
81+
```
82+
}];
83+
84+
let arguments = (ins Builtin_StringAttr:$id);
85+
let regions = (region SizedRegion<1>:$bodyRegion);
86+
87+
let assemblyFormat = "$id attr-dict-with-keyword $bodyRegion";
88+
let extraClassDeclaration = [{
89+
//===------------------------------------------------------------------===//
90+
// OpAsmOpInterface Methods
91+
//===------------------------------------------------------------------===//
92+
93+
/// EmitC ops in the body of the translation_unit can omit their 'emitc.'
94+
/// prefix in the assembly.
95+
static ::llvm::StringRef getDefaultDialect() {
96+
return "emitc";
97+
}
98+
}];
99+
}
100+
58101
def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
59102
let summary = "Addition operation";
60103
let description = [{

mlir/include/mlir/Target/Cpp/CppEmitter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define MLIR_TARGET_CPP_CPPEMITTER_H
1515

1616
#include "mlir/Support/LLVM.h"
17+
#include "llvm/ADT/StringRef.h"
1718

1819
namespace mlir {
1920
class Operation;
@@ -24,7 +25,8 @@ namespace emitc {
2425
/// 'declareVariablesAtTop' enforces that all variables for op results and block
2526
/// arguments are declared at the beginning of the function.
2627
LogicalResult translateToCpp(Operation *op, raw_ostream &os,
27-
bool declareVariablesAtTop = false);
28+
bool declareVariablesAtTop = false,
29+
StringRef onlyTu = "");
2830
} // namespace emitc
2931
} // namespace mlir
3032

mlir/lib/Target/Cpp/TranslateRegistration.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@ void registerToCppTranslation() {
2929
llvm::cl::desc("Declare variables at top when emitting C/C++"),
3030
llvm::cl::init(false));
3131

32+
static llvm::cl::opt<std::string> onlyTu(
33+
"translation-unit-id",
34+
llvm::cl::desc("Only emit the translation unit with the matching id"),
35+
llvm::cl::init(""));
36+
3237
TranslateFromMLIRRegistration reg(
3338
"mlir-to-cpp", "translate from mlir to cpp",
3439
[](Operation *op, raw_ostream &output) {
3540
return emitc::translateToCpp(
3641
op, output,
37-
/*declareVariablesAtTop=*/declareVariablesAtTop);
42+
/*declareVariablesAtTop=*/declareVariablesAtTop,
43+
/*onlyTu=*/onlyTu);
3844
},
3945
[](DialectRegistry &registry) {
4046
// clang-format off

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
115115
namespace {
116116
/// Emitter that uses dialect specific emitters to emit C++ code.
117117
struct CppEmitter {
118-
explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop);
118+
explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
119+
StringRef onlyTu);
119120

120121
/// Emits attribute or returns failure.
121122
LogicalResult emitAttribute(Location loc, Attribute attr);
@@ -231,6 +232,9 @@ struct CppEmitter {
231232
/// be declared at the beginning of a function.
232233
bool shouldDeclareVariablesAtTop() { return declareVariablesAtTop; };
233234

235+
/// Returns whether this translation unit should be emitted
236+
bool shouldEmitTu(TranslationUnitOp tu) { return tu.getId() == onlyTu; }
237+
234238
/// Get expression currently being emitted.
235239
ExpressionOp getEmittedExpression() { return emittedExpression; }
236240

@@ -258,6 +262,9 @@ struct CppEmitter {
258262
/// includes results from ops located in nested regions.
259263
bool declareVariablesAtTop;
260264

265+
/// Only emit translation units whos id matches this value.
266+
std::string onlyTu;
267+
261268
/// Map from value to name of C++ variable that contain the name.
262269
ValueMapper valueMapper;
263270

@@ -936,6 +943,19 @@ static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) {
936943
return success();
937944
}
938945

946+
static LogicalResult printOperation(CppEmitter &emitter, TranslationUnitOp tu) {
947+
if (!emitter.shouldEmitTu(tu))
948+
return success();
949+
950+
CppEmitter::Scope scope(emitter);
951+
952+
for (Operation &op : tu) {
953+
if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false)))
954+
return failure();
955+
}
956+
return success();
957+
}
958+
939959
template <class FuncOpClass>
940960
static LogicalResult printFunctionArgs(CppEmitter &emitter,
941961
FuncOpClass functionOp,
@@ -1177,8 +1197,10 @@ static LogicalResult printOperation(CppEmitter &emitter,
11771197
return success();
11781198
}
11791199

1180-
CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop)
1181-
: os(os), declareVariablesAtTop(declareVariablesAtTop) {
1200+
CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
1201+
StringRef onlyTu)
1202+
: os(os), declareVariablesAtTop(declareVariablesAtTop),
1203+
onlyTu(onlyTu.str()) {
11821204
valueInScopeCount.push(0);
11831205
labelInScopeCount.push(0);
11841206
}
@@ -1580,8 +1602,8 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
15801602
emitc::GlobalOp, emitc::IfOp, emitc::IncludeOp,
15811603
emitc::LogicalAndOp, emitc::LogicalNotOp, emitc::LogicalOrOp,
15821604
emitc::MulOp, emitc::RemOp, emitc::ReturnOp, emitc::SubOp,
1583-
emitc::UnaryMinusOp, emitc::UnaryPlusOp, emitc::VariableOp,
1584-
emitc::VerbatimOp>(
1605+
emitc::TranslationUnitOp, emitc::UnaryMinusOp,
1606+
emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp>(
15851607
[&](auto op) { return printOperation(*this, op); })
15861608
// Func ops.
15871609
.Case<func::CallOp, func::FuncOp, func::ReturnOp>(
@@ -1791,7 +1813,8 @@ LogicalResult CppEmitter::emitTupleType(Location loc, ArrayRef<Type> types) {
17911813
}
17921814

17931815
LogicalResult emitc::translateToCpp(Operation *op, raw_ostream &os,
1794-
bool declareVariablesAtTop) {
1795-
CppEmitter emitter(os, declareVariablesAtTop);
1816+
bool declareVariablesAtTop,
1817+
StringRef onlyTu) {
1818+
CppEmitter emitter(os, declareVariablesAtTop, onlyTu);
17961819
return emitter.emitOperation(*op, /*trailingSemicolon=*/false);
17971820
}

mlir/test/Target/Cpp/tu.mlir

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s --check-prefix NO-FILTER
2+
// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=non-existing %s | FileCheck %s --check-prefix NON-EXISTING
3+
// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=tu_one %s | FileCheck %s --check-prefix TU-ONE
4+
// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=tu_two %s | FileCheck %s --check-prefix TU-TWO
5+
6+
7+
// NO-FILTER-NOT: func_one
8+
// NO-FILTER-NOT: func_two
9+
10+
// NON-EXISTING-NOT: func_one
11+
// NON-EXISTING-NOT: func_two
12+
13+
// TU-ONE: func_one
14+
// TU-ONE-NOT: func_two
15+
16+
// TU-TWO-NOT: func_one
17+
// TU-TWO: func_two
18+
19+
emitc.tu "tu_one" {
20+
emitc.func @func_one(%arg: f32) {
21+
emitc.return
22+
}
23+
}
24+
25+
emitc.tu "tu_two" {
26+
emitc.func @func_two(%arg: f32) {
27+
emitc.return
28+
}
29+
}

0 commit comments

Comments
 (0)