Skip to content

Commit d4ac0b6

Browse files
committed
[mlir][emitc] Relax hasSideEffect rules for Var/Member
The load side effect semantic depends on the operation that was used to declare the load's operand. In case of `VariableOp` and `MemberOp` the operation storage is on the stack, thus can be considered to not have side effects compared to e.g. subscript operation.
1 parent 14e89b0 commit d4ac0b6

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,17 @@ def EmitC_LoadOp : EmitC_Op<"load", [CExpressionInterface,
966966
let results = (outs AnyType:$result);
967967

968968
let assemblyFormat = "$operand attr-dict `:` type($operand)";
969+
970+
let extraClassDeclaration = [{
971+
bool hasSideEffects() {
972+
auto *defOp = this->getOperand().getDefiningOp();
973+
// The load side effect semantic depends on the operation that was used to
974+
// declare the load's operand, `VariableOp` and `MemberOp` perform loading
975+
// from the stack, thus we may consider them as not having side effect to
976+
// make end code more readable by letting those loads to get inlined.
977+
return !defOp || !(isa<VariableOp>(defOp) || isa<MemberOp>(defOp));
978+
}
979+
}];
969980
}
970981

971982
def EmitC_MulOp : EmitC_BinaryOp<"mul", []> {

mlir/test/Dialect/EmitC/transforms.mlir

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,18 @@ func.func @single_result_requirement() -> (i32, i32) {
135135
// CHECK-SAME: %[[VAL_1:.*]]: !emitc.ptr<i32>) -> i1 {
136136
// CHECK: %[[VAL_2:.*]] = "emitc.constant"() <{value = 0 : i64}> : () -> i64
137137
// CHECK: %[[VAL_3:.*]] = "emitc.variable"() <{value = #emitc.opaque<"42">}> : () -> !emitc.lvalue<i32>
138-
// CHECK: %[[VAL_4:.*]] = emitc.expression : i32 {
139-
// CHECK: %[[VAL_5:.*]] = load %[[VAL_3]] : <i32>
140-
// CHECK: yield %[[VAL_5]] : i32
138+
// CHECK: %[[VAL_4:.*]] = emitc.subscript %[[VAL_1]]{{\[}}%[[VAL_2]]] : (!emitc.ptr<i32>, i64) -> !emitc.lvalue<i32>
139+
// CHECK: %[[VAL_5:.*]] = emitc.expression : i32 {
140+
// CHECK: %[[VAL_6:.*]] = load %[[VAL_4]] : <i32>
141+
// CHECK: yield %[[VAL_6]] : i32
141142
// CHECK: }
142-
// CHECK: %[[VAL_6:.*]] = emitc.subscript %[[VAL_1]]{{\[}}%[[VAL_2]]] : (!emitc.ptr<i32>, i64) -> !emitc.lvalue<i32>
143-
// CHECK: %[[VAL_7:.*]] = emitc.expression : i32 {
144-
// CHECK: %[[VAL_8:.*]] = load %[[VAL_6]] : <i32>
145-
// CHECK: yield %[[VAL_8]] : i32
143+
// CHECK: %[[VAL_7:.*]] = emitc.expression : i1 {
144+
// CHECK: %[[VAL_8:.*]] = load %[[VAL_3]] : <i32>
145+
// CHECK: %[[VAL_9:.*]] = add %[[VAL_8]], %[[VAL_5]] : (i32, i32) -> i32
146+
// CHECK: %[[VAL_10:.*]] = cmp lt, %[[VAL_9]], %[[VAL_0]] : (i32, i32) -> i1
147+
// CHECK: yield %[[VAL_10]] : i1
146148
// CHECK: }
147-
// CHECK: %[[VAL_9:.*]] = emitc.expression : i1 {
148-
// CHECK: %[[VAL_10:.*]] = add %[[VAL_4]], %[[VAL_7]] : (i32, i32) -> i32
149-
// CHECK: %[[VAL_11:.*]] = cmp lt, %[[VAL_10]], %[[VAL_0]] : (i32, i32) -> i1
150-
// CHECK: yield %[[VAL_11]] : i1
151-
// CHECK: }
152-
// CHECK: return %[[VAL_9]] : i1
149+
// CHECK: return %[[VAL_7]] : i1
153150
// CHECK: }
154151

155152

mlir/test/Target/Cpp/expressions.mlir

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,13 @@ func.func @expression_with_subscript_user(%arg0: !emitc.ptr<!emitc.opaque<"void"
343343
return %res_load : i32
344344
}
345345

346-
// CPP-DEFAULT: bool expression_with_load(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]], int32_t* [[VAL_3:v.+]]) {
346+
// CPP-DEFAULT: bool expression_with_var_load_and_subscript(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]], int32_t* [[VAL_3:v.+]]) {
347347
// CPP-DEFAULT-NEXT: int64_t [[VAL_4:v.+]] = 0;
348348
// CPP-DEFAULT-NEXT: int32_t [[VAL_5:v.+]] = 42;
349349
// CPP-DEFAULT-NEXT: bool [[VAL_6:v.+]] = [[VAL_5]] + [[VAL_2]] < [[VAL_3]][[[VAL_4]]] + [[VAL_1]];
350350
// CPP-DEFAULT-NEXT: return [[VAL_6]];
351351

352-
// CPP-DECLTOP: bool expression_with_load(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]], int32_t* [[VAL_3:v.+]]) {
352+
// CPP-DECLTOP: bool expression_with_var_load_and_subscript(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]], int32_t* [[VAL_3:v.+]]) {
353353
// CPP-DECLTOP-NEXT: int64_t [[VAL_4:v.+]];
354354
// CPP-DECLTOP-NEXT: int32_t [[VAL_5:v.+]];
355355
// CPP-DECLTOP-NEXT: bool [[VAL_6:v.+]];
@@ -358,7 +358,7 @@ func.func @expression_with_subscript_user(%arg0: !emitc.ptr<!emitc.opaque<"void"
358358
// CPP-DECLTOP-NEXT: [[VAL_6]] = [[VAL_5]] + [[VAL_2]] < [[VAL_3]][[[VAL_4]]] + [[VAL_1]];
359359
// CPP-DECLTOP-NEXT: return [[VAL_6]];
360360

361-
func.func @expression_with_load(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr<i32>) -> i1 {
361+
func.func @expression_with_var_load_and_subscript(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr<i32>) -> i1 {
362362
%c0 = "emitc.constant"() {value = 0 : i64} : () -> i64
363363
%0 = "emitc.variable"() <{value = #emitc.opaque<"42">}> : () -> !emitc.lvalue<i32>
364364
%ptr = emitc.subscript %arg2[%c0] : (!emitc.ptr<i32>, i64) -> !emitc.lvalue<i32>
@@ -373,6 +373,26 @@ func.func @expression_with_load(%arg0: i32, %arg1: i32, %arg2: !emitc.ptr<i32>)
373373
return %result : i1
374374
}
375375

376+
// CPP-DEFAULT: bool expression_with_var_load(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]]) {
377+
// CPP-DEFAULT-NEXT: int32_t [[VAL_3:v.+]] = 42;
378+
// CPP-DEFAULT-NEXT: return [[VAL_3]] + [[VAL_1]] < [[VAL_2]];
379+
380+
// CPP-DECLTOP: bool expression_with_var_load(int32_t [[VAL_1:v.+]], int32_t [[VAL_2:v.+]]) {
381+
// CPP-DECLTOP-NEXT: int32_t [[VAL_3:v.+]];
382+
// CPP-DECLTOP-NEXT: [[VAL_3]] = 42;
383+
// CPP-DECLTOP-NEXT: return [[VAL_3]] + [[VAL_1]] < [[VAL_2]];
384+
385+
func.func @expression_with_var_load(%arg0: i32, %arg1: i32) -> i1 {
386+
%0 = "emitc.variable"() <{value = #emitc.opaque<"42">}> : () -> !emitc.lvalue<i32>
387+
%result = emitc.expression : i1 {
388+
%a = emitc.load %0 : !emitc.lvalue<i32>
389+
%b = emitc.add %a, %arg0 : (i32, i32) -> i32
390+
%d = emitc.cmp lt, %b, %arg1 :(i32, i32) -> i1
391+
yield %d : i1
392+
}
393+
return %result : i1
394+
}
395+
376396
// CPP-DEFAULT: bool expression_with_load_and_call(int32_t* [[VAL_1:v.+]]) {
377397
// CPP-DEFAULT-NEXT: int64_t [[VAL_2:v.+]] = 0;
378398
// CPP-DEFAULT-NEXT: bool [[VAL_3:v.+]] = [[VAL_1]][[[VAL_2]]] + bar([[VAL_1]][[[VAL_2]]]) < [[VAL_1]][[[VAL_2]]];

0 commit comments

Comments
 (0)