[clang] [CIR] Implement FlattenCFG for coroutine AwaitOp, CoroBodyOp, and CoReturnOp (PR #203802)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 16 18:17:26 PDT 2026


================
@@ -1805,11 +1813,212 @@ class CIRTryOpFlattening : public mlir::OpRewritePattern<cir::TryOp> {
   }
 };
 
+static mlir::Block *getOrCreateBlockForSuspendPoint(
+    cir::FuncOp funcOp, mlir::PatternRewriter &rewriter, mlir::Location loc) {
+  mlir::Block &entryBlock = funcOp.getBody().front();
+
+  auto it = llvm::find_if(entryBlock, [](auto &op) {
+    return mlir::isa<AllocaOp>(&op) &&
+           mlir::cast<AllocaOp>(&op).getCoroutineSuspendPoint();
+  });
+
+  assert(it->hasOneUse() &&
+         "coroutine suspend point alloca must have exactly one use");
+  auto storeOp = cast<cir::StoreOp>(*it->getUses().begin()->getOwner());
+  auto suspendPoint = cast<cir::ConstantOp>(storeOp.getValue().getDefiningOp());
+  mlir::Block *suspendBlock = suspendPoint->getBlock();
----------------
Andres-Salamanca wrote:

The idea was to use the `coroutine_suspend_point` alloca together with a store emitted at the exact location where a suspend-point block should exist. This allowed `cir.await` to branch to that location, and later during flattening I could recover the suspend point and build the corresponding switch destination.

Now that you mention that constants can be hoisted, I agree this is not the right approach.

A better solution would be to create the suspend-point block directly during CodeGen and emit a `cir.br` to it. For example, instead of terminating the suspend region with a `cir.yield`, `cir.await` suspend region could branch to the suspend block (either the return block or the GRO block):

```mlir
cir.await ...
  suspend {
    cir.br ^suspendBB
  }

^suspendBB:
  ...
```

Then, during flattening, we can replace that branch with the flattened switch containing the three coroutine paths (`resume`, `destroy`, and `suspend`).

https://github.com/llvm/llvm-project/pull/203802


More information about the cfe-commits mailing list