[Mlir-commits] [mlir] [mlir] Add option to add comdat to all linkonce functions (PR #65270)
David Truby
llvmlistbot at llvm.org
Mon Sep 4 08:30:16 PDT 2023
https://github.com/DavidTruby created https://github.com/llvm/llvm-project/pull/65270:
This adds an option to the FuncToLLVM pass to add an Any comdat to each linkonce
and linkonce_odr function when lowering. These comdats are necessary on Windows
to allow the default system linker to link binaries containing these functions.
>From a28350de1a2682a94819526e9c0b10be299aece4 Mon Sep 17 00:00:00 2001
From: David Truby <david at truby.dev>
Date: Mon, 4 Sep 2023 16:06:24 +0100
Subject: [PATCH] [mlir] Add option to add comdat to all linkonce functions
This adds an option to the FuncToLLVM pass to add an Any comdat to each linkonce
and linkonce_odr function when lowering. These comdats are necessary on Windows
to allow the default system linker to link binaries containing these functions.
---
.../Conversion/LLVMCommon/LoweringOptions.h | 1 +
mlir/include/mlir/Conversion/Passes.td | 7 +++--
.../mlir/Dialect/LLVMIR/LLVMAttrDefs.td | 2 +-
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 27 +++++++++++++++++++
.../FuncToLLVM/add-linkonce-comdat.mlir | 17 ++++++++++++
5 files changed, 51 insertions(+), 3 deletions(-)
create mode 100644 mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir
diff --git a/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h b/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
index cc4e17e9527f01e..677fdbb3e973df2 100644
--- a/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
+++ b/mlir/include/mlir/Conversion/LLVMCommon/LoweringOptions.h
@@ -34,6 +34,7 @@ class LowerToLLVMOptions {
bool useBarePtrCallConv = false;
bool useOpaquePointers = true;
+ bool addComdatToLinkonceFuncs = false;
enum class AllocLowering {
/// Use malloc for heap allocations.
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index eaf016bde69e3be..6bcffa32a7010be 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -381,6 +381,9 @@ def ConvertFuncToLLVMPass : Pass<"convert-func-to-llvm", "ModuleOp"> {
Option<"useOpaquePointers", "use-opaque-pointers", "bool",
/*default=*/"true", "Generate LLVM IR using opaque pointers "
"instead of typed pointers">,
+ Option<"addComdatToLinkonceFuncs", "add-comdat-to-linkonce-funcs", "bool",
+ /*default=*/"false", "Add an any comdat selector to Linkonce "
+ "functions">,
];
}
@@ -760,12 +763,12 @@ def ConvertMemRefToSPIRV : Pass<"convert-memref-to-spirv"> {
def ConvertNVVMToLLVMPass : Pass<"convert-nvvm-to-llvm"> {
let summary = "Convert NVVM dialect to LLVM dialect";
let description = [{
- This pass generates inline assembly for the NVVM ops which is not
+ This pass generates inline assembly for the NVVM ops which is not
implemented in LLVM core.
}];
let dependentDialects = [
"NVVM::NVVMDialect",
- ];
+ ];
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index 2443b23e42e43ce..d4a9e911f36b145 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -35,7 +35,7 @@ def CConvAttr : LLVM_Attr<"CConv", "cconv"> {
def ComdatAttr : LLVM_Attr<"Comdat", "comdat"> {
let parameters = (ins "comdat::Comdat":$comdat);
- let assemblyFormat = "$comdat";
+ let assemblyFormat = "`<` $comdat `>`";
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 1db463c0ab7163b..580b4796fbe55f9 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -328,6 +328,25 @@ static void modifyFuncOpToUseBarePtrCallingConv(
namespace {
+template <typename Op>
+void addComdat(Op &op, mlir::PatternRewriter &rewriter,
+ mlir::ModuleOp &module) {
+ const char *comdatName = "__llvm_comdat";
+ mlir::LLVM::ComdatOp comdatOp =
+ module.lookupSymbol<mlir::LLVM::ComdatOp>(comdatName);
+ if (!comdatOp) {
+ comdatOp =
+ rewriter.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
+ }
+ mlir::OpBuilder::InsertionGuard guard(rewriter);
+ rewriter.setInsertionPointToEnd(&comdatOp.getBody().back());
+ auto selectorOp = rewriter.create<mlir::LLVM::ComdatSelectorOp>(
+ comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
+ op.setComdatAttr(mlir::SymbolRefAttr::get(
+ rewriter.getContext(), comdatName,
+ mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr())));
+}
+
struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
protected:
using ConvertOpToLLVMPattern<func::FuncOp>::ConvertOpToLLVMPattern;
@@ -461,6 +480,13 @@ struct FuncOpConversionBase : public ConvertOpToLLVMPattern<func::FuncOp> {
"region types conversion failed");
}
+ if (getTypeConverter()->getOptions().addComdatToLinkonceFuncs &&
+ (newFuncOp.getLinkage() == LLVM::Linkage::Linkonce ||
+ newFuncOp.getLinkage() == LLVM::Linkage::LinkonceODR)) {
+ auto module = newFuncOp->getParentOfType<mlir::ModuleOp>();
+ addComdat(newFuncOp, rewriter, module);
+ }
+
return newFuncOp;
}
};
@@ -764,6 +790,7 @@ struct ConvertFuncToLLVMPass
options.overrideIndexBitwidth(indexBitwidth);
options.dataLayout = llvm::DataLayout(this->dataLayout);
options.useOpaquePointers = useOpaquePointers;
+ options.addComdatToLinkonceFuncs = addComdatToLinkonceFuncs;
LLVMTypeConverter typeConverter(&getContext(), options,
&dataLayoutAnalysis);
diff --git a/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir b/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir
new file mode 100644
index 000000000000000..95cd8b6dd79de65
--- /dev/null
+++ b/mlir/test/Conversion/FuncToLLVM/add-linkonce-comdat.mlir
@@ -0,0 +1,17 @@
+// RUN: mlir-opt -convert-func-to-llvm='add-comdat-to-linkonce-funcs=1' -split-input-file -verify-diagnostics %s | FileCheck %s
+
+// CHECK-DAG: llvm.func linkonce @linkonce() comdat(@__llvm_comdat::@linkonce)
+func.func @linkonce() attributes {llvm.linkage = #llvm.linkage<linkonce>} {
+ return
+}
+
+// CHECK-DAG: llvm.comdat @__llvm_comdat {
+// CHECK: llvm.comdat_selector @linkonce any
+// CHECK: llvm.comdat_selector @linkonce_odr any
+// CHECK: }
+
+
+// CHECK-DAG: llvm.func linkonce_odr @linkonce_odr() comdat(@__llvm_comdat::@linkonce_odr)
+func.func @linkonce_odr() attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
+ return
+}
More information about the Mlir-commits
mailing list