[clang] [CIR] Initial implementation of CIR-to-LLVM IR lowering pass (PR #125260)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 31 11:12:54 PST 2025
================
@@ -22,13 +34,127 @@ 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"; }
+};
+
+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);
+ // These defaults are just here until the equivalent attributes are
+ // available on cir.global ops.
+ const bool isConst = false;
+ const bool isDsoLocal = true;
+ 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;
+
+ // Check for missing funcionalities.
+ if (!init.has_value()) {
+ rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
+ op, llvmType, isConst, linkage, symbol, mlir::Attribute(),
+ /*alignment*/ 0, /*addrSpace*/ 0, /*dsoLocal*/ isDsoLocal,
+ /*threadLocal*/ false, /*comdat*/ mlir::SymbolRefAttr(), attributes);
+ return mlir::success();
+ }
+
+ // Initializer is a constant array: convert it to a compatible llvm init.
+ if (auto intAttr = mlir::dyn_cast<cir::IntAttr>(init.value())) {
+ 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(), /*alignment*/ 0,
+ /*addrSpace*/ 0, /*dsoLocal*/ isDsoLocal, /*threadLocal*/ false,
+ /*comdat*/ mlir::SymbolRefAttr(), attributes);
+
+ return mlir::success();
+}
+
+static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
+ mlir::DataLayout &dataLayout) {
+ converter.addConversion([&](cir::IntType type) -> mlir::Type {
+ // LLVM doesn't work with signed types, so we drop the CIR signs here.
+ return mlir::IntegerType::get(type.getContext(), type.getWidth());
+ });
+}
+
+void ConvertCIRToLLVMPass::runOnOperation() {
+ llvm::TimeTraceScope scope("Convert CIR to LLVM Pass");
+
+ mlir::ModuleOp module = getOperation();
----------------
erichkeane wrote:
Got it, thanks! The copy just looked suspicious for something that is named so impactfully :)
https://github.com/llvm/llvm-project/pull/125260
More information about the cfe-commits
mailing list