[Mlir-commits] [mlir] [mlir][emitc] Add 'emitc.while' and 'emitc.do' ops to the dialect (PR #143008)
Kirill Chibisov
llvmlistbot at llvm.org
Wed Jun 18 02:13:31 PDT 2025
================
@@ -1572,4 +1572,156 @@ def EmitC_SwitchOp : EmitC_Op<"switch", [RecursiveMemoryEffects,
let hasVerifier = 1;
}
+def EmitC_WhileOp : EmitC_Op<"while",
+ [HasOnlyGraphRegion, RecursiveMemoryEffects, NoRegionArguments, OpAsmOpInterface, NoTerminator]> {
+ let summary = "While operation";
+ let description = [{
+ The `emitc.while` operation represents a C/C++ while loop construct that
+ repeatedly executes a body region as long as a condition region evaluates to
+ true. The operation has two regions:
+
+ 1. A condition region that must yield a boolean value (i1)
+ 2. A body region that contains the loop body
+
+ The condition region is evaluated before each iteration. If it yields true,
+ the body region is executed. The loop terminates when the condition yields
+ false. The condition region must contain exactly one block that terminates
+ with an `emitc.yield` operation producing an i1 value.
+
+ Example:
+
+ ```mlir
+ emitc.func @foo(%arg0 : !emitc.ptr<i32>) {
+ %var = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
+ %0 = emitc.literal "10" : i32
+ %1 = emitc.literal "1" : i32
+
+ emitc.while {
+ %var_load = load %var : <i32>
+ %res = emitc.cmp le, %var_load, %0 : (i32, i32) -> i1
+ emitc.yield %res : i1
+ } do {
+ emitc.verbatim "printf(\"%d\", *{});" args %arg0 : !emitc.ptr<i32>
+ %var_load = load %var : <i32>
+ %tmp_add = add %var_load, %1 : (i32, i32) -> i32
+ "emitc.assign"(%var, %tmp_add) : (!emitc.lvalue<i32>, i32) -> ()
+ }
+
+ return
+ }
+ ```
+
+ ```c++
+ // Code emitted for the operation above.
+ void foo(int32_t* v1) {
+ int32_t v2 = 0;
+ while (v2 <= 10) {
+ printf("%d", *v1);
+ int32_t v3 = v2;
+ int32_t v4 = v3 + 1;
+ v2 = v4;
+ }
+ return;
+ }
+ ```
+ }];
+
+ let arguments = (ins);
+ let results = (outs);
+ let regions = (region MaxSizedRegion<1>:$conditionRegion,
----------------
kchibisov wrote:
The problem is that you can not use `emitc.expression` as an operand because it's not a type, so you can only pass a `bool` pretty much.
>OTOH, if the condition's emitc.expression is located outside the loop then inlining that expression would change program semantics from a single to multiple evaluations of the expression.
This will make `while` completely useless, it must always be inlined for `load` to be a part of the condition and be inside the cond `while (cond)`.
>How about requiring the condition region of these loop ops to contain a single emitc.expression op feeding an emitc.yield? That should both utilize emitc.expression and avoid any inlining issues.
Do you want to nest it one more time? That should work, a bit ugly, but I guess it's fine.
https://github.com/llvm/llvm-project/pull/143008
More information about the Mlir-commits
mailing list