https://github.com/Lancern created 
https://github.com/llvm/llvm-project/pull/159390

Most lowering patterns have exactly the same class declaration with different 
names and different `matchAndRewrite` implementations, yet their declaration 
occupies near 1000 lines of code in `LowerToLLVM.h`, making this file difficult 
to read and boring to maintain. In this patch, I migrate their declarations to 
be generated from `CIROps.td` using `clang-tblgen`. Some extra `CIR_Op` 
TableGen fields are introduced to help this:

  - The `CIR_Op` class now defines a `bit` field `hasLLVMLowering` which 
defaults to `true`. If its value is `true`, `clang-tblgen` would generate an 
LLVM lowering pattern declaration for the operation.

  - Some LLVM lowering patterns has bounded recursion. This could be enabled by 
setting the `isLLVMLoweringRecursive` field in a `CIR_Op` record to `true`.

  - Some LLVM lowering patterns have defined additional class members. They 
could be listed in the `extraLLVMLoweringPatternDecl` field.

Note that in the incubator we have a similar TableGen code generator that 
generates LLVM lowering code for CIR builtin ops which has a one-to-one 
correspondence to LLVM dialect operations. This patch does NOT try to upstream 
it.

Some additional noticeable changes made by this patch:

  - This patch adds the `dataLayout` member to every LLVM lowering pattern 
class to make the job easier for a code generator. In the future we might want 
to add more members to the lowering patterns, and we will need to update the 
code generator to make such changes.

>From 63db52b98a7e536e6020756b73588c49c5aaa7ee Mon Sep 17 00:00:00 2001
From: Sirui Mu <msrlanc...@gmail.com>
Date: Wed, 17 Sep 2025 23:39:35 +0800
Subject: [PATCH] [CIR][NFC] Use TableGen to generate LLVM lowering patterns

Most lowering patterns have exactly the same class declaration with different
names and different `matchAndRewrite` implementations, yet their declaration
occupies near 1000 lines of code in `LowerToLLVM.h`, making this file difficult
to read and boring to maintain. In this patch, I migrate their declarations to
be generated from `CIROps.td` using `clang-tblgen`. Some extra `CIR_Op` TableGen
fields are introduced to help this:

  - The `CIR_Op` class now defines a `bit` field `hasLLVMLowering` which
    defaults to `true`. If its value is `true`, `clang-tblgen` would generate an
    LLVM lowering pattern declaration for the operation.

  - Some LLVM lowering patterns has bounded recursion. This could be enabled by
    setting the `isLLVMLoweringRecursive` field in a `CIR_Op` record to `true`.

  - Some LLVM lowering patterns have defined additional class members. They
    could be listed in the `extraLLVMLoweringPatternDecl` field.

Note that in the incubator we have a similar TableGen code generator that
generates LLVM lowering code for CIR builtin ops which has a one-to-one
correspondence to LLVM dialect operations. This patch does NOT try to upstream
it.

Some additional noticeable changes made by this patch:

  - This patch adds the `dataLayout` member to every LLVM lowering pattern class
    to make the job easier for a code generator. In the future we might want to
    add more members to the lowering patterns, and we will need to update the
    code generator to make such changes.
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  80 +-
 .../clang/CIR/Dialect/IR/CMakeLists.txt       |   4 +
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  84 +-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 798 +-----------------
 clang/utils/TableGen/CIRLoweringEmitter.cpp   | 125 +++
 clang/utils/TableGen/CMakeLists.txt           |   1 +
 clang/utils/TableGen/TableGen.cpp             |   6 +
 clang/utils/TableGen/TableGenBackends.h       |   1 +
 8 files changed, 223 insertions(+), 876 deletions(-)
 create mode 100644 clang/utils/TableGen/CIRLoweringEmitter.cpp

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 38c4a87f69d6d..f80c9faf708ef 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -78,7 +78,15 @@ class LLVMLoweringInfo {
 }
 
 class CIR_Op<string mnemonic, list<Trait> traits = []> :
-    Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
+    Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo {
+  // Should we generate an LLVM lowering pattern for this op?
+  bit hasLLVMLowering = true;
+  // Is the LLVM lowering pattern for this operation recursive?
+  bit isLLVMLoweringRecursive = false;
+  // Extra class declarations to be included in the generated LLVM lowering
+  // pattern.
+  code extraLLVMLoweringPatternDecl = "";
+}
 
 
//===----------------------------------------------------------------------===//
 // CastOp
@@ -218,6 +226,10 @@ def CIR_CastOp : CIR_Op<"cast", [
   // The input and output types should match the cast kind.
   let hasVerifier = 1;
   let hasFolder = 1;
+
+  let extraLLVMLoweringPatternDecl = [{
+    mlir::Type convertTy(mlir::Type ty) const;
+  }];
 }
 
 
@@ -297,6 +309,8 @@ def CIR_ConstantOp : CIR_Op<"const", [
   }];
 
   let hasFolder = 1;
+
+  let isLLVMLoweringRecursive = true;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -613,6 +627,8 @@ def CIR_IfOp : CIR_Op<"if", [
       CArg<"BuilderCallbackRef", "buildTerminatedBody">:$thenBuilder,
       CArg<"BuilderCallbackRef", "nullptr">:$elseBuilder)>
   ];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -659,6 +675,7 @@ def CIR_ConditionOp : CIR_Op<"condition", [
   let arguments = (ins CIR_BoolType:$condition);
   let assemblyFormat = " `(` $condition `)` attr-dict ";
   let hasVerifier = 1;
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -726,6 +743,8 @@ def CIR_YieldOp : CIR_Op<"yield", [
   let builders = [
     OpBuilder<(ins), [{ /* nothing to do */ }]>,
   ];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -741,6 +760,7 @@ def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
   }];
   let assemblyFormat = "attr-dict";
   let hasVerifier = 1;
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -756,6 +776,7 @@ def CIR_ContinueOp : CIR_Op<"continue", [Terminator]> {
   }];
   let assemblyFormat = "attr-dict";
   let hasVerifier = 1;
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -814,6 +835,8 @@ def CIR_ScopeOp : CIR_Op<"scope", [
     // Scopes without yielding values.
     OpBuilder<(ins "llvm::function_ref<void(mlir::OpBuilder &, 
mlir::Location)>":$scopeBuilder)>
   ];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -860,6 +883,8 @@ def CIR_CaseOp : CIR_Op<"case", [
                    "CaseOpKind":$kind,
                    "mlir::OpBuilder::InsertPoint &":$insertPoint)>
   ];
+
+  let hasLLVMLowering = false;
 }
 
 def CIR_SwitchOp : CIR_Op<"switch", [
@@ -1025,6 +1050,8 @@ def CIR_SwitchOp : CIR_Op<"switch", [
     // This is an expensive and need to be used with caution.
     bool isSimpleForm(llvm::SmallVectorImpl<CaseOp> &cases);
   }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1170,6 +1197,8 @@ def CIR_GotoOp : CIR_Op<"goto", [Terminator]> {
   }];
   let arguments = (ins StrAttr:$label);
   let assemblyFormat = [{ $label attr-dict }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1185,6 +1214,8 @@ def CIR_LabelOp : CIR_Op<"label", [AlwaysSpeculatable]> {
   let arguments = (ins StrAttr:$label);
   let assemblyFormat = [{ $label attr-dict }];
   let hasVerifier = 1;
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1349,6 +1380,8 @@ def CIR_WhileOp : CIR_WhileOpBase<"while"> {
     }
     ```
   }];
+
+  let hasLLVMLowering = false;
 }
 
 def CIR_DoWhileOp : CIR_WhileOpBase<"do"> {
@@ -1375,6 +1408,8 @@ def CIR_DoWhileOp : CIR_WhileOpBase<"do"> {
     }
     ```
   }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1442,6 +1477,8 @@ def CIR_ForOp : CIR_LoopOpBase<"for"> {
       return llvm::SmallVector<mlir::Region *, 3>{&getCond(), &getBody(), 
&getStep()};
     }
   }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1480,6 +1517,8 @@ def CIR_CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
   let assemblyFormat = [{
     `(` $kind `,` $lhs `,` $rhs  `)` `:` type($lhs) `,` type($result) attr-dict
   }];
+
+  let isLLVMLoweringRecursive = true;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1550,6 +1589,10 @@ def CIR_BinOp : CIR_Op<"binop", [
   }];
 
   let hasVerifier = 1;
+
+  let extraLLVMLoweringPatternDecl = [{
+    mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const;
+  }];
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1687,6 +1730,8 @@ def CIR_TernaryOp : CIR_Op<"ternary", [
       `false` $falseRegion
     `)` `:` functional-type(operands, results) attr-dict
   }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1790,6 +1835,20 @@ def CIR_GlobalOp : CIR_Op<"global", [
     "cir::GlobalLinkageKind::ExternalLinkage">:$linkage)>];
 
   let hasVerifier = 1;
+
+  let isLLVMLoweringRecursive = true;
+  let extraLLVMLoweringPatternDecl = [{
+    mlir::LogicalResult matchAndRewriteRegionInitializedGlobal(
+      cir::GlobalOp op, mlir::Attribute init,
+      mlir::ConversionPatternRewriter &rewriter) const;
+
+    void setupRegionInitializedLLVMGlobalOp(
+        cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;
+
+    mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
+    mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op,
+                                      mlir::OpBuilder &builder) const;
+  }];
 }
 
 
//===----------------------------------------------------------------------===//
@@ -2340,6 +2399,19 @@ def CIR_FuncOp : CIR_Op<"func", [
 
   let hasCustomAssemblyFormat = 1;
   let hasVerifier = 1;
+
+  let extraLLVMLoweringPatternDecl = [{
+    static mlir::StringRef getLinkageAttrNameString() { return "linkage"; }
+
+    void lowerFuncAttributes(
+        cir::FuncOp func, bool filterArgAndResAttrs,
+        mlir::SmallVectorImpl<mlir::NamedAttribute> &result) const;
+
+    mlir::LogicalResult
+    matchAndRewriteAlias(cir::FuncOp op, llvm::StringRef aliasee, mlir::Type 
ty,
+                         OpAdaptor adaptor,
+                         mlir::ConversionPatternRewriter &rewriter) const;
+  }];
 }
 
 
//===----------------------------------------------------------------------===//
@@ -2761,6 +2833,8 @@ class CIR_ArrayInitDestroy<string mnemonic> : 
CIR_Op<mnemonic> {
         regionBuilder($_builder, $_state.location);
     }]>
   ];
+
+  let hasLLVMLowering = false;
 }
 
 def CIR_ArrayCtor : CIR_ArrayInitDestroy<"array.ctor"> {
@@ -3380,6 +3454,8 @@ def CIR_ComplexMulOp : CIR_Op<"complex.mul", [
   let assemblyFormat = [{
     $lhs `,` $rhs `range` `(` $range `)` `:` qualified(type($result)) attr-dict
   }];
+
+  let hasLLVMLowering = false;
 }
 
 def CIR_ComplexDivOp : CIR_Op<"complex.div", [
@@ -3422,6 +3498,8 @@ def CIR_ComplexDivOp : CIR_Op<"complex.div", [
   let assemblyFormat = [{
     $lhs `,` $rhs `range` `(` $range `)` `:` qualified(type($result)) attr-dict
   }];
+
+  let hasLLVMLowering = false;
 }
 
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt 
b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
index 6e7f3da4add3e..870f9e3f5d052 100644
--- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt
@@ -20,6 +20,10 @@ mlir_tablegen(CIROpsAttributes.h.inc -gen-attrdef-decls)
 mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs)
 add_public_tablegen_target(MLIRCIREnumsGen)
 
+clang_tablegen(CIRLowering.inc -gen-cir-lowering
+               SOURCE CIROps.td
+               TARGET CIRLowering)
+
 set(LLVM_TARGET_DEFINITIONS CIRTypeConstraints.td)
 mlir_tablegen(CIRTypeConstraints.h.inc -gen-type-constraint-decls)
 mlir_tablegen(CIRTypeConstraints.cpp.inc -gen-type-constraint-defs)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 1d7e3df1430ac..e18149a61abd0 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2463,87 +2463,11 @@ void ConvertCIRToLLVMPass::runOnOperation() {
 
   mlir::RewritePatternSet patterns(&getContext());
 
-  patterns.add<CIRToLLVMReturnOpLowering>(patterns.getContext());
-  // This could currently be merged with the group below, but it will get more
-  // arguments later, so we'll keep it separate for now.
-  patterns.add<CIRToLLVMAllocaOpLowering>(converter, patterns.getContext(), 
dl);
-  patterns.add<CIRToLLVMLoadOpLowering>(converter, patterns.getContext(), dl);
-  patterns.add<CIRToLLVMStoreOpLowering>(converter, patterns.getContext(), dl);
-  patterns.add<CIRToLLVMGlobalOpLowering>(converter, patterns.getContext(), 
dl);
-  patterns.add<CIRToLLVMCastOpLowering>(converter, patterns.getContext(), dl);
-  patterns.add<CIRToLLVMPtrStrideOpLowering>(converter, patterns.getContext(),
-                                             dl);
-  patterns.add<CIRToLLVMInlineAsmOpLowering>(converter, patterns.getContext(),
-                                             dl);
   patterns.add<
-      // clang-format off
-               CIRToLLVMACosOpLowering,
-               CIRToLLVMASinOpLowering,
-               CIRToLLVMAssumeOpLowering,
-               CIRToLLVMAssumeAlignedOpLowering,
-               CIRToLLVMAssumeSepStorageOpLowering,
-               CIRToLLVMAtomicCmpXchgLowering,
-               CIRToLLVMBaseClassAddrOpLowering,
-               CIRToLLVMATanOpLowering,
-               CIRToLLVMBinOpLowering,
-               CIRToLLVMBitClrsbOpLowering,
-               CIRToLLVMBitClzOpLowering,
-               CIRToLLVMBitCtzOpLowering,
-               CIRToLLVMBitFfsOpLowering,
-               CIRToLLVMBitParityOpLowering,
-               CIRToLLVMBitPopcountOpLowering,
-               CIRToLLVMBitReverseOpLowering,
-               CIRToLLVMBrCondOpLowering,
-               CIRToLLVMBrOpLowering,
-               CIRToLLVMByteSwapOpLowering,
-               CIRToLLVMCallOpLowering,
-               CIRToLLVMCmpOpLowering,
-               CIRToLLVMComplexAddOpLowering,
-               CIRToLLVMComplexCreateOpLowering,
-               CIRToLLVMComplexImagOpLowering,
-               CIRToLLVMComplexImagPtrOpLowering,
-               CIRToLLVMComplexRealOpLowering,
-               CIRToLLVMComplexRealPtrOpLowering,
-               CIRToLLVMComplexSubOpLowering,
-               CIRToLLVMCopyOpLowering,
-               CIRToLLVMCosOpLowering,
-               CIRToLLVMConstantOpLowering,
-               CIRToLLVMExpectOpLowering,
-               CIRToLLVMFAbsOpLowering,
-               CIRToLLVMFrameAddrOpLowering,
-               CIRToLLVMFuncOpLowering,
-               CIRToLLVMGetBitfieldOpLowering,
-               CIRToLLVMGetGlobalOpLowering,
-               CIRToLLVMGetMemberOpLowering,
-               CIRToLLVMReturnAddrOpLowering,
-               CIRToLLVMRotateOpLowering,
-               CIRToLLVMSelectOpLowering,
-               CIRToLLVMSetBitfieldOpLowering,
-               CIRToLLVMShiftOpLowering,
-               CIRToLLVMStackRestoreOpLowering,
-               CIRToLLVMStackSaveOpLowering,
-               CIRToLLVMSwitchFlatOpLowering,
-               CIRToLLVMThrowOpLowering,
-               CIRToLLVMTrapOpLowering,
-               CIRToLLVMUnaryOpLowering,
-               CIRToLLVMUnreachableOpLowering,
-               CIRToLLVMVAArgOpLowering,
-               CIRToLLVMVAEndOpLowering,
-               CIRToLLVMVAStartOpLowering,
-               CIRToLLVMVecCmpOpLowering,
-               CIRToLLVMVecCreateOpLowering,
-               CIRToLLVMVecExtractOpLowering,
-               CIRToLLVMVecInsertOpLowering,
-               CIRToLLVMVecShuffleDynamicOpLowering,
-               CIRToLLVMVecShuffleOpLowering,
-               CIRToLLVMVecSplatOpLowering,
-               CIRToLLVMVecTernaryOpLowering,
-               CIRToLLVMVTableAddrPointOpLowering,
-               CIRToLLVMVTableGetVPtrOpLowering,
-               CIRToLLVMVTableGetVirtualFnAddrOpLowering,
-               CIRToLLVMVTTAddrPointOpLowering
-      // clang-format on
-      >(converter, patterns.getContext());
+#define GET_LLVM_LOWERING_PATTERNS_LIST
+#include "clang/CIR/Dialect/IR/CIRLowering.inc"
+#undef GET_LLVM_LOWERING_PATTERNS_LIST
+      >(converter, patterns.getContext(), dl);
 
   processCIRAttrs(module);
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 09ff7a0901c69..0591de545b81d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -34,801 +34,9 @@ void convertSideEffectForCall(mlir::Operation *callOp, bool 
isNothrow,
                               mlir::LLVM::MemoryEffectsAttr &memoryEffect,
                               bool &noUnwind, bool &willReturn);
 
-class CIRToLLVMAssumeOpLowering
-    : public mlir::OpConversionPattern<cir::AssumeOp> {
-public:
-  using mlir::OpConversionPattern<cir::AssumeOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::AssumeOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMAssumeAlignedOpLowering
-    : public mlir::OpConversionPattern<cir::AssumeAlignedOp> {
-public:
-  using mlir::OpConversionPattern<cir::AssumeAlignedOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::AssumeAlignedOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMAssumeSepStorageOpLowering
-    : public mlir::OpConversionPattern<cir::AssumeSepStorageOp> {
-public:
-  using 
mlir::OpConversionPattern<cir::AssumeSepStorageOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::AssumeSepStorageOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitClrsbOpLowering
-    : public mlir::OpConversionPattern<cir::BitClrsbOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitClrsbOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitClrsbOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitClzOpLowering
-    : public mlir::OpConversionPattern<cir::BitClzOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitClzOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitClzOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitCtzOpLowering
-    : public mlir::OpConversionPattern<cir::BitCtzOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitCtzOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitCtzOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitFfsOpLowering
-    : public mlir::OpConversionPattern<cir::BitFfsOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitFfsOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitFfsOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitParityOpLowering
-    : public mlir::OpConversionPattern<cir::BitParityOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitParityOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitParityOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitPopcountOpLowering
-    : public mlir::OpConversionPattern<cir::BitPopcountOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitPopcountOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitPopcountOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBitReverseOpLowering
-    : public mlir::OpConversionPattern<cir::BitReverseOp> {
-public:
-  using mlir::OpConversionPattern<cir::BitReverseOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BitReverseOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMAtomicCmpXchgLowering
-    : public mlir::OpConversionPattern<cir::AtomicCmpXchg> {
-public:
-  using mlir::OpConversionPattern<cir::AtomicCmpXchg>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::AtomicCmpXchg op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBrCondOpLowering
-    : public mlir::OpConversionPattern<cir::BrCondOp> {
-public:
-  using mlir::OpConversionPattern<cir::BrCondOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BrCondOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMByteSwapOpLowering
-    : public mlir::OpConversionPattern<cir::ByteSwapOp> {
-public:
-  using mlir::OpConversionPattern<cir::ByteSwapOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ByteSwapOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMCastOpLowering : public mlir::OpConversionPattern<cir::CastOp> {
-  mlir::DataLayout const &dataLayout;
-
-  mlir::Type convertTy(mlir::Type ty) const;
-
-public:
-  CIRToLLVMCastOpLowering(const mlir::TypeConverter &typeConverter,
-                          mlir::MLIRContext *context,
-                          mlir::DataLayout const &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::CastOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMCopyOpLowering : public mlir::OpConversionPattern<cir::CopyOp> {
-public:
-  using mlir::OpConversionPattern<cir::CopyOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::CopyOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMCosOpLowering : public mlir::OpConversionPattern<cir::CosOp> {
-public:
-  using mlir::OpConversionPattern<cir::CosOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::CosOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMExpectOpLowering
-    : public mlir::OpConversionPattern<cir::ExpectOp> {
-public:
-  using mlir::OpConversionPattern<cir::ExpectOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ExpectOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMReturnOpLowering
-    : public mlir::OpConversionPattern<cir::ReturnOp> {
-public:
-  using mlir::OpConversionPattern<cir::ReturnOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ReturnOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMRotateOpLowering
-    : public mlir::OpConversionPattern<cir::RotateOp> {
-public:
-  using mlir::OpConversionPattern<cir::RotateOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::RotateOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> {
-public:
-  using mlir::OpConversionPattern<cir::CallOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::CallOp op, OpAdaptor adaptor,
-                  mlir::ConversionPatternRewriter &rewriter) const override;
-};
-
-class CIRToLLVMReturnAddrOpLowering
-    : public mlir::OpConversionPattern<cir::ReturnAddrOp> {
-public:
-  using mlir::OpConversionPattern<cir::ReturnAddrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ReturnAddrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMFrameAddrOpLowering
-    : public mlir::OpConversionPattern<cir::FrameAddrOp> {
-public:
-  using mlir::OpConversionPattern<cir::FrameAddrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::FrameAddrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMAllocaOpLowering
-    : public mlir::OpConversionPattern<cir::AllocaOp> {
-  mlir::DataLayout const &dataLayout;
-
-public:
-  CIRToLLVMAllocaOpLowering(mlir::TypeConverter const &typeConverter,
-                            mlir::MLIRContext *context,
-                            mlir::DataLayout const &dataLayout)
-      : OpConversionPattern<cir::AllocaOp>(typeConverter, context),
-        dataLayout(dataLayout) {}
-
-  using mlir::OpConversionPattern<cir::AllocaOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::AllocaOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern<cir::LoadOp> {
-  mlir::DataLayout const &dataLayout;
-
-public:
-  CIRToLLVMLoadOpLowering(const mlir::TypeConverter &typeConverter,
-                          mlir::MLIRContext *context,
-                          mlir::DataLayout const &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::LoadOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMStoreOpLowering
-    : public mlir::OpConversionPattern<cir::StoreOp> {
-  mlir::DataLayout const &dataLayout;
-
-public:
-  CIRToLLVMStoreOpLowering(const mlir::TypeConverter &typeConverter,
-                           mlir::MLIRContext *context,
-                           mlir::DataLayout const &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::StoreOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMConstantOpLowering
-    : public mlir::OpConversionPattern<cir::ConstantOp> {
-public:
-  CIRToLLVMConstantOpLowering(const mlir::TypeConverter &typeConverter,
-                              mlir::MLIRContext *context)
-      : OpConversionPattern(typeConverter, context) {
-    setHasBoundedRewriteRecursion();
-  }
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ConstantOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMFuncOpLowering : public mlir::OpConversionPattern<cir::FuncOp> {
-  static mlir::StringRef getLinkageAttrNameString() { return "linkage"; }
-
-  void lowerFuncAttributes(
-      cir::FuncOp func, bool filterArgAndResAttrs,
-      mlir::SmallVectorImpl<mlir::NamedAttribute> &result) const;
-
-  mlir::LogicalResult
-  matchAndRewriteAlias(cir::FuncOp op, llvm::StringRef aliasee, mlir::Type ty,
-                       OpAdaptor adaptor,
-                       mlir::ConversionPatternRewriter &rewriter) const;
-
-public:
-  using mlir::OpConversionPattern<cir::FuncOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::FuncOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMSwitchFlatOpLowering
-    : public mlir::OpConversionPattern<cir::SwitchFlatOp> {
-public:
-  using mlir::OpConversionPattern<cir::SwitchFlatOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::SwitchFlatOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMGetGlobalOpLowering
-    : public mlir::OpConversionPattern<cir::GetGlobalOp> {
-public:
-  using mlir::OpConversionPattern<cir::GetGlobalOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::GetGlobalOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMGlobalOpLowering
-    : public mlir::OpConversionPattern<cir::GlobalOp> {
-  const mlir::DataLayout &dataLayout;
-
-public:
-  CIRToLLVMGlobalOpLowering(const mlir::TypeConverter &typeConverter,
-                            mlir::MLIRContext *context,
-                            const mlir::DataLayout &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {
-    setHasBoundedRewriteRecursion();
-  }
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::GlobalOp op, OpAdaptor adaptor,
-                  mlir::ConversionPatternRewriter &rewriter) const override;
-
-private:
-  mlir::LogicalResult matchAndRewriteRegionInitializedGlobal(
-      cir::GlobalOp op, mlir::Attribute init,
-      mlir::ConversionPatternRewriter &rewriter) const;
-
-  void setupRegionInitializedLLVMGlobalOp(
-      cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;
-
-  mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
-  mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op,
-                                    mlir::OpBuilder &builder) const;
-};
-
-class CIRToLLVMUnaryOpLowering
-    : public mlir::OpConversionPattern<cir::UnaryOp> {
-public:
-  using mlir::OpConversionPattern<cir::UnaryOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::UnaryOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBinOpLowering : public mlir::OpConversionPattern<cir::BinOp> {
-  mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const;
-
-public:
-  using mlir::OpConversionPattern<cir::BinOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BinOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMCmpOpLowering : public mlir::OpConversionPattern<cir::CmpOp> {
-public:
-  CIRToLLVMCmpOpLowering(const mlir::TypeConverter &typeConverter,
-                         mlir::MLIRContext *context)
-      : OpConversionPattern(typeConverter, context) {
-    setHasBoundedRewriteRecursion();
-  }
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::CmpOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMShiftOpLowering
-    : public mlir::OpConversionPattern<cir::ShiftOp> {
-public:
-  using mlir::OpConversionPattern<cir::ShiftOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ShiftOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMSelectOpLowering
-    : public mlir::OpConversionPattern<cir::SelectOp> {
-public:
-  using mlir::OpConversionPattern<cir::SelectOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::SelectOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBrOpLowering : public mlir::OpConversionPattern<cir::BrOp> {
-public:
-  using mlir::OpConversionPattern<cir::BrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMGetMemberOpLowering
-    : public mlir::OpConversionPattern<cir::GetMemberOp> {
-public:
-  using mlir::OpConversionPattern<cir::GetMemberOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::GetMemberOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMUnreachableOpLowering
-    : public mlir::OpConversionPattern<cir::UnreachableOp> {
-public:
-  using mlir::OpConversionPattern<cir::UnreachableOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::UnreachableOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMTrapOpLowering : public mlir::OpConversionPattern<cir::TrapOp> {
-public:
-  using mlir::OpConversionPattern<cir::TrapOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::TrapOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMPtrStrideOpLowering
-    : public mlir::OpConversionPattern<cir::PtrStrideOp> {
-  mlir::DataLayout const &dataLayout;
-
-public:
-  CIRToLLVMPtrStrideOpLowering(const mlir::TypeConverter &typeConverter,
-                               mlir::MLIRContext *context,
-                               mlir::DataLayout const &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
-  using mlir::OpConversionPattern<cir::PtrStrideOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::PtrStrideOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMBaseClassAddrOpLowering
-    : public mlir::OpConversionPattern<cir::BaseClassAddrOp> {
-public:
-  using mlir::OpConversionPattern<cir::BaseClassAddrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::BaseClassAddrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVTableAddrPointOpLowering
-    : public mlir::OpConversionPattern<cir::VTableAddrPointOp> {
-public:
-  using mlir::OpConversionPattern<cir::VTableAddrPointOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VTableAddrPointOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVTableGetVPtrOpLowering
-    : public mlir::OpConversionPattern<cir::VTableGetVPtrOp> {
-public:
-  using mlir::OpConversionPattern<cir::VTableGetVPtrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VTableGetVPtrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVTableGetVirtualFnAddrOpLowering
-    : public mlir::OpConversionPattern<cir::VTableGetVirtualFnAddrOp> {
-public:
-  using mlir::OpConversionPattern<
-      cir::VTableGetVirtualFnAddrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VTableGetVirtualFnAddrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVTTAddrPointOpLowering
-    : public mlir::OpConversionPattern<cir::VTTAddrPointOp> {
-public:
-  using mlir::OpConversionPattern<cir::VTTAddrPointOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VTTAddrPointOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMStackSaveOpLowering
-    : public mlir::OpConversionPattern<cir::StackSaveOp> {
-public:
-  using mlir::OpConversionPattern<cir::StackSaveOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::StackSaveOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMStackRestoreOpLowering
-    : public mlir::OpConversionPattern<cir::StackRestoreOp> {
-public:
-  using OpConversionPattern<cir::StackRestoreOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::StackRestoreOp op, OpAdaptor adaptor,
-                  mlir::ConversionPatternRewriter &rewriter) const override;
-};
-
-class CIRToLLVMVecCreateOpLowering
-    : public mlir::OpConversionPattern<cir::VecCreateOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecCreateOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecCreateOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecExtractOpLowering
-    : public mlir::OpConversionPattern<cir::VecExtractOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecExtractOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecExtractOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecInsertOpLowering
-    : public mlir::OpConversionPattern<cir::VecInsertOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecInsertOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecInsertOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecCmpOpLowering
-    : public mlir::OpConversionPattern<cir::VecCmpOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecCmpOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecCmpOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecSplatOpLowering
-    : public mlir::OpConversionPattern<cir::VecSplatOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecSplatOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecSplatOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecShuffleOpLowering
-    : public mlir::OpConversionPattern<cir::VecShuffleOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecShuffleOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecShuffleOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecShuffleDynamicOpLowering
-    : public mlir::OpConversionPattern<cir::VecShuffleDynamicOp> {
-public:
-  using mlir::OpConversionPattern<
-      cir::VecShuffleDynamicOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecShuffleDynamicOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVecTernaryOpLowering
-    : public mlir::OpConversionPattern<cir::VecTernaryOp> {
-public:
-  using mlir::OpConversionPattern<cir::VecTernaryOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VecTernaryOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexCreateOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexCreateOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexCreateOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexCreateOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexRealOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexRealOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexRealOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexRealOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexImagOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexImagOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexImagOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexImagOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexImagPtrOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexImagPtrOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexImagPtrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexImagPtrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexRealPtrOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexRealPtrOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexRealPtrOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexRealPtrOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexAddOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexAddOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexAddOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexAddOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMComplexSubOpLowering
-    : public mlir::OpConversionPattern<cir::ComplexSubOp> {
-public:
-  using mlir::OpConversionPattern<cir::ComplexSubOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ComplexSubOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMSetBitfieldOpLowering
-    : public mlir::OpConversionPattern<cir::SetBitfieldOp> {
-public:
-  using mlir::OpConversionPattern<cir::SetBitfieldOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::SetBitfieldOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMGetBitfieldOpLowering
-    : public mlir::OpConversionPattern<cir::GetBitfieldOp> {
-public:
-  using mlir::OpConversionPattern<cir::GetBitfieldOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::GetBitfieldOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMFAbsOpLowering : public mlir::OpConversionPattern<cir::FAbsOp> {
-public:
-  using mlir::OpConversionPattern<cir::FAbsOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::FAbsOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMACosOpLowering : public mlir::OpConversionPattern<cir::ACosOp> {
-public:
-  using mlir::OpConversionPattern<cir::ACosOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ACosOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMASinOpLowering : public mlir::OpConversionPattern<cir::ASinOp> {
-public:
-  using mlir::OpConversionPattern<cir::ASinOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ASinOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMATanOpLowering : public mlir::OpConversionPattern<cir::ATanOp> {
-public:
-  using mlir::OpConversionPattern<cir::ATanOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ATanOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMInlineAsmOpLowering
-    : public mlir::OpConversionPattern<cir::InlineAsmOp> {
-  mlir::DataLayout const &dataLayout;
-
-public:
-  CIRToLLVMInlineAsmOpLowering(const mlir::TypeConverter &typeConverter,
-                               mlir::MLIRContext *context,
-                               mlir::DataLayout const &dataLayout)
-      : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {}
-
-  using mlir::OpConversionPattern<cir::InlineAsmOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::InlineAsmOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMThrowOpLowering
-    : public mlir::OpConversionPattern<cir::ThrowOp> {
-public:
-  using mlir::OpConversionPattern<cir::ThrowOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::ThrowOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVAStartOpLowering
-    : public mlir::OpConversionPattern<cir::VAStartOp> {
-public:
-  using mlir::OpConversionPattern<cir::VAStartOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VAStartOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVAEndOpLowering
-    : public mlir::OpConversionPattern<cir::VAEndOp> {
-public:
-  using mlir::OpConversionPattern<cir::VAEndOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VAEndOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
-
-class CIRToLLVMVAArgOpLowering
-    : public mlir::OpConversionPattern<cir::VAArgOp> {
-public:
-  using mlir::OpConversionPattern<cir::VAArgOp>::OpConversionPattern;
-
-  mlir::LogicalResult
-  matchAndRewrite(cir::VAArgOp op, OpAdaptor,
-                  mlir::ConversionPatternRewriter &) const override;
-};
+#define GET_LLVM_LOWERING_PATTERNS
+#include "clang/CIR/Dialect/IR/CIRLowering.inc"
+#undef GET_LLVM_LOWERING_PATTERNS
 
 } // namespace direct
 } // namespace cir
diff --git a/clang/utils/TableGen/CIRLoweringEmitter.cpp 
b/clang/utils/TableGen/CIRLoweringEmitter.cpp
new file mode 100644
index 0000000000000..ae2d6bcb74393
--- /dev/null
+++ b/clang/utils/TableGen/CIRLoweringEmitter.cpp
@@ -0,0 +1,125 @@
+//===-- CIRLoweringEmitter.cpp - Generate CIR lowering patterns 
-----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This TableGen backend emits CIR operation lowering patterns.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TableGenBackends.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+std::vector<std::string> LLVMLoweringPatterns;
+std::vector<std::string> LLVMLoweringPatternsList;
+
+// Adapted from mlir/lib/TableGen/Operator.cpp
+// Returns the C++ class name of the operation, which is the name of the
+// operation with the dialect prefix removed and the first underscore removed.
+// If the operation name starts with an underscore, the underscore is 
considered
+// part of the class name.
+std::string GetOpCppClassName(const Record *OpRecord) {
+  StringRef Name = OpRecord->getName();
+  StringRef Prefix;
+  StringRef CppClassName;
+  std::tie(Prefix, CppClassName) = Name.split('_');
+  if (Prefix.empty()) {
+    // Class name with a leading underscore and without dialect prefix
+    return Name.str();
+  }
+  if (CppClassName.empty()) {
+    // Class name without dialect prefix
+    return Prefix.str();
+  }
+
+  return CppClassName.str();
+}
+
+std::string GetOpLLVMLoweringPatternName(llvm::StringRef OpName) {
+  std::string Name = "CIRToLLVM";
+  Name += OpName;
+  Name += "Lowering";
+  return Name;
+}
+
+void GenerateLLVMLoweringPattern(llvm::StringRef OpName,
+                                 llvm::StringRef PatternName, bool IsRecursive,
+                                 llvm::StringRef ExtraDecl) {
+  std::string CodeBuffer;
+  llvm::raw_string_ostream Code(CodeBuffer);
+
+  Code << "class " << PatternName
+       << " : public mlir::OpConversionPattern<cir::" << OpName << "> {\n";
+  Code << "  mlir::DataLayout const &dataLayout;\n";
+  Code << "\n";
+
+  Code << "public:\n";
+  Code << "  using mlir::OpConversionPattern<cir::" << OpName
+       << ">::OpConversionPattern;\n";
+
+  Code << "  " << PatternName
+       << "(mlir::TypeConverter const "
+          "&typeConverter, mlir::MLIRContext *context, mlir::DataLayout const "
+          "&dataLayout)\n";
+  Code << "    : OpConversionPattern<cir::" << OpName
+       << ">(typeConverter, context), dataLayout(dataLayout)";
+  if (IsRecursive) {
+    Code << " {\n";
+    Code << "    setHasBoundedRewriteRecursion();\n";
+    Code << "  }\n";
+  } else {
+    Code << " {}\n";
+  }
+
+  Code << "\n";
+
+  Code << "  mlir::LogicalResult matchAndRewrite(cir::" << OpName
+       << " op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) "
+          "const override;\n";
+
+  if (!ExtraDecl.empty()) {
+    Code << "\nprivate:\n";
+    Code << ExtraDecl << "\n";
+  }
+
+  Code << "};\n";
+
+  LLVMLoweringPatterns.push_back(std::move(CodeBuffer));
+}
+
+void Generate(const Record *OpRecord) {
+  std::string OpName = GetOpCppClassName(OpRecord);
+
+  if (OpRecord->getValueAsBit("hasLLVMLowering")) {
+    std::string PatternName = GetOpLLVMLoweringPatternName(OpName);
+    bool IsRecursive = OpRecord->getValueAsBit("isLLVMLoweringRecursive");
+    llvm::StringRef ExtraDecl =
+        OpRecord->getValueAsString("extraLLVMLoweringPatternDecl");
+
+    GenerateLLVMLoweringPattern(OpName, PatternName, IsRecursive, ExtraDecl);
+    LLVMLoweringPatternsList.push_back(std::move(PatternName));
+  }
+}
+} // namespace
+
+void clang::EmitCIRLowering(const llvm::RecordKeeper &RK,
+                            llvm::raw_ostream &OS) {
+  emitSourceFileHeader("Lowering patterns for CIR operations", OS);
+  for (const auto *OpRecord : RK.getAllDerivedDefinitions("CIR_Op"))
+    Generate(OpRecord);
+
+  OS << "#ifdef GET_LLVM_LOWERING_PATTERNS\n"
+     << llvm::join(LLVMLoweringPatterns, "\n") << "#endif\n\n";
+  OS << "#ifdef GET_LLVM_LOWERING_PATTERNS_LIST\n"
+     << llvm::join(LLVMLoweringPatternsList, ",\n") << "\n#endif\n\n";
+}
diff --git a/clang/utils/TableGen/CMakeLists.txt 
b/clang/utils/TableGen/CMakeLists.txt
index ce759ec8548d9..14f13824e9575 100644
--- a/clang/utils/TableGen/CMakeLists.txt
+++ b/clang/utils/TableGen/CMakeLists.txt
@@ -4,6 +4,7 @@ add_tablegen(clang-tblgen CLANG
   DESTINATION "${CLANG_TOOLS_INSTALL_DIR}"
   EXPORT Clang
   ASTTableGen.cpp
+  CIRLoweringEmitter.cpp
   ClangASTNodesEmitter.cpp
   ClangASTPropertiesEmitter.cpp
   ClangAttrEmitter.cpp
diff --git a/clang/utils/TableGen/TableGen.cpp 
b/clang/utils/TableGen/TableGen.cpp
index 98c4a07a99c42..df14955201a18 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -25,6 +25,7 @@ using namespace clang;
 enum ActionType {
   PrintRecords,
   DumpJSON,
+  GenCIRLowering,
   GenClangAttrClasses,
   GenClangAttrParserStringSwitches,
   GenClangAttrSubjectMatchRulesParserStringSwitches,
@@ -128,6 +129,8 @@ cl::opt<ActionType> Action(
                    "Print all records to stdout (default)"),
         clEnumValN(DumpJSON, "dump-json",
                    "Dump all records as machine-readable JSON"),
+        clEnumValN(GenCIRLowering, "gen-cir-lowering",
+                   "Generate CIR operation lowering patterns"),
         clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
                    "Generate clang attribute clases"),
         clEnumValN(GenClangAttrParserStringSwitches,
@@ -354,6 +357,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper 
&Records) {
   case DumpJSON:
     EmitJSON(Records, OS);
     break;
+  case GenCIRLowering:
+    EmitCIRLowering(Records, OS);
+    break;
   case GenClangAttrClasses:
     EmitClangAttrClass(Records, OS);
     break;
diff --git a/clang/utils/TableGen/TableGenBackends.h 
b/clang/utils/TableGen/TableGenBackends.h
index 79b1f66d0e49e..e017571362b90 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -24,6 +24,7 @@ class RecordKeeper;
 
 namespace clang {
 
+void EmitCIRLowering(const llvm::RecordKeeper &RK, llvm::raw_ostream &OS);
 void EmitClangDeclContext(const llvm::RecordKeeper &RK, llvm::raw_ostream &OS);
 /**
   @param PriorizeIfSubclassOf These classes should be prioritized in the 
output.

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to