https://github.com/Lancern updated https://github.com/llvm/llvm-project/pull/159390
>From b44f24618f1bf3289d88633ce0395cf213462f67 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..80dc209c69a7b --- /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 << " [[maybe_unused]] 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