Skip to content

Commit d2e6f15

Browse files
committed
[mlir][emitc] Mark emitc.literal with CExpression
This PR marks `emitc.literal` as a valid operation within `emitc.expression`, removing an artificial restriction since literals are inherently inlined into expressions during emission. Example: ```mlir %0 = emitc.expression : i32 { %literal = emitc.literal "42" : i32 emitc.yield %literal : i32 } ```
1 parent 5622a92 commit d2e6f15

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ def EmitC_IncludeOp
873873
let hasCustomAssemblyFormat = 1;
874874
}
875875

876-
def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
876+
def EmitC_LiteralOp : EmitC_Op<"literal", [Pure, CExpressionInterface]> {
877877
let summary = "Literal operation";
878878
let description = [{
879879
The `emitc.literal` operation produces an SSA value equal to some constant

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
100100
.Case<emitc::ConstantOp>([&](auto op) { return 17; })
101101
.Case<emitc::DivOp>([&](auto op) { return 13; })
102102
.Case<emitc::LoadOp>([&](auto op) { return 16; })
103+
.Case<emitc::LiteralOp>([&](auto op) { return 16; })
103104
.Case<emitc::LogicalAndOp>([&](auto op) { return 4; })
104105
.Case<emitc::LogicalNotOp>([&](auto op) { return 15; })
105106
.Case<emitc::LogicalOrOp>([&](auto op) { return 3; })
@@ -452,6 +453,16 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::LoadOp loadOp) {
452453
return emitter.emitOperand(loadOp.getOperand());
453454
}
454455

456+
static LogicalResult printOperation(CppEmitter &emitter,
457+
emitc::LiteralOp literalOp) {
458+
// If literalOp is used inside an expression, we treat it as an embedded one.
459+
if (emitter.isPartOfCurrentExpression(literalOp.getResult()))
460+
return emitter.ostream() << literalOp.getValue(), success();
461+
462+
emitter.cacheDeferredOpResult(literalOp.getResult(), literalOp.getValue());
463+
return success();
464+
}
465+
455466
static LogicalResult printBinaryOperation(CppEmitter &emitter,
456467
Operation *operation,
457468
StringRef binaryOperator) {
@@ -1714,10 +1725,10 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
17141725
emitc::DeclareFuncOp, emitc::DivOp, emitc::ExpressionOp,
17151726
emitc::FieldOp, emitc::FileOp, emitc::ForOp, emitc::FuncOp,
17161727
emitc::GlobalOp, emitc::IfOp, emitc::IncludeOp, emitc::LoadOp,
1717-
emitc::LogicalAndOp, emitc::LogicalNotOp, emitc::LogicalOrOp,
1718-
emitc::MulOp, emitc::RemOp, emitc::ReturnOp, emitc::SubOp,
1719-
emitc::SwitchOp, emitc::UnaryMinusOp, emitc::UnaryPlusOp,
1720-
emitc::VariableOp, emitc::VerbatimOp>(
1728+
emitc::LiteralOp, emitc::LogicalAndOp, emitc::LogicalNotOp,
1729+
emitc::LogicalOrOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
1730+
emitc::SubOp, emitc::SwitchOp, emitc::UnaryMinusOp,
1731+
emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp>(
17211732

17221733
[&](auto op) { return printOperation(*this, op); })
17231734
// Func ops.
@@ -1731,10 +1742,6 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
17311742
cacheDeferredOpResult(op.getResult(), op.getFieldName());
17321743
return success();
17331744
})
1734-
.Case<emitc::LiteralOp>([&](auto op) {
1735-
cacheDeferredOpResult(op.getResult(), op.getValue());
1736-
return success();
1737-
})
17381745
.Case<emitc::MemberOp>([&](auto op) {
17391746
cacheDeferredOpResult(op.getResult(), createMemberAccess(op));
17401747
return success();

mlir/test/Dialect/EmitC/form-expressions.mlir

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,29 @@ func.func @expression_with_constant(%arg0: i32) -> i32 {
208208
%a = emitc.mul %arg0, %c42 : (i32, i32) -> i32
209209
return %a : i32
210210
}
211+
212+
// CHECK-LABEL: func.func @expression_with_literal(
213+
// CHECK-SAME: %[[ARG0:.*]]: i32) -> i1 {
214+
// CHECK: %[[VAL_0:.*]] = emitc.expression : i32 {
215+
// CHECK: %[[VAL_1:.*]] = literal "1" : i32
216+
// CHECK: yield %[[VAL_1]] : i32
217+
// CHECK: }
218+
// CHECK: %[[VAL_2:.*]] = emitc.expression : i32 {
219+
// CHECK: %[[VAL_3:.*]] = literal "2" : i32
220+
// CHECK: yield %[[VAL_3]] : i32
221+
// CHECK: }
222+
// CHECK: %[[VAL_4:.*]] = emitc.expression : i1 {
223+
// CHECK: %[[VAL_5:.*]] = add %[[VAL_0]], %[[VAL_2]] : (i32, i32) -> i32
224+
// CHECK: %[[VAL_6:.*]] = cmp lt, %[[VAL_5]], %[[ARG0]] : (i32, i32) -> i1
225+
// CHECK: yield %[[VAL_6]] : i1
226+
// CHECK: }
227+
// CHECK: return %[[VAL_4]] : i1
228+
// CHECK: }
229+
230+
func.func @expression_with_literal(%arg0: i32) -> i1 {
231+
%literal1 = emitc.literal "1" : i32
232+
%literal2 = emitc.literal "2" : i32
233+
%b = emitc.add %literal1, %literal2 : (i32, i32) -> i32
234+
%c = emitc.cmp lt, %b, %arg0 :(i32, i32) -> i1
235+
return %c : i1
236+
}

mlir/test/Target/Cpp/expressions.mlir

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,29 @@ emitc.func @expression_with_call_opaque_with_args_array(%0 : i32, %1 : i32) {
458458
}
459459
return
460460
}
461+
462+
463+
// CPP-DEFAULT: bool expression_with_literal(int32_t [[VAL_1:v[0-9]+]]) {
464+
// CPP-DEFAULT-NEXT: bool [[VAL_2:v[0-9]+]] = (1 + [[VAL_1]]) / 2 < 3;
465+
// CPP-DEFAULT-NEXT: return [[VAL_2]];
466+
// CPP-DEFAULT-NEXT: }
467+
468+
// CPP-DECLTOP: bool expression_with_literal(int32_t [[VAL_1:v[0-9]+]]) {
469+
// CPP-DECLTOP-NEXT: bool [[VAL_2:v[0-9]+]];
470+
// CPP-DECLTOP-NEXT: [[VAL_2]] = (1 + [[VAL_1]]) / 2 < 3;
471+
// CPP-DECLTOP-NEXT: return [[VAL_2]];
472+
// CPP-DECLTOP-NEXT: }
473+
474+
func.func @expression_with_literal(%arg0 : i32) -> i1 {
475+
%ret = emitc.expression noinline : i1 {
476+
%literal1 = emitc.literal "1" : i32
477+
%literal2 = emitc.literal "2" : i32
478+
%add = add %literal1, %arg0 : (i32, i32) -> i32
479+
%div = div %add, %literal2 : (i32, i32) -> i32
480+
%literal3 = emitc.literal "3" : i32
481+
%f = emitc.cmp lt, %div, %literal3 :(i32, i32) -> i1
482+
emitc.yield %f : i1
483+
}
484+
485+
return %ret : i1
486+
}

0 commit comments

Comments
 (0)