================ @@ -753,6 +755,221 @@ def ScopeOp : CIR_Op<"scope", [ ]; } +//===----------------------------------------------------------------------===// +// SwitchOp +//===----------------------------------------------------------------------===// + +def CaseOpKind_DT : I32EnumAttrCase<"Default", 1, "default">; +def CaseOpKind_EQ : I32EnumAttrCase<"Equal", 2, "equal">; +def CaseOpKind_AO : I32EnumAttrCase<"Anyof", 3, "anyof">; +def CaseOpKind_RG : I32EnumAttrCase<"Range", 4, "range">; + +def CaseOpKind : I32EnumAttr< + "CaseOpKind", + "case kind", + [CaseOpKind_DT, CaseOpKind_EQ, CaseOpKind_AO, CaseOpKind_RG]> { + let cppNamespace = "::cir"; +} + +def CaseOp : CIR_Op<"case", [ + DeclareOpInterfaceMethods<RegionBranchOpInterface>, + RecursivelySpeculatable, AutomaticAllocationScope]> { + let summary = "Case operation"; + let description = [{ + The `cir.case` operation represents a case within a C/C++ switch. + The `cir.case` operation must be in a `cir.switch` operation directly + or indirectly. + + The `cir.case` have 4 kinds: + - `equal, <constant>`: equality of the second case operand against the + condition. + - `anyof, [constant-list]`: equals to any of the values in a subsequent + following list. + - `range, [lower-bound, upper-bound]`: the condition is within the closed + interval. + - `default`: any other value. + + Each case region must be explicitly terminated. + }]; + + let arguments = (ins ArrayAttr:$value, CaseOpKind:$kind); + let regions = (region AnyRegion:$caseRegion); + + let assemblyFormat = "`(` $kind `,` $value `)` $caseRegion attr-dict"; + + let skipDefaultBuilders = 1; + let builders = [ + OpBuilder<(ins "mlir::ArrayAttr":$value, + "CaseOpKind":$kind, + "mlir::OpBuilder::InsertPoint &":$insertPoint)> + ]; +} + +def SwitchOp : CIR_Op<"switch", + [SameVariadicOperandSize, + DeclareOpInterfaceMethods<RegionBranchOpInterface>, + RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments]> { + let summary = "Switch operation"; + let description = [{ + The `cir.switch` operation represents C/C++ switch functionality for + conditionally executing multiple regions of code. The operand to an switch + is an integral condition value. + + The set of `cir.case` operations and their enclosing `cir.switch` + represents the semantics of a C/C++ switch statement. Users can use + `collectCases(llvm::SmallVector<CaseOp> &cases)` to collect the `cir.case` + operation in the `cir.switch` operation easily. + + The `cir.case` operations doesn't have to be in the region of `cir.switch` + directly. However, when all the `cir.case` operations lives in the region + of `cir.switch` directly and there is no other operations except the ending + `cir.yield` operation in the region of `cir.switch` directly, we call the ---------------- andykaylor wrote:
```suggestion `cir.yield` operation in the region of `cir.switch` directly, we say the ``` 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