//====- LowerToLLVM.h- Lowering from CIR to LLVM --------------------------===// // // 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 file declares an interface for converting CIR modules to LLVM IR. // //===----------------------------------------------------------------------===// #ifndef CLANG_CIR_LOWERTOLLVM_H #define CLANG_CIR_LOWERTOLLVM_H #include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Transforms/DialectConversion.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" namespace cir { namespace direct { /// Convert a CIR attribute to an LLVM attribute. May use the datalayout for /// lowering attributes to-be-stored in memory. mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, mlir::ConversionPatternRewriter &rewriter, const mlir::TypeConverter *converter); mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage); void convertSideEffectForCall(mlir::Operation *callOp, bool isNothrow, cir::SideEffect sideEffect, mlir::LLVM::MemoryEffectsAttr &memoryEffect, bool &noUnwind, bool &willReturn); class CIRToLLVMAssumeOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::AssumeOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMAssumeAlignedOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::AssumeAlignedOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMAssumeSepStorageOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::AssumeSepStorageOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitClrsbOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitClrsbOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitClzOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitClzOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitCtzOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitCtzOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitFfsOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitFfsOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitParityOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitParityOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitPopcountOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitPopcountOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBitReverseOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BitReverseOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBrCondOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BrCondOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMByteSwapOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ByteSwapOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMCastOpLowering : public mlir::OpConversionPattern { 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 CIRToLLVMExpectOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ExpectOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMReturnOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ReturnOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMRotateOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::RotateOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::CallOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override; }; class CIRToLLVMReturnAddrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ReturnAddrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMFrameAddrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::FrameAddrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMAllocaOpLowering : public mlir::OpConversionPattern { mlir::DataLayout const &dataLayout; public: CIRToLLVMAllocaOpLowering(mlir::TypeConverter const &typeConverter, mlir::MLIRContext *context, mlir::DataLayout const &dataLayout) : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) {} using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::AllocaOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMLoadOpLowering : public mlir::OpConversionPattern { 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 { 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 { 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 { static mlir::StringRef getLinkageAttrNameString() { return "linkage"; } void lowerFuncAttributes( cir::FuncOp func, bool filterArgAndResAttrs, mlir::SmallVectorImpl &result) const; mlir::LogicalResult matchAndRewriteAlias(cir::FuncOp op, llvm::StringRef aliasee, mlir::Type ty, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const; public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::FuncOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMSwitchFlatOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::SwitchFlatOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMGetGlobalOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::GetGlobalOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMGlobalOpLowering : public mlir::OpConversionPattern { 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 { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::UnaryOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBinOpLowering : public mlir::OpConversionPattern { mlir::LLVM::IntegerOverflowFlags getIntOverflowFlag(cir::BinOp op) const; public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BinOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMCmpOpLowering : public mlir::OpConversionPattern { 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 { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ShiftOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMSelectOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::SelectOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMGetMemberOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::GetMemberOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMUnreachableOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::UnreachableOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMTrapOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::TrapOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMPtrStrideOpLowering : public mlir::OpConversionPattern { 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::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::PtrStrideOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMBaseClassAddrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::BaseClassAddrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVTableAddrPointOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VTableAddrPointOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVTableGetVPtrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VTableGetVPtrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVTableGetVirtualFnAddrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern< cir::VTableGetVirtualFnAddrOp>::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VTableGetVirtualFnAddrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMStackSaveOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::StackSaveOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMStackRestoreOpLowering : public mlir::OpConversionPattern { public: using OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::StackRestoreOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override; }; class CIRToLLVMVecCreateOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecCreateOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecExtractOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecExtractOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecInsertOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecInsertOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecCmpOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecCmpOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecSplatOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecSplatOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecShuffleOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecShuffleOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecShuffleDynamicOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern< cir::VecShuffleDynamicOp>::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecShuffleDynamicOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVecTernaryOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VecTernaryOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexCreateOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexCreateOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexRealOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexRealOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexImagOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexImagOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexImagPtrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexImagPtrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexRealPtrOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexRealPtrOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexAddOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexAddOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMComplexSubOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::ComplexSubOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMSetBitfieldOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::SetBitfieldOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMGetBitfieldOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::GetBitfieldOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMFAbsOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::FAbsOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMInlineAsmOpLowering : public mlir::OpConversionPattern { 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::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::InlineAsmOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVAStartOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VAStartOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVAEndOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VAEndOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; class CIRToLLVMVAArgOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; mlir::LogicalResult matchAndRewrite(cir::VAArgOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; } // namespace direct } // namespace cir #endif // CLANG_CIR_LOWERTOLLVM_H