================ @@ -22,16 +34,156 @@ using namespace llvm; namespace cir { namespace direct { +struct ConvertCIRToLLVMPass + : public mlir::PassWrapper<ConvertCIRToLLVMPass, + mlir::OperationPass<mlir::ModuleOp>> { + void getDependentDialects(mlir::DialectRegistry ®istry) const override { + registry.insert<mlir::BuiltinDialect, mlir::DLTIDialect, + mlir::LLVM::LLVMDialect, mlir::func::FuncDialect>(); + } + void runOnOperation() final; + + StringRef getDescription() const override { + return "Convert the prepared CIR dialect module to LLVM dialect"; + } + + StringRef getArgument() const override { return "cir-flat-to-llvm"; } +}; + +// This pass requires the CIR to be in a "flat" state. All blocks in each +// function must belong to the parent region. +mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite( + cir::GlobalOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + + // Fetch required values to create LLVM op. + const mlir::Type cirSymType = op.getSymType(); + + // This is the LLVM dialect type. + const mlir::Type llvmType = getTypeConverter()->convertType(cirSymType); + // FIXME: These default values are placeholders until the the equivalent + // attributes are available on cir.global ops. + const bool isConst = false; + const unsigned addrSpace = 0; + const bool isDsoLocal = true; + const bool isThreadLocal = false; + const uint64_t alignment = 0; + const mlir::LLVM::Linkage linkage = mlir::LLVM::Linkage::External; + const StringRef symbol = op.getSymName(); + std::optional<mlir::Attribute> init = op.getInitialValue(); + + SmallVector<mlir::NamedAttribute> attributes; + + if (init.has_value()) { + if (auto fltAttr = mlir::dyn_cast<cir::FPAttr>(init.value())) { + // Initializer is a constant floating-point number: convert to MLIR + // builtin constant. + init = rewriter.getFloatAttr(llvmType, fltAttr.getValue()); + } else if (auto intAttr = mlir::dyn_cast<cir::IntAttr>(init.value())) { + // Initializer is a constant array: convert it to a compatible llvm init. + init = rewriter.getIntegerAttr(llvmType, intAttr.getValue()); + } else { + op.emitError() << "unsupported initializer '" << init.value() << "'"; + return mlir::failure(); + } + } + + // Rewrite op. + rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>( + op, llvmType, isConst, linkage, symbol, init.value_or(mlir::Attribute()), + alignment, addrSpace, isDsoLocal, isThreadLocal, + /*comdat=*/ mlir::SymbolRefAttr(), attributes); + + return mlir::success(); +} + +static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, + mlir::DataLayout &dataLayout) { + converter.addConversion([&](cir::IntType type) -> mlir::Type { ---------------- erichkeane wrote:
Its a shame there isn't an `addConversions` variadic version of this that we could just call all of these in 1 place. I see this comes from MLIR unfortunately, but perhaps something to suggest upstream elsewhere. https://github.com/llvm/llvm-project/pull/125260 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits