[clang] [CIR] Upstream initial support for switch statements (PR #137106)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 28 11:32:11 PDT 2025
================
@@ -802,6 +804,126 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef<Attribute> operands) {
return nullptr;
}
+//===----------------------------------------------------------------------===//
+// CaseOp
+//===----------------------------------------------------------------------===//
+
+void cir::CaseOp::getSuccessorRegions(
+ mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) {
+ if (!point.isParent()) {
+ regions.push_back(RegionSuccessor());
+ return;
+ }
+ regions.push_back(RegionSuccessor(&getCaseRegion()));
+}
+
+void cir::CaseOp::build(OpBuilder &builder, OperationState &result,
+ ArrayAttr value, CaseOpKind kind,
+ OpBuilder::InsertPoint &insertPoint) {
+ OpBuilder::InsertionGuard guardSwitch(builder);
+ result.addAttribute("value", value);
+ result.getOrAddProperties<Properties>().kind =
+ cir::CaseOpKindAttr::get(builder.getContext(), kind);
+ Region *caseRegion = result.addRegion();
+ builder.createBlock(caseRegion);
+
+ insertPoint = builder.saveInsertionPoint();
+}
+
+//===----------------------------------------------------------------------===//
+// SwitchOp
+//===----------------------------------------------------------------------===//
+
+static ParseResult parseSwitchOp(OpAsmParser &parser, mlir::Region ®ions,
+ mlir::OpAsmParser::UnresolvedOperand &cond,
+ mlir::Type &condType) {
+ cir::IntType intCondType;
+
+ if (parser.parseLParen())
+ return mlir::failure();
+
+ if (parser.parseOperand(cond))
+ return mlir::failure();
+ if (parser.parseColon())
+ return mlir::failure();
+ if (parser.parseCustomTypeWithFallback(intCondType))
+ return mlir::failure();
+ condType = intCondType;
+
+ if (parser.parseRParen())
+ return mlir::failure();
+ if (parser.parseRegion(regions, /*arguments=*/{}, /*argTypes=*/{}))
+ return failure();
+
+ return mlir::success();
+}
+
+static void printSwitchOp(OpAsmPrinter &p, cir::SwitchOp op,
+ mlir::Region &bodyRegion, mlir::Value condition,
+ mlir::Type condType) {
+ p << "(";
+ p << condition;
+ p << " : ";
+ p.printStrippedAttrOrType(condType);
+ p << ")";
+
+ p << ' ';
+ p.printRegion(bodyRegion, /*printEntryBlockArgs=*/false,
+ /*printBlockTerminators=*/true);
+}
+
+void cir::SwitchOp::getSuccessorRegions(
+ mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ion) {
+ if (!point.isParent()) {
+ region.push_back(RegionSuccessor());
+ return;
+ }
+
+ region.push_back(RegionSuccessor(&getBody()));
+}
+
+void cir::SwitchOp::build(
+ OpBuilder &builder, OperationState &result, Value cond,
+ function_ref<void(OpBuilder &, Location, OperationState &)> switchBuilder) {
+ assert(switchBuilder && "the builder callback for regions must be present");
+ OpBuilder::InsertionGuard guardSwitch(builder);
+ Region *switchRegion = result.addRegion();
+ builder.createBlock(switchRegion);
+ result.addOperands({cond});
+ switchBuilder(builder, result.location, result);
+}
+
+void cir::SwitchOp::collectCases(llvm::SmallVector<CaseOp> &cases) {
+ walk<mlir::WalkOrder::PreOrder>([&](mlir::Operation *op) {
+ // Don't walk in nested switch op.
+ if (isa<cir::SwitchOp>(op) && op != *this)
+ return WalkResult::skip();
+
+ if (auto caseOp = dyn_cast<cir::CaseOp>(op))
+ cases.push_back(caseOp);
+
+ return WalkResult::advance();
+ });
+}
+
+bool cir::SwitchOp::isSimpleForm(llvm::SmallVector<CaseOp> &cases) {
----------------
Andres-Salamanca wrote:
Done
https://github.com/llvm/llvm-project/pull/137106
More information about the cfe-commits
mailing list