blob: d9fb91066317b62d5c5ffdf8de97b872aa54c5bc [file] [log] [blame]
//====- 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<cir::AssumeOp> {
public:
using mlir::OpConversionPattern<cir::AssumeOp>::OpConversionPattern;
mlir::LogicalResult
matchAndRewrite(cir::AssumeOp 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 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 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 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 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 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 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;
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 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 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 CIRToLLVMGetBitfieldOpLowering
: public mlir::OpConversionPattern<cir::GetBitfieldOp> {
public:
using mlir::OpConversionPattern<cir::GetBitfieldOp>::OpConversionPattern;
mlir::LogicalResult
matchAndRewrite(cir::GetBitfieldOp op, OpAdaptor,
mlir::ConversionPatternRewriter &) const override;
};
} // namespace direct
} // namespace cir
#endif // CLANG_CIR_LOWERTOLLVM_H