[clang] [CIR] Add structured control flow for coroutine suspend points (PR #213191)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 31 09:55:01 PDT 2026
================
@@ -382,11 +381,25 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
// Handle allocation failure if 'ReturnStmtOnAllocFailure' was provided.
if (s.getReturnStmtOnAllocFailure())
cgm.errorNYI("handle coroutine return alloc failure");
-
+ cir::CoroRetPointOp coroRet = nullptr;
+ mlir::OpBuilder::InsertPoint coroRetRegion;
{
assert(!cir::MissingFeatures::generateDebugInfo());
ParamReferenceReplacerRAII paramReplacer(localDeclMap);
RunCleanupsScope resumeScope(*this);
+ mlir::OpBuilder::InsertPoint coroRetBody;
+ coroRet = cir::CoroRetPointOp::create(
+ builder, openCurlyLoc,
+ /*bodyBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location) {
+ coroRetBody = b.saveInsertionPoint();
----------------
andykaylor wrote:
Yeah, so we've had basically two merging patterns. One can be seen in `emitForStmt` and does something like this:
```
cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc) {
LexicalScope lexScope{*this, loc,
builder.getInsertionBlock()};
res = forStmtBuilder();
});
```
That is, we have an op-builder that needs to enclose an arbitrary amount of code and does so by calling another function (in this case a lambda, but it could be a normal function) that emits the code that goes inside the region.
The other pattern is what you're doing here, which is basically:
```
void someFunction() {
// ... do some things ...
op = cir::SomeOp::create(builder, loc,
[&](mlir::OpBuilder &b, mlir::Location) {
savedInsertPt = b.saveInsertPoint();
});
// Point to the inside of a region for an op we just created
mlir::OpBuilder::InsertionGuard guard(builder);
builder.restoreInsertionPoint(savedInsertPt);
// ... generate the code that goes inside the region ...
}
```
You can see that the second pattern can easily be transformed into the first by moving the code that generates the content of the region into a function or lambda. Not only is that more robust, it's also easier to follow the logic, especially in a case like you have here where you're emitting code into two different regions.
https://github.com/llvm/llvm-project/pull/213191
More information about the cfe-commits
mailing list