================ @@ -802,6 +804,132 @@ 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(); +} + +LogicalResult cir::CaseOp::verify() { return success(); } + +//===----------------------------------------------------------------------===// +// 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())); +} + +LogicalResult cir::SwitchOp::verify() { return success(); } + +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(); + }); +} + +// Check if the switch is in a simple form. If yes, collect the cases to \param +// cases. This is an expensive and need to be used with caution. ---------------- xlauko wrote:
This is not true as it collects cases also in the case it is not in simple form. https://github.com/llvm/llvm-project/pull/137106 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits