Skip to content

[CIR] Clean up enum attributes #144999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

xlauko
Copy link
Contributor

@xlauko xlauko commented Jun 20, 2025

This mirrors incubator changes from llvm/clangir#1678

  • Create CIR specific EnumAttr bases and prefix enum attributes with CIR_ that automatically puts enum to cir namespace

  • Removes unnecessary enum case definitions

  • Unifies naming of enum values to use capitals consistently and make enumerations to start from 0

This mirrors incubator changes from llvm/clangir#1678

- Create CIR specific EnumAttr bases and prefix enum attributes with CIR_ that automatically puts enum to cir namespace

- Removes unnecessary enum case definitions

- Unifies naming of enum values to use capitals consistently and make enumerations to start from 0
@xlauko
Copy link
Contributor Author

xlauko commented Jun 20, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@xlauko xlauko marked this pull request as ready for review June 20, 2025 09:00
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Jun 20, 2025
@xlauko xlauko requested a review from andykaylor June 20, 2025 09:01
@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

@llvm/pr-subscribers-clangir

Author: Henrich Lauko (xlauko)

Changes

This mirrors incubator changes from llvm/clangir#1678

  • Create CIR specific EnumAttr bases and prefix enum attributes with CIR_ that automatically puts enum to cir namespace

  • Removes unnecessary enum case definitions

  • Unifies naming of enum values to use capitals consistently and make enumerations to start from 0


Patch is 22.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144999.diff

2 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+22-15)
  • (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+189-235)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 9e01dde379d7a..03e970db2847d 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -47,6 +47,16 @@ class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
   let cppNamespace = "::cir";
 }
 
+class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
+    : I64EnumAttr<name, summary, cases> {
+  let cppNamespace = "::cir";
+}
+
+class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
+    : EnumAttr<CIR_Dialect, info, name, traits> {
+  let assemblyFormat = "`<` $value `>`";
+}
+
 class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
     : CIR_Attr<name, attrMnemonic, traits> {
   let returnType = "bool";
@@ -330,36 +340,33 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex",
 // VisibilityAttr
 //===----------------------------------------------------------------------===//
 
-def CIR_VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
-  I32EnumAttrCase<"Default", 1, "default">,
-  I32EnumAttrCase<"Hidden", 2, "hidden">,
-  I32EnumAttrCase<"Protected", 3, "protected">
+def CIR_VisibilityKind : CIR_I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
+  I32EnumAttrCase<"Default", 0, "default">,
+  I32EnumAttrCase<"Hidden", 1, "hidden">,
+  I32EnumAttrCase<"Protected", 2, "protected">
 ]> {
   let genSpecializedAttr = 0;
-  let cppNamespace = "::cir";
 }
 
-def CIR_VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
+def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> {
   let summary = "Visibility attribute";
   let description = [{
     Visibility attributes.
   }];
-  let parameters = (ins "VisibilityKind":$value);
 
-  let assemblyFormat = [{
-    $value
-  }];
+  let cppClassName = "VisibilityAttr";
 
+  let skipDefaultBuilders = 1;
   let builders = [
-    AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{
+    AttrBuilder<(ins CArg<"VisibilityKind",
+                          "cir::VisibilityKind::Default">:$value), [{
       return $_get($_ctxt, value);
     }]>
   ];
 
-  let skipDefaultBuilders = 1;
-
-  // Make DefaultValuedAttr accept VisibilityKind as default value ($0).
-  let constBuilderCall = "cir::VisibilityAttr::get($_builder.getContext(), $0)";
+  let assemblyFormat = [{
+    $value
+  }];
 
   let extraClassDeclaration = [{
     bool isDefault() const { return getValue() == VisibilityKind::Default; };
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 852d3aa131148..f978bd9a96bcf 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -91,94 +91,80 @@ def SameFirstOperandAndResultType :
 // CastOp
 //===----------------------------------------------------------------------===//
 
-// CK_Dependent
-def CK_BitCast : I32EnumAttrCase<"bitcast", 1>;
-// CK_LValueBitCast
-// CK_LValueToRValueBitCast
-// CK_LValueToRValue
-// CK_NoOp
-// CK_BaseToDerived
-// CK_DerivedToBase
-// CK_UncheckedDerivedToBase
-// CK_Dynamic
-// CK_ToUnion
-def CK_ArrayToPointerDecay : I32EnumAttrCase<"array_to_ptrdecay", 11>;
-// CK_FunctionToPointerDecay
-// CK_NullToPointer
-// CK_NullToMemberPointer
-// CK_BaseToDerivedMemberPointer
-// CK_DerivedToBaseMemberPointer
-def CK_MemberPointerToBoolean : I32EnumAttrCase<"member_ptr_to_bool", 17>;
-// CK_ReinterpretMemberPointer
-// CK_UserDefinedConversion
-// CK_ConstructorConversion
-def CK_IntegralToPointer : I32EnumAttrCase<"int_to_ptr", 21>;
-def CK_PointerToIntegral : I32EnumAttrCase<"ptr_to_int", 22>;
-def CK_PointerToBoolean : I32EnumAttrCase<"ptr_to_bool", 23>;
-// CK_ToVoid
-// CK_MatrixCast
-// CK_VectorSplat
-def CK_IntegralCast : I32EnumAttrCase<"integral", 27>;
-def CK_IntegralToBoolean : I32EnumAttrCase<"int_to_bool", 28>;
-def CK_IntegralToFloating : I32EnumAttrCase<"int_to_float", 29>;
-// CK_FloatingToFixedPoint
-// CK_FixedPointToFloating
-// CK_FixedPointCast
-// CK_FixedPointToIntegral
-// CK_IntegralToFixedPoint
-// CK_FixedPointToBoolean
-def CK_FloatingToIntegral : I32EnumAttrCase<"float_to_int", 36>;
-def CK_FloatingToBoolean : I32EnumAttrCase<"float_to_bool", 37>;
-def CK_BooleanToSignedIntegral : I32EnumAttrCase<"bool_to_int", 38>;
-def CK_FloatingCast : I32EnumAttrCase<"floating", 39>;
-// CK_CPointerToObjCPointerCast
-// CK_BlockPointerToObjCPointerCast
-// CK_AnyPointerToBlockPointerCast
-// CK_ObjCObjectLValueCast
-// CK_FloatingRealToComplex
-// CK_FloatingComplexToReal
-// CK_FloatingComplexToBoolean
-def CK_FloatingComplexCast : I32EnumAttrCase<"float_complex", 47>;
-// CK_FloatingComplexToIntegralComplex
-// CK_IntegralRealToComplex
-def CK_IntegralComplexToReal : I32EnumAttrCase<"int_complex_to_real", 50>;
-def CK_IntegralComplexToBoolean : I32EnumAttrCase<"int_complex_to_bool", 51>;
-def CK_IntegralComplexCast : I32EnumAttrCase<"int_complex", 52>;
-def CK_IntegralComplexToFloatingComplex
-    : I32EnumAttrCase<"int_complex_to_float_complex", 53>;
-// CK_ARCProduceObject
-// CK_ARCConsumeObject
-// CK_ARCReclaimReturnedObject
-// CK_ARCExtendBlockObject
-// CK_AtomicToNonAtomic
-// CK_NonAtomicToAtomic
-// CK_CopyAndAutoreleaseBlockObject
-// CK_BuiltinFnToFnPtr
-// CK_ZeroToOCLOpaqueType
-def CK_AddressSpaceConversion : I32EnumAttrCase<"address_space", 63>;
-// CK_IntToOCLSampler
-// CK_HLSLVectorTruncation
-// CK_HLSLArrayRValue
-// CK_HLSLElementwiseCast
-// CK_HLSLAggregateSplatCast
-
-// Enums below are specific to CIR and don't have a correspondence to classic
-// codegen:
-def CK_BooleanToFloat : I32EnumAttrCase<"bool_to_float", 1000>;
-
-def CastKind : I32EnumAttr<
-    "CastKind",
-    "cast kind",
-    [CK_BitCast, CK_ArrayToPointerDecay, CK_MemberPointerToBoolean,
-     CK_IntegralToPointer, CK_PointerToIntegral, CK_PointerToBoolean,
-     CK_IntegralCast, CK_IntegralToBoolean, CK_IntegralToFloating,
-     CK_FloatingToIntegral, CK_FloatingToBoolean, CK_BooleanToSignedIntegral,
-     CK_FloatingCast, CK_FloatingComplexCast, CK_IntegralComplexToReal,
-     CK_IntegralComplexToBoolean, CK_IntegralComplexCast,
-     CK_IntegralComplexToFloatingComplex, CK_AddressSpaceConversion,
-     CK_BooleanToFloat]> {
-  let cppNamespace = "::cir";
-}
+def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [
+  I32EnumAttrCase<"bitcast", 1>,
+  // CK_LValueBitCast
+  // CK_LValueToRValueBitCast
+  // CK_LValueToRValue
+  // CK_NoOp
+  // CK_BaseToDerived
+  // CK_DerivedToBase
+  // CK_UncheckedDerivedToBase
+  // CK_Dynamic
+  // CK_ToUnion
+  I32EnumAttrCase<"array_to_ptrdecay", 11>,
+  // CK_FunctionToPointerDecay
+  // CK_NullToPointer
+  // CK_NullToMemberPointer
+  // CK_BaseToDerivedMemberPointer
+  // CK_DerivedToBaseMemberPointer
+  I32EnumAttrCase<"member_ptr_to_bool", 17>,
+  // CK_ReinterpretMemberPointer
+  // CK_UserDefinedConversion
+  // CK_ConstructorConversion
+  I32EnumAttrCase<"int_to_ptr", 21>,
+  I32EnumAttrCase<"ptr_to_int", 22>,
+  I32EnumAttrCase<"ptr_to_bool", 23>,
+  // CK_ToVoid
+  // CK_MatrixCast
+  // CK_VectorSplat
+  I32EnumAttrCase<"integral", 27>,
+  I32EnumAttrCase<"int_to_bool", 28>,
+  I32EnumAttrCase<"int_to_float", 29>,
+  // CK_FloatingToFixedPoint
+  // CK_FixedPointToFloating
+  // CK_FixedPointCast
+  // CK_FixedPointToIntegral
+  // CK_IntegralToFixedPoint
+  // CK_FixedPointToBoolean
+  I32EnumAttrCase<"float_to_int", 36>,
+  I32EnumAttrCase<"float_to_bool", 37>,
+  I32EnumAttrCase<"bool_to_int", 38>,
+  I32EnumAttrCase<"floating", 39>,
+  // CK_CPointerToObjCPointerCast
+  // CK_BlockPointerToObjCPointerCast
+  // CK_AnyPointerToBlockPointerCast
+  // CK_ObjCObjectLValueCast
+  // I32EnumAttrCase<"float_to_complex", 44>,
+  // I32EnumAttrCase<"float_complex_to_real", 45>,
+  // I32EnumAttrCase<"float_complex_to_bool", 46>,
+  I32EnumAttrCase<"float_complex", 47>,
+  // I32EnumAttrCase<"float_complex_to_int_complex", 48>,
+  // I32EnumAttrCase<"int_to_complex", 49>,
+  I32EnumAttrCase<"int_complex_to_real", 50>,
+  I32EnumAttrCase<"int_complex_to_bool", 51>,
+  I32EnumAttrCase<"int_complex", 52>,
+  I32EnumAttrCase<"int_complex_to_float_complex", 53>,
+  // CK_ARCProduceObject
+  // CK_ARCConsumeObject
+  // CK_ARCReclaimReturnedObject
+  // CK_ARCExtendBlockObject
+  // CK_AtomicToNonAtomic
+  // CK_NonAtomicToAtomic
+  // CK_CopyAndAutoreleaseBlockObject
+  // CK_BuiltinFnToFnPtr
+  // CK_ZeroToOCLOpaqueType
+  I32EnumAttrCase<"address_space", 63>,
+  // CK_IntToOCLSampler
+  // CK_HLSLVectorTruncation
+  // CK_HLSLArrayRValue
+  // CK_HLSLElementwiseCast
+  // CK_HLSLAggregateSplatCast
+
+  // Enums below are specific to CIR and don't have a correspondence to classic
+  // codegen:
+  I32EnumAttrCase<"bool_to_float", 1000>,
+]>;
 
 def CastOp : CIR_Op<"cast",
              [Pure,
@@ -186,45 +172,49 @@ def CastOp : CIR_Op<"cast",
   // FIXME: not all conversions are free of side effects.
   let summary = "Conversion between values of different types";
   let description = [{
-    Apply C/C++ usual conversions rules between values. Currently supported kinds:
+    Apply the usual C/C++ conversion rules between values. This operation models
+    a subset of conversions as defined in Clang's `OperationKinds.def`
+    (`llvm-project/clang/include/clang/AST/OperationKinds.def`).
+
+    Note: not all conversions are implemented using `cir.cast`. For instance,
+    lvalue-to-rvalue conversion is modeled as a `cir.load` instead.  Currently
+    supported kinds:
 
-    - `array_to_ptrdecay`
     - `bitcast`
+    - `array_to_ptrdecay`
+    - `member_ptr_to_bool
+    - `int_to_ptr`
+    - `ptr_to_int`
+    - `ptr_to_bool`
     - `integral`
     - `int_to_bool`
     - `int_to_float`
-    - `floating`
     - `float_to_int`
     - `float_to_bool`
-    - `ptr_to_int`
-    - `ptr_to_bool`
     - `bool_to_int`
-    - `bool_to_float`
-    - `address_space`
-    - `float_to_complex`
-    - `int_to_complex`
-    - `float_complex_to_real`
+    - `floating`
+    - `float_complex`
     - `int_complex_to_real`
-    - `float_complex_to_bool`
     - `int_complex_to_bool`
-    - `float_complex`
-    - `float_complex_to_int_complex`
     - `int_complex`
     - `int_complex_to_float_complex`
+    - `address_space`
+
+    CIR also supports some additional conversions that are not part of the classic
+    Clang codegen:
 
-    This is effectively a subset of the rules from
-    `llvm-project/clang/include/clang/AST/OperationKinds.def`; but note that some
-    of the conversions aren't implemented in terms of `cir.cast`, `lvalue-to-rvalue`
-    for instance is modeled as a regular `cir.load`.
+    - `bool_to_float`
+
+    Example:
 
     ```mlir
-    %4 = cir.cast (int_to_bool, %3 : i32), !cir.bool
+    %4 = cir.cast(int_to_bool, %3 : i32), !cir.bool
     ...
     %x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr<!cir.array<i32 x 10>>), !cir.ptr<i32>
     ```
   }];
 
-  let arguments = (ins CastKind:$kind, CIR_AnyType:$src);
+  let arguments = (ins CIR_CastKind:$kind, CIR_AnyType:$src);
   let results = (outs CIR_AnyType:$result);
 
   let assemblyFormat = [{
@@ -767,17 +757,12 @@ 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 CIR_CaseOpKind : CIR_I32EnumAttr<"CaseOpKind", "case kind", [
+  I32EnumAttrCase<"Default", 0, "default">,
+  I32EnumAttrCase<"Equal", 1, "equal">,
+  I32EnumAttrCase<"Anyof", 2, "anyof">,
+  I32EnumAttrCase<"Range", 3, "range">
+]>;
 
 def CaseOp : CIR_Op<"case", [
        DeclareOpInterfaceMethods<RegionBranchOpInterface>,
@@ -800,7 +785,7 @@ def CaseOp : CIR_Op<"case", [
     Each case region must be explicitly terminated.
   }];
 
-  let arguments = (ins ArrayAttr:$value, CaseOpKind:$kind);
+  let arguments = (ins ArrayAttr:$value, CIR_CaseOpKind:$kind);
   let regions = (region AnyRegion:$caseRegion);
 
   let assemblyFormat = "`(` $kind `,` $value `)` $caseRegion attr-dict";
@@ -1067,23 +1052,13 @@ def BrOp : CIR_Op<"br",
 // UnaryOp
 //===----------------------------------------------------------------------===//
 
-def UnaryOpKind_Inc   : I32EnumAttrCase<"Inc",   1, "inc">;
-def UnaryOpKind_Dec   : I32EnumAttrCase<"Dec",   2, "dec">;
-def UnaryOpKind_Plus  : I32EnumAttrCase<"Plus",  3, "plus">;
-def UnaryOpKind_Minus : I32EnumAttrCase<"Minus", 4, "minus">;
-def UnaryOpKind_Not   : I32EnumAttrCase<"Not",   5, "not">;
-
-def UnaryOpKind : I32EnumAttr<
-    "UnaryOpKind",
-    "unary operation kind",
-    [UnaryOpKind_Inc,
-     UnaryOpKind_Dec,
-     UnaryOpKind_Plus,
-     UnaryOpKind_Minus,
-     UnaryOpKind_Not,
-     ]> {
-  let cppNamespace = "::cir";
-}
+def CIR_UnaryOpKind : CIR_I32EnumAttr<"UnaryOpKind", "unary operation kind", [
+  I32EnumAttrCase<"Inc",   0, "inc">,
+  I32EnumAttrCase<"Dec",   1, "dec">,
+  I32EnumAttrCase<"Plus",  2, "plus">,
+  I32EnumAttrCase<"Minus", 3, "minus">,
+  I32EnumAttrCase<"Not",   4, "not">
+]>;
 
 def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> {
   let summary = "Unary operations";
@@ -1103,10 +1078,13 @@ def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> {
     ```
   }];
 
+  let arguments = (ins
+    Arg<CIR_UnaryOpKind, "unary op kind">:$kind,
+    Arg<CIR_AnyType>:$input,
+    UnitAttr:$no_signed_wrap
+  );
+
   let results = (outs CIR_AnyType:$result);
-  let arguments = (ins Arg<UnaryOpKind, "unary op kind">:$kind,
-                   Arg<CIR_AnyType>:$input,
-                   UnitAttr:$no_signed_wrap);
 
   let assemblyFormat = [{
       `(` $kind `,` $input `)`
@@ -1331,20 +1309,14 @@ def ForOp : LoopOpBase<"for"> {
 // CmpOp
 //===----------------------------------------------------------------------===//
 
-def CmpOpKind_LT : I32EnumAttrCase<"lt", 1>;
-def CmpOpKind_LE : I32EnumAttrCase<"le", 2>;
-def CmpOpKind_GT : I32EnumAttrCase<"gt", 3>;
-def CmpOpKind_GE : I32EnumAttrCase<"ge", 4>;
-def CmpOpKind_EQ : I32EnumAttrCase<"eq", 5>;
-def CmpOpKind_NE : I32EnumAttrCase<"ne", 6>;
-
-def CmpOpKind : I32EnumAttr<
-    "CmpOpKind",
-    "compare operation kind",
-    [CmpOpKind_LT, CmpOpKind_LE, CmpOpKind_GT,
-     CmpOpKind_GE, CmpOpKind_EQ, CmpOpKind_NE]> {
-  let cppNamespace = "::cir";
-}
+def CIR_CmpOpKind : CIR_I32EnumAttr<"CmpOpKind", "compare operation kind", [
+  I32EnumAttrCase<"lt", 0>,
+  I32EnumAttrCase<"le", 1>,
+  I32EnumAttrCase<"gt", 2>,
+  I32EnumAttrCase<"ge", 3>,
+  I32EnumAttrCase<"eq", 4>,
+  I32EnumAttrCase<"ne", 5>
+]>;
 
 def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
 
@@ -1359,9 +1331,13 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
     ```
   }];
 
+  let arguments = (ins
+    CIR_CmpOpKind:$kind,
+    CIR_AnyType:$lhs,
+    CIR_AnyType:$rhs
+  );
+
   let results = (outs CIR_BoolType:$result);
-  let arguments = (ins Arg<CmpOpKind, "cmp kind">:$kind,
-                       CIR_AnyType:$lhs, CIR_AnyType:$rhs);
 
   let assemblyFormat = [{
     `(` $kind `,` $lhs `,` $rhs  `)` `:` type($lhs) `,` type($result) attr-dict
@@ -1373,26 +1349,18 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
 //===----------------------------------------------------------------------===//
 
 // FIXME: represent Commutative, Idempotent traits for appropriate binops
-def BinOpKind_Mul : I32EnumAttrCase<"Mul", 1, "mul">;
-def BinOpKind_Div : I32EnumAttrCase<"Div", 2, "div">;
-def BinOpKind_Rem : I32EnumAttrCase<"Rem", 3, "rem">;
-def BinOpKind_Add : I32EnumAttrCase<"Add", 4, "add">;
-def BinOpKind_Sub : I32EnumAttrCase<"Sub", 5, "sub">;
-def BinOpKind_And : I32EnumAttrCase<"And", 8, "and">;
-def BinOpKind_Xor : I32EnumAttrCase<"Xor", 9, "xor">;
-def BinOpKind_Or  : I32EnumAttrCase<"Or", 10, "or">;
-// TODO(cir): Do we need a min binop?
-def BinOpKind_Max : I32EnumAttrCase<"Max", 11, "max">;
-
-def BinOpKind : I32EnumAttr<
-    "BinOpKind",
-    "binary operation (arith and logic) kind",
-    [BinOpKind_Mul, BinOpKind_Div, BinOpKind_Rem,
-     BinOpKind_Add, BinOpKind_Sub,
-     BinOpKind_And, BinOpKind_Xor,
-     BinOpKind_Or, BinOpKind_Max]> {
-  let cppNamespace = "::cir";
-}
+def CIR_BinOpKind : CIR_I32EnumAttr<
+  "BinOpKind", "binary operation (arith and logic) kind", [
+    I32EnumAttrCase<"Mul", 0, "mul">,
+    I32EnumAttrCase<"Div", 1, "div">,
+    I32EnumAttrCase<"Rem", 2, "rem">,
+    I32EnumAttrCase<"Add", 3, "add">,
+    I32EnumAttrCase<"Sub", 4, "sub">,
+    I32EnumAttrCase<"And", 5, "and">,
+    I32EnumAttrCase<"Xor", 6, "xor">,
+    I32EnumAttrCase<"Or", 7, "or">,
+    I32EnumAttrCase<"Max", 8, "max">
+]>;
 
 def BinOp : CIR_Op<"binop", [Pure,
   SameTypeOperands, SameOperandsAndResultType]> {
@@ -1424,13 +1392,16 @@ def BinOp : CIR_Op<"binop", [Pure,
     ```
   }];
 
+  let arguments = (ins
+    CIR_BinOpKind:$kind,
+    CIR_AnyType:$lhs, CIR_AnyType:$rhs,
+    UnitAttr:$no_unsigned_wrap,
+    UnitAttr:$no_signed_wrap,
+    UnitAttr:$saturated
+  );
+
   // TODO: get more accurate than CIR_AnyType
   let results = (outs CIR_AnyType:$result);
-  let arguments = (ins Arg<BinOpKind, "binop kind">:$kind,
-                       CIR_AnyType:$lhs, CIR_AnyType:$rhs,
-                       UnitAttr:$no_unsigned_wrap,
-                       UnitAttr:$no_signed_wrap,
-                       UnitAttr:$saturated);
 
   let assemblyFormat = [{
     `(` $kind `,` $lhs `,` $rhs  `)`
@@ -1586,54 +1557,34 @@ def TernaryOp : CIR_Op<"ternary",
 // currently handy as part of forwarding appropriate linkage types for LLVM
 // lowering, specially useful for C++ support.
 
-// Externally visible function
-def Global_ExternalLinkage :
-  I32EnumAttrCase<"ExternalLinkage", 0, "external">;
-// Available for inspection, not emission.
-def Global_AvailableExternallyLinkage :
-  I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">;
-// Keep one copy of function when linking (inline)
-def Global_LinkOnceAnyLinkage :
-  I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">;
-// Same, but only replaced by something equivalent.
-def Global_LinkOnceODRLinkage :
-  I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">;
-// Keep one copy of named function when linking (weak)
-def Global_WeakAnyLinkage :
-  I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">;
-// Same, but only replaced by something equivalent.
-def Global_WeakODRLinkage :
-  I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">;
-// TODO: should we add something like appending linkage too?
-// Special purpose, only applies to global arrays
-// def Global_AppendingLinkage :
-//   I32EnumAttrCase<"AppendingLinkage", 6, "appending">;
-// Rename collisions when linking (static functions).
-def Global_InternalLinkage :
-  I32EnumAttrCase<"InternalLinkage", 7, "internal">;
-// Like Internal, but omit from symbol table, prefix it with
-// "cir_" to prevent clash with MLIR's symbol "private".
-def Global_PrivateLinkage :
-  I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">;
-// ExternalWeak linkage description.
-def Global_ExternalWeakLinkage :
-  I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">;
-// Tentative definitions.
-def Global_CommonLinkage :
-  I32EnumAttrCase<"CommonLinkage", 10, "common">;
-
 /// An enumeration for the kinds of linkage for global values.
-def GlobalLinkageKind : I32EnumAttr<
-    "GlobalLinkageKind",
-    "Linkage type/kind",
-    [Global_ExternalLinkage, Global_AvailableExternallyLinkage,
-     Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage,
-     Global_WeakAnyLinkage, Global_WeakODRLinkage,
-     Global_InternalLinkage, Global_PrivateLinkage,
-     Global_ExternalWeakLinkage, Global_CommonLinkage
-     ]> {
-  let cppNamespace = "::cir";
-}
+def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
+  "GlobalLinkageKind", "linkage kind", [
+    // Externally visible function
+    I32EnumAttrCase<"ExternalLinkage", 0, "external">,
+    // Available for inspection, not emission.
+    I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">,
+    // Keep one copy of function when linking (inline)
+    I3...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

@llvm/pr-subscribers-clang

Author: Henrich Lauko (xlauko)

Changes

This mirrors incubator changes from llvm/clangir#1678

  • Create CIR specific EnumAttr bases and prefix enum attributes with CIR_ that automatically puts enum to cir namespace

  • Removes unnecessary enum case definitions

  • Unifies naming of enum values to use capitals consistently and make enumerations to start from 0


Patch is 22.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144999.diff

2 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+22-15)
  • (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+189-235)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 9e01dde379d7a..03e970db2847d 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -47,6 +47,16 @@ class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
   let cppNamespace = "::cir";
 }
 
+class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
+    : I64EnumAttr<name, summary, cases> {
+  let cppNamespace = "::cir";
+}
+
+class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
+    : EnumAttr<CIR_Dialect, info, name, traits> {
+  let assemblyFormat = "`<` $value `>`";
+}
+
 class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
     : CIR_Attr<name, attrMnemonic, traits> {
   let returnType = "bool";
@@ -330,36 +340,33 @@ def ConstComplexAttr : CIR_Attr<"ConstComplex", "const_complex",
 // VisibilityAttr
 //===----------------------------------------------------------------------===//
 
-def CIR_VisibilityKind : I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
-  I32EnumAttrCase<"Default", 1, "default">,
-  I32EnumAttrCase<"Hidden", 2, "hidden">,
-  I32EnumAttrCase<"Protected", 3, "protected">
+def CIR_VisibilityKind : CIR_I32EnumAttr<"VisibilityKind", "C/C++ visibility", [
+  I32EnumAttrCase<"Default", 0, "default">,
+  I32EnumAttrCase<"Hidden", 1, "hidden">,
+  I32EnumAttrCase<"Protected", 2, "protected">
 ]> {
   let genSpecializedAttr = 0;
-  let cppNamespace = "::cir";
 }
 
-def CIR_VisibilityAttr : CIR_Attr<"Visibility", "visibility"> {
+def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> {
   let summary = "Visibility attribute";
   let description = [{
     Visibility attributes.
   }];
-  let parameters = (ins "VisibilityKind":$value);
 
-  let assemblyFormat = [{
-    $value
-  }];
+  let cppClassName = "VisibilityAttr";
 
+  let skipDefaultBuilders = 1;
   let builders = [
-    AttrBuilder<(ins CArg<"VisibilityKind", "cir::VisibilityKind::Default">:$value), [{
+    AttrBuilder<(ins CArg<"VisibilityKind",
+                          "cir::VisibilityKind::Default">:$value), [{
       return $_get($_ctxt, value);
     }]>
   ];
 
-  let skipDefaultBuilders = 1;
-
-  // Make DefaultValuedAttr accept VisibilityKind as default value ($0).
-  let constBuilderCall = "cir::VisibilityAttr::get($_builder.getContext(), $0)";
+  let assemblyFormat = [{
+    $value
+  }];
 
   let extraClassDeclaration = [{
     bool isDefault() const { return getValue() == VisibilityKind::Default; };
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 852d3aa131148..f978bd9a96bcf 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -91,94 +91,80 @@ def SameFirstOperandAndResultType :
 // CastOp
 //===----------------------------------------------------------------------===//
 
-// CK_Dependent
-def CK_BitCast : I32EnumAttrCase<"bitcast", 1>;
-// CK_LValueBitCast
-// CK_LValueToRValueBitCast
-// CK_LValueToRValue
-// CK_NoOp
-// CK_BaseToDerived
-// CK_DerivedToBase
-// CK_UncheckedDerivedToBase
-// CK_Dynamic
-// CK_ToUnion
-def CK_ArrayToPointerDecay : I32EnumAttrCase<"array_to_ptrdecay", 11>;
-// CK_FunctionToPointerDecay
-// CK_NullToPointer
-// CK_NullToMemberPointer
-// CK_BaseToDerivedMemberPointer
-// CK_DerivedToBaseMemberPointer
-def CK_MemberPointerToBoolean : I32EnumAttrCase<"member_ptr_to_bool", 17>;
-// CK_ReinterpretMemberPointer
-// CK_UserDefinedConversion
-// CK_ConstructorConversion
-def CK_IntegralToPointer : I32EnumAttrCase<"int_to_ptr", 21>;
-def CK_PointerToIntegral : I32EnumAttrCase<"ptr_to_int", 22>;
-def CK_PointerToBoolean : I32EnumAttrCase<"ptr_to_bool", 23>;
-// CK_ToVoid
-// CK_MatrixCast
-// CK_VectorSplat
-def CK_IntegralCast : I32EnumAttrCase<"integral", 27>;
-def CK_IntegralToBoolean : I32EnumAttrCase<"int_to_bool", 28>;
-def CK_IntegralToFloating : I32EnumAttrCase<"int_to_float", 29>;
-// CK_FloatingToFixedPoint
-// CK_FixedPointToFloating
-// CK_FixedPointCast
-// CK_FixedPointToIntegral
-// CK_IntegralToFixedPoint
-// CK_FixedPointToBoolean
-def CK_FloatingToIntegral : I32EnumAttrCase<"float_to_int", 36>;
-def CK_FloatingToBoolean : I32EnumAttrCase<"float_to_bool", 37>;
-def CK_BooleanToSignedIntegral : I32EnumAttrCase<"bool_to_int", 38>;
-def CK_FloatingCast : I32EnumAttrCase<"floating", 39>;
-// CK_CPointerToObjCPointerCast
-// CK_BlockPointerToObjCPointerCast
-// CK_AnyPointerToBlockPointerCast
-// CK_ObjCObjectLValueCast
-// CK_FloatingRealToComplex
-// CK_FloatingComplexToReal
-// CK_FloatingComplexToBoolean
-def CK_FloatingComplexCast : I32EnumAttrCase<"float_complex", 47>;
-// CK_FloatingComplexToIntegralComplex
-// CK_IntegralRealToComplex
-def CK_IntegralComplexToReal : I32EnumAttrCase<"int_complex_to_real", 50>;
-def CK_IntegralComplexToBoolean : I32EnumAttrCase<"int_complex_to_bool", 51>;
-def CK_IntegralComplexCast : I32EnumAttrCase<"int_complex", 52>;
-def CK_IntegralComplexToFloatingComplex
-    : I32EnumAttrCase<"int_complex_to_float_complex", 53>;
-// CK_ARCProduceObject
-// CK_ARCConsumeObject
-// CK_ARCReclaimReturnedObject
-// CK_ARCExtendBlockObject
-// CK_AtomicToNonAtomic
-// CK_NonAtomicToAtomic
-// CK_CopyAndAutoreleaseBlockObject
-// CK_BuiltinFnToFnPtr
-// CK_ZeroToOCLOpaqueType
-def CK_AddressSpaceConversion : I32EnumAttrCase<"address_space", 63>;
-// CK_IntToOCLSampler
-// CK_HLSLVectorTruncation
-// CK_HLSLArrayRValue
-// CK_HLSLElementwiseCast
-// CK_HLSLAggregateSplatCast
-
-// Enums below are specific to CIR and don't have a correspondence to classic
-// codegen:
-def CK_BooleanToFloat : I32EnumAttrCase<"bool_to_float", 1000>;
-
-def CastKind : I32EnumAttr<
-    "CastKind",
-    "cast kind",
-    [CK_BitCast, CK_ArrayToPointerDecay, CK_MemberPointerToBoolean,
-     CK_IntegralToPointer, CK_PointerToIntegral, CK_PointerToBoolean,
-     CK_IntegralCast, CK_IntegralToBoolean, CK_IntegralToFloating,
-     CK_FloatingToIntegral, CK_FloatingToBoolean, CK_BooleanToSignedIntegral,
-     CK_FloatingCast, CK_FloatingComplexCast, CK_IntegralComplexToReal,
-     CK_IntegralComplexToBoolean, CK_IntegralComplexCast,
-     CK_IntegralComplexToFloatingComplex, CK_AddressSpaceConversion,
-     CK_BooleanToFloat]> {
-  let cppNamespace = "::cir";
-}
+def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [
+  I32EnumAttrCase<"bitcast", 1>,
+  // CK_LValueBitCast
+  // CK_LValueToRValueBitCast
+  // CK_LValueToRValue
+  // CK_NoOp
+  // CK_BaseToDerived
+  // CK_DerivedToBase
+  // CK_UncheckedDerivedToBase
+  // CK_Dynamic
+  // CK_ToUnion
+  I32EnumAttrCase<"array_to_ptrdecay", 11>,
+  // CK_FunctionToPointerDecay
+  // CK_NullToPointer
+  // CK_NullToMemberPointer
+  // CK_BaseToDerivedMemberPointer
+  // CK_DerivedToBaseMemberPointer
+  I32EnumAttrCase<"member_ptr_to_bool", 17>,
+  // CK_ReinterpretMemberPointer
+  // CK_UserDefinedConversion
+  // CK_ConstructorConversion
+  I32EnumAttrCase<"int_to_ptr", 21>,
+  I32EnumAttrCase<"ptr_to_int", 22>,
+  I32EnumAttrCase<"ptr_to_bool", 23>,
+  // CK_ToVoid
+  // CK_MatrixCast
+  // CK_VectorSplat
+  I32EnumAttrCase<"integral", 27>,
+  I32EnumAttrCase<"int_to_bool", 28>,
+  I32EnumAttrCase<"int_to_float", 29>,
+  // CK_FloatingToFixedPoint
+  // CK_FixedPointToFloating
+  // CK_FixedPointCast
+  // CK_FixedPointToIntegral
+  // CK_IntegralToFixedPoint
+  // CK_FixedPointToBoolean
+  I32EnumAttrCase<"float_to_int", 36>,
+  I32EnumAttrCase<"float_to_bool", 37>,
+  I32EnumAttrCase<"bool_to_int", 38>,
+  I32EnumAttrCase<"floating", 39>,
+  // CK_CPointerToObjCPointerCast
+  // CK_BlockPointerToObjCPointerCast
+  // CK_AnyPointerToBlockPointerCast
+  // CK_ObjCObjectLValueCast
+  // I32EnumAttrCase<"float_to_complex", 44>,
+  // I32EnumAttrCase<"float_complex_to_real", 45>,
+  // I32EnumAttrCase<"float_complex_to_bool", 46>,
+  I32EnumAttrCase<"float_complex", 47>,
+  // I32EnumAttrCase<"float_complex_to_int_complex", 48>,
+  // I32EnumAttrCase<"int_to_complex", 49>,
+  I32EnumAttrCase<"int_complex_to_real", 50>,
+  I32EnumAttrCase<"int_complex_to_bool", 51>,
+  I32EnumAttrCase<"int_complex", 52>,
+  I32EnumAttrCase<"int_complex_to_float_complex", 53>,
+  // CK_ARCProduceObject
+  // CK_ARCConsumeObject
+  // CK_ARCReclaimReturnedObject
+  // CK_ARCExtendBlockObject
+  // CK_AtomicToNonAtomic
+  // CK_NonAtomicToAtomic
+  // CK_CopyAndAutoreleaseBlockObject
+  // CK_BuiltinFnToFnPtr
+  // CK_ZeroToOCLOpaqueType
+  I32EnumAttrCase<"address_space", 63>,
+  // CK_IntToOCLSampler
+  // CK_HLSLVectorTruncation
+  // CK_HLSLArrayRValue
+  // CK_HLSLElementwiseCast
+  // CK_HLSLAggregateSplatCast
+
+  // Enums below are specific to CIR and don't have a correspondence to classic
+  // codegen:
+  I32EnumAttrCase<"bool_to_float", 1000>,
+]>;
 
 def CastOp : CIR_Op<"cast",
              [Pure,
@@ -186,45 +172,49 @@ def CastOp : CIR_Op<"cast",
   // FIXME: not all conversions are free of side effects.
   let summary = "Conversion between values of different types";
   let description = [{
-    Apply C/C++ usual conversions rules between values. Currently supported kinds:
+    Apply the usual C/C++ conversion rules between values. This operation models
+    a subset of conversions as defined in Clang's `OperationKinds.def`
+    (`llvm-project/clang/include/clang/AST/OperationKinds.def`).
+
+    Note: not all conversions are implemented using `cir.cast`. For instance,
+    lvalue-to-rvalue conversion is modeled as a `cir.load` instead.  Currently
+    supported kinds:
 
-    - `array_to_ptrdecay`
     - `bitcast`
+    - `array_to_ptrdecay`
+    - `member_ptr_to_bool
+    - `int_to_ptr`
+    - `ptr_to_int`
+    - `ptr_to_bool`
     - `integral`
     - `int_to_bool`
     - `int_to_float`
-    - `floating`
     - `float_to_int`
     - `float_to_bool`
-    - `ptr_to_int`
-    - `ptr_to_bool`
     - `bool_to_int`
-    - `bool_to_float`
-    - `address_space`
-    - `float_to_complex`
-    - `int_to_complex`
-    - `float_complex_to_real`
+    - `floating`
+    - `float_complex`
     - `int_complex_to_real`
-    - `float_complex_to_bool`
     - `int_complex_to_bool`
-    - `float_complex`
-    - `float_complex_to_int_complex`
     - `int_complex`
     - `int_complex_to_float_complex`
+    - `address_space`
+
+    CIR also supports some additional conversions that are not part of the classic
+    Clang codegen:
 
-    This is effectively a subset of the rules from
-    `llvm-project/clang/include/clang/AST/OperationKinds.def`; but note that some
-    of the conversions aren't implemented in terms of `cir.cast`, `lvalue-to-rvalue`
-    for instance is modeled as a regular `cir.load`.
+    - `bool_to_float`
+
+    Example:
 
     ```mlir
-    %4 = cir.cast (int_to_bool, %3 : i32), !cir.bool
+    %4 = cir.cast(int_to_bool, %3 : i32), !cir.bool
     ...
     %x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr<!cir.array<i32 x 10>>), !cir.ptr<i32>
     ```
   }];
 
-  let arguments = (ins CastKind:$kind, CIR_AnyType:$src);
+  let arguments = (ins CIR_CastKind:$kind, CIR_AnyType:$src);
   let results = (outs CIR_AnyType:$result);
 
   let assemblyFormat = [{
@@ -767,17 +757,12 @@ 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 CIR_CaseOpKind : CIR_I32EnumAttr<"CaseOpKind", "case kind", [
+  I32EnumAttrCase<"Default", 0, "default">,
+  I32EnumAttrCase<"Equal", 1, "equal">,
+  I32EnumAttrCase<"Anyof", 2, "anyof">,
+  I32EnumAttrCase<"Range", 3, "range">
+]>;
 
 def CaseOp : CIR_Op<"case", [
        DeclareOpInterfaceMethods<RegionBranchOpInterface>,
@@ -800,7 +785,7 @@ def CaseOp : CIR_Op<"case", [
     Each case region must be explicitly terminated.
   }];
 
-  let arguments = (ins ArrayAttr:$value, CaseOpKind:$kind);
+  let arguments = (ins ArrayAttr:$value, CIR_CaseOpKind:$kind);
   let regions = (region AnyRegion:$caseRegion);
 
   let assemblyFormat = "`(` $kind `,` $value `)` $caseRegion attr-dict";
@@ -1067,23 +1052,13 @@ def BrOp : CIR_Op<"br",
 // UnaryOp
 //===----------------------------------------------------------------------===//
 
-def UnaryOpKind_Inc   : I32EnumAttrCase<"Inc",   1, "inc">;
-def UnaryOpKind_Dec   : I32EnumAttrCase<"Dec",   2, "dec">;
-def UnaryOpKind_Plus  : I32EnumAttrCase<"Plus",  3, "plus">;
-def UnaryOpKind_Minus : I32EnumAttrCase<"Minus", 4, "minus">;
-def UnaryOpKind_Not   : I32EnumAttrCase<"Not",   5, "not">;
-
-def UnaryOpKind : I32EnumAttr<
-    "UnaryOpKind",
-    "unary operation kind",
-    [UnaryOpKind_Inc,
-     UnaryOpKind_Dec,
-     UnaryOpKind_Plus,
-     UnaryOpKind_Minus,
-     UnaryOpKind_Not,
-     ]> {
-  let cppNamespace = "::cir";
-}
+def CIR_UnaryOpKind : CIR_I32EnumAttr<"UnaryOpKind", "unary operation kind", [
+  I32EnumAttrCase<"Inc",   0, "inc">,
+  I32EnumAttrCase<"Dec",   1, "dec">,
+  I32EnumAttrCase<"Plus",  2, "plus">,
+  I32EnumAttrCase<"Minus", 3, "minus">,
+  I32EnumAttrCase<"Not",   4, "not">
+]>;
 
 def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> {
   let summary = "Unary operations";
@@ -1103,10 +1078,13 @@ def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> {
     ```
   }];
 
+  let arguments = (ins
+    Arg<CIR_UnaryOpKind, "unary op kind">:$kind,
+    Arg<CIR_AnyType>:$input,
+    UnitAttr:$no_signed_wrap
+  );
+
   let results = (outs CIR_AnyType:$result);
-  let arguments = (ins Arg<UnaryOpKind, "unary op kind">:$kind,
-                   Arg<CIR_AnyType>:$input,
-                   UnitAttr:$no_signed_wrap);
 
   let assemblyFormat = [{
       `(` $kind `,` $input `)`
@@ -1331,20 +1309,14 @@ def ForOp : LoopOpBase<"for"> {
 // CmpOp
 //===----------------------------------------------------------------------===//
 
-def CmpOpKind_LT : I32EnumAttrCase<"lt", 1>;
-def CmpOpKind_LE : I32EnumAttrCase<"le", 2>;
-def CmpOpKind_GT : I32EnumAttrCase<"gt", 3>;
-def CmpOpKind_GE : I32EnumAttrCase<"ge", 4>;
-def CmpOpKind_EQ : I32EnumAttrCase<"eq", 5>;
-def CmpOpKind_NE : I32EnumAttrCase<"ne", 6>;
-
-def CmpOpKind : I32EnumAttr<
-    "CmpOpKind",
-    "compare operation kind",
-    [CmpOpKind_LT, CmpOpKind_LE, CmpOpKind_GT,
-     CmpOpKind_GE, CmpOpKind_EQ, CmpOpKind_NE]> {
-  let cppNamespace = "::cir";
-}
+def CIR_CmpOpKind : CIR_I32EnumAttr<"CmpOpKind", "compare operation kind", [
+  I32EnumAttrCase<"lt", 0>,
+  I32EnumAttrCase<"le", 1>,
+  I32EnumAttrCase<"gt", 2>,
+  I32EnumAttrCase<"ge", 3>,
+  I32EnumAttrCase<"eq", 4>,
+  I32EnumAttrCase<"ne", 5>
+]>;
 
 def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
 
@@ -1359,9 +1331,13 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
     ```
   }];
 
+  let arguments = (ins
+    CIR_CmpOpKind:$kind,
+    CIR_AnyType:$lhs,
+    CIR_AnyType:$rhs
+  );
+
   let results = (outs CIR_BoolType:$result);
-  let arguments = (ins Arg<CmpOpKind, "cmp kind">:$kind,
-                       CIR_AnyType:$lhs, CIR_AnyType:$rhs);
 
   let assemblyFormat = [{
     `(` $kind `,` $lhs `,` $rhs  `)` `:` type($lhs) `,` type($result) attr-dict
@@ -1373,26 +1349,18 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
 //===----------------------------------------------------------------------===//
 
 // FIXME: represent Commutative, Idempotent traits for appropriate binops
-def BinOpKind_Mul : I32EnumAttrCase<"Mul", 1, "mul">;
-def BinOpKind_Div : I32EnumAttrCase<"Div", 2, "div">;
-def BinOpKind_Rem : I32EnumAttrCase<"Rem", 3, "rem">;
-def BinOpKind_Add : I32EnumAttrCase<"Add", 4, "add">;
-def BinOpKind_Sub : I32EnumAttrCase<"Sub", 5, "sub">;
-def BinOpKind_And : I32EnumAttrCase<"And", 8, "and">;
-def BinOpKind_Xor : I32EnumAttrCase<"Xor", 9, "xor">;
-def BinOpKind_Or  : I32EnumAttrCase<"Or", 10, "or">;
-// TODO(cir): Do we need a min binop?
-def BinOpKind_Max : I32EnumAttrCase<"Max", 11, "max">;
-
-def BinOpKind : I32EnumAttr<
-    "BinOpKind",
-    "binary operation (arith and logic) kind",
-    [BinOpKind_Mul, BinOpKind_Div, BinOpKind_Rem,
-     BinOpKind_Add, BinOpKind_Sub,
-     BinOpKind_And, BinOpKind_Xor,
-     BinOpKind_Or, BinOpKind_Max]> {
-  let cppNamespace = "::cir";
-}
+def CIR_BinOpKind : CIR_I32EnumAttr<
+  "BinOpKind", "binary operation (arith and logic) kind", [
+    I32EnumAttrCase<"Mul", 0, "mul">,
+    I32EnumAttrCase<"Div", 1, "div">,
+    I32EnumAttrCase<"Rem", 2, "rem">,
+    I32EnumAttrCase<"Add", 3, "add">,
+    I32EnumAttrCase<"Sub", 4, "sub">,
+    I32EnumAttrCase<"And", 5, "and">,
+    I32EnumAttrCase<"Xor", 6, "xor">,
+    I32EnumAttrCase<"Or", 7, "or">,
+    I32EnumAttrCase<"Max", 8, "max">
+]>;
 
 def BinOp : CIR_Op<"binop", [Pure,
   SameTypeOperands, SameOperandsAndResultType]> {
@@ -1424,13 +1392,16 @@ def BinOp : CIR_Op<"binop", [Pure,
     ```
   }];
 
+  let arguments = (ins
+    CIR_BinOpKind:$kind,
+    CIR_AnyType:$lhs, CIR_AnyType:$rhs,
+    UnitAttr:$no_unsigned_wrap,
+    UnitAttr:$no_signed_wrap,
+    UnitAttr:$saturated
+  );
+
   // TODO: get more accurate than CIR_AnyType
   let results = (outs CIR_AnyType:$result);
-  let arguments = (ins Arg<BinOpKind, "binop kind">:$kind,
-                       CIR_AnyType:$lhs, CIR_AnyType:$rhs,
-                       UnitAttr:$no_unsigned_wrap,
-                       UnitAttr:$no_signed_wrap,
-                       UnitAttr:$saturated);
 
   let assemblyFormat = [{
     `(` $kind `,` $lhs `,` $rhs  `)`
@@ -1586,54 +1557,34 @@ def TernaryOp : CIR_Op<"ternary",
 // currently handy as part of forwarding appropriate linkage types for LLVM
 // lowering, specially useful for C++ support.
 
-// Externally visible function
-def Global_ExternalLinkage :
-  I32EnumAttrCase<"ExternalLinkage", 0, "external">;
-// Available for inspection, not emission.
-def Global_AvailableExternallyLinkage :
-  I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">;
-// Keep one copy of function when linking (inline)
-def Global_LinkOnceAnyLinkage :
-  I32EnumAttrCase<"LinkOnceAnyLinkage", 2, "linkonce">;
-// Same, but only replaced by something equivalent.
-def Global_LinkOnceODRLinkage :
-  I32EnumAttrCase<"LinkOnceODRLinkage", 3, "linkonce_odr">;
-// Keep one copy of named function when linking (weak)
-def Global_WeakAnyLinkage :
-  I32EnumAttrCase<"WeakAnyLinkage", 4, "weak">;
-// Same, but only replaced by something equivalent.
-def Global_WeakODRLinkage :
-  I32EnumAttrCase<"WeakODRLinkage", 5, "weak_odr">;
-// TODO: should we add something like appending linkage too?
-// Special purpose, only applies to global arrays
-// def Global_AppendingLinkage :
-//   I32EnumAttrCase<"AppendingLinkage", 6, "appending">;
-// Rename collisions when linking (static functions).
-def Global_InternalLinkage :
-  I32EnumAttrCase<"InternalLinkage", 7, "internal">;
-// Like Internal, but omit from symbol table, prefix it with
-// "cir_" to prevent clash with MLIR's symbol "private".
-def Global_PrivateLinkage :
-  I32EnumAttrCase<"PrivateLinkage", 8, "cir_private">;
-// ExternalWeak linkage description.
-def Global_ExternalWeakLinkage :
-  I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">;
-// Tentative definitions.
-def Global_CommonLinkage :
-  I32EnumAttrCase<"CommonLinkage", 10, "common">;
-
 /// An enumeration for the kinds of linkage for global values.
-def GlobalLinkageKind : I32EnumAttr<
-    "GlobalLinkageKind",
-    "Linkage type/kind",
-    [Global_ExternalLinkage, Global_AvailableExternallyLinkage,
-     Global_LinkOnceAnyLinkage, Global_LinkOnceODRLinkage,
-     Global_WeakAnyLinkage, Global_WeakODRLinkage,
-     Global_InternalLinkage, Global_PrivateLinkage,
-     Global_ExternalWeakLinkage, Global_CommonLinkage
-     ]> {
-  let cppNamespace = "::cir";
-}
+def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
+  "GlobalLinkageKind", "linkage kind", [
+    // Externally visible function
+    I32EnumAttrCase<"ExternalLinkage", 0, "external">,
+    // Available for inspection, not emission.
+    I32EnumAttrCase<"AvailableExternallyLinkage", 1, "available_externally">,
+    // Keep one copy of function when linking (inline)
+    I3...
[truncated]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants