Author: Andres-Salamanca Date: 2026-10-23T15:55:15-05:00 New Revision: de93044a5f303a8eb847cfc1f97c490de7809189
URL: https://github.com/llvm/llvm-project/commit/de93044a5f303a8eb847cfc1f97c490de7809189 DIFF: https://github.com/llvm/llvm-project/commit/de93044a5f303a8eb847cfc1f97c490de7809189.diff LOG: [CIR] Replace coroutine unit attrs on FuncOp with a CoroutineKind enum attr (#234817) Follow-up to #203802. `cir.func` used two independent unit attributes, `coroutine` and`flattened_coroutine`, to track whether a function is a coroutine and whether its body has been flattened. Nothing prevented both from being set at once, and `FlattenCFG` had to clear one and set the other by hand. Replace them with a single optional `coroutine_kind` attribute backed by a new `CoroutineKind` enum (`coroutine`, `flattened_coroutine`). Added: Modified: clang/include/clang/CIR/Dialect/IR/CIRAttrs.td clang/include/clang/CIR/Dialect/IR/CIROps.td clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp clang/lib/CIR/Dialect/IR/CIRDialect.cpp clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp Removed: ################################################################################ diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index b3cc021989fde..54158e5b77d84 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -1852,6 +1852,36 @@ def CIR_FuncInfoAttr : AnyAttrOf<[ CIR_FuncIdentityAttr ], "function information attribute">; + +//===----------------------------------------------------------------------===// +// CoroutineKindAttr +//===----------------------------------------------------------------------===// + +def CIR_CoroutineKind : CIR_I32Enum<"CoroutineKind", "coroutine kind", [ + I32EnumCase<"Coroutine", 0, "coroutine">, + I32EnumCase<"FlattenedCoroutine", 1, "flattened_coroutine"> +]>; + +def CIR_CoroutineKindAttr : CIR_EnumAttr<CIR_CoroutineKind, "coroutine_kind"> { + let description = [{ + Marks a `cir.func` as a coroutine and records which form its body + is in. A function without this attribute is not a coroutine. + + - `coroutine`: the body still holds the structured `cir.coroutine` op + (and its `cir.await` / `cir.co_return` children), as emitted by CIRGen. + - `flattened_coroutine`: FlattenCFG has inlined those regions into plain + blocks. The function no longer contains a `cir.coroutine` op, but is + still a coroutine for the purposes of LLVM lowering. + + On `cir.func` it is printed as a bare keyword: + + ```mlir + cir.func coroutine @f() { ... } + cir.func flattened_coroutine @f() { ... } + ``` + }]; +} + //===----------------------------------------------------------------------===// // BitFieldDeclAttr //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 571231462236f..f22c15aea680a 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4386,8 +4386,7 @@ def CIR_FuncOp : CIR_Op<"func", [ >:$global_visibility, TypeAttrOf<CIR_FuncType>:$function_type, UnitAttr:$builtin, - UnitAttr:$coroutine, - UnitAttr:$flattened_coroutine, + OptionalAttr<CIR_CoroutineKindAttr>:$coroutine_kind, OptionalAttr<CIR_InlineKindAttr>:$inline_kind, UnitAttr:$lambda, UnitAttr:$no_proto, diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp index 0122d8a377b39..538db6747cf0b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp @@ -340,7 +340,7 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) { cir::ConstantOp nullPtrCst = builder.getNullPtr(voidPtrTy, openCurlyLoc); auto fn = mlir::cast<cir::FuncOp>(curFn); - fn.setCoroutine(true); + fn.setCoroutineKind(cir::CoroutineKind::Coroutine); const TargetInfo &ti = cgm.getASTContext().getTargetInfo(); unsigned newAlign = ti.getNewAlign() / ti.getCharWidth(); diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 7dcd0e9fefe29..838ea1e953e9b 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2923,9 +2923,7 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) { mlir::Builder &builder = parser.getBuilder(); mlir::StringAttr builtinNameAttr = getBuiltinAttrName(state.name); - mlir::StringAttr coroutineNameAttr = getCoroutineAttrName(state.name); - mlir::StringAttr flattenedCoroutineNameAttr = - getFlattenedCoroutineAttrName(state.name); + mlir::StringAttr coroutineKindNameAttr = getCoroutineKindAttrName(state.name); mlir::StringAttr inlineKindNameAttr = getInlineKindAttrName(state.name); mlir::StringAttr lambdaNameAttr = getLambdaAttrName(state.name); mlir::StringAttr noProtoNameAttr = getNoProtoAttrName(state.name); @@ -2939,14 +2937,19 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) { if (::mlir::succeeded(parser.parseOptionalKeyword(builtinNameAttr.strref()))) state.addAttribute(builtinNameAttr, parser.getBuilder().getUnitAttr()); - if (::mlir::succeeded( - parser.parseOptionalKeyword(coroutineNameAttr.strref()))) - state.addAttribute(coroutineNameAttr, parser.getBuilder().getUnitAttr()); - - if (::mlir::succeeded( - parser.parseOptionalKeyword(flattenedCoroutineNameAttr.strref()))) - state.addAttribute(flattenedCoroutineNameAttr, - parser.getBuilder().getUnitAttr()); + + // Parse optional coroutine kind attribute + { + static constexpr llvm::StringRef keywords[] = {"coroutine", + "flattened_coroutine"}; + llvm::StringRef keyword; + if (parser.parseOptionalKeyword(&keyword, keywords).succeeded()) + state.addAttribute( + coroutineKindNameAttr, + cir::CoroutineKindAttr::get(builder.getContext(), + *cir::symbolizeCoroutineKind(keyword))); + } + // Parse optional inline kind attribute cir::InlineKindAttr inlineKindAttr; if (failed(parseInlineKindAttr(parser, inlineKindAttr))) @@ -3289,11 +3292,8 @@ void cir::FuncOp::print(OpAsmPrinter &p) { if (getBuiltin()) p << " builtin"; - if (getCoroutine()) - p << " coroutine"; - - if (getFlattenedCoroutine()) - p << " flattened_coroutine"; + if (std::optional<cir::CoroutineKind> coroKind = getCoroutineKind()) + p << ' ' << cir::stringifyCoroutineKind(*coroKind); printInlineKindAttr(p, getInlineKindAttr()); @@ -3392,7 +3392,7 @@ void cir::FuncOp::print(OpAsmPrinter &p) { mlir::LogicalResult cir::FuncOp::verify() { - if (!isDeclaration() && getCoroutine()) { + if (!isDeclaration() && getCoroutineKind() == cir::CoroutineKind::Coroutine) { int coroutineOpCount = 0; this->walk([&](Operation *op) { if (isa<CoroutineOp>(op)) { diff --git a/clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp b/clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp index 87115ff26ed59..0bcdb90571f27 100644 --- a/clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp +++ b/clang/lib/CIR/Dialect/Transforms/FlattenCFG.cpp @@ -2324,8 +2324,7 @@ class CIRCoroutineFlattening : public mlir::OpRewritePattern<cir::CoroutineOp> { // The coroutine regions have been flattened, so the original coroutine // attribute no longer verifies. Preserve the information that this function // originated from a coroutine for LLVM lowering. - func.setCoroutine(false); - func.setFlattenedCoroutine(true); + func.setCoroutineKind(cir::CoroutineKind::FlattenedCoroutine); rewriter.eraseOp(coroOp); return mlir::success(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
