[clang] [CIR] Upstream initial support for switch statements (PR #137106)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 28 11:31:30 PDT 2025
================
@@ -422,6 +428,121 @@ mlir::LogicalResult CIRGenFunction::emitBreakStmt(const clang::BreakStmt &s) {
return mlir::success();
}
+template <typename T>
+mlir::LogicalResult
+CIRGenFunction::emitCaseDefaultCascade(const T *stmt, mlir::Type condType,
+ mlir::ArrayAttr value, CaseOpKind kind,
+ bool buildingTopLevelCase) {
+
+ assert((isa<CaseStmt, DefaultStmt>(stmt)) &&
+ "only case or default stmt go here");
+
+ mlir::LogicalResult result = mlir::success();
+
+ mlir::Location loc = getLoc(stmt->getBeginLoc());
+
+ enum class SubStmtKind { Case, Default, Other };
+ SubStmtKind subStmtKind = SubStmtKind::Other;
+ const Stmt *sub = stmt->getSubStmt();
+
+ mlir::OpBuilder::InsertPoint insertPoint;
+ builder.create<CaseOp>(loc, value, kind, insertPoint);
+
+ {
+ mlir::OpBuilder::InsertionGuard guardSwitch(builder);
+ builder.restoreInsertionPoint(insertPoint);
+
+ if (isa<DefaultStmt>(sub) && isa<CaseStmt>(stmt)) {
+ subStmtKind = SubStmtKind::Default;
+ builder.createYield(loc);
+ } else if (isa<CaseStmt>(sub) && isa<DefaultStmt>(stmt)) {
+ subStmtKind = SubStmtKind::Case;
+ builder.createYield(loc);
+ } else
+ result = emitStmt(sub, /*useCurrentScope=*/!isa<CompoundStmt>(sub));
+
+ insertPoint = builder.saveInsertionPoint();
+ }
+
+ // If the substmt is default stmt or case stmt, try to handle the special case
+ // to make it into the simple form. e.g.
+ //
+ // swtich () {
+ // case 1:
+ // default:
+ // ...
+ // }
+ //
+ // we prefer generating
+ //
+ // cir.switch() {
+ // cir.case(equal, 1) {
+ // cir.yield
+ // }
+ // cir.case(default) {
+ // ...
+ // }
+ // }
+ //
+ // than
+ //
+ // cir.switch() {
+ // cir.case(equal, 1) {
+ // cir.case(default) {
+ // ...
+ // }
+ // }
+ // }
+ //
+ // We don't need to revert this if we find the current switch can't be in
+ // simple form later since the conversion itself should be harmless.
+ if (subStmtKind == SubStmtKind::Case)
+ result = emitCaseStmt(*cast<CaseStmt>(sub), condType, buildingTopLevelCase);
+ else if (subStmtKind == SubStmtKind::Default) {
----------------
Andres-Salamanca wrote:
Done
https://github.com/llvm/llvm-project/pull/137106
More information about the cfe-commits
mailing list