[clang] [CIR] Upstream support for switch statements case kinds (PR #138003)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Thu May 1 11:17:37 PDT 2025
================
@@ -428,6 +429,52 @@ mlir::LogicalResult CIRGenFunction::emitBreakStmt(const clang::BreakStmt &s) {
return mlir::success();
}
+const CaseStmt *CIRGenFunction::foldCaseStmt(const clang::CaseStmt &s,
+ mlir::Type condType,
+ mlir::ArrayAttr &value,
+ cir::CaseOpKind &kind) {
+ const CaseStmt *caseStmt = &s;
+ const CaseStmt *lastCase = &s;
+ SmallVector<mlir::Attribute, 4> caseEltValueListAttr;
+
+ // Fold cascading cases whenever possible to simplify codegen a bit.
+ while (caseStmt) {
+ lastCase = caseStmt;
+
+ auto intVal = caseStmt->getLHS()->EvaluateKnownConstInt(getContext());
+
+ if (auto *rhs = caseStmt->getRHS()) {
+ auto endVal = rhs->EvaluateKnownConstInt(getContext());
+ SmallVector<mlir::Attribute, 4> rangeCaseAttr = {
+ cir::IntAttr::get(condType, intVal),
+ cir::IntAttr::get(condType, endVal)};
+ value = builder.getArrayAttr(rangeCaseAttr);
+ kind = cir::CaseOpKind::Range;
+
+ // We may not be able to fold rangaes. Due to we can't present range case
+ // with other trivial cases now.
+ return caseStmt;
+ }
+
+ caseEltValueListAttr.push_back(cir::IntAttr::get(condType, intVal));
+
+ caseStmt = dyn_cast_or_null<CaseStmt>(caseStmt->getSubStmt());
+
+ // Break early if we found ranges. We can't fold ranges due to the same
+ // reason above.
+ if (caseStmt && caseStmt->getRHS())
+ break;
+ }
+
+ if (!caseEltValueListAttr.empty()) {
+ value = builder.getArrayAttr(caseEltValueListAttr);
+ kind = caseEltValueListAttr.size() > 1 ? cir::CaseOpKind::Anyof
----------------
andykaylor wrote:
I agree that this should be moved to an optimization pass. Perhaps CIRSimplify?
https://github.com/llvm/llvm-project/pull/138003
More information about the cfe-commits
mailing list