diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 41c30b81770bc..549a37de2e412 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -1327,4 +1327,23 @@ def ModuleFlagAttr let assemblyFormat = "`<` $behavior `,` $key `,` $value `>`"; } +//===----------------------------------------------------------------------===// +// LLVM_DependentLibrariesAttr +//===----------------------------------------------------------------------===// + +def LLVM_DependentLibrariesAttr + : LLVM_Attr<"DependentLibraries", "dependent_libraries"> { + let summary = "LLVM dependent libraries attribute"; + let description = [{ + Represents the list of dependent libraries for the current module. + This attribute is used to specify the libraries that the module depends + on, and it can be used for linking purposes. + + See the following links for more details: + https://llvm.org/docs/LangRef.html#dependent-libs-named-metadata + }]; + let parameters = (ins OptionalArrayRefParameter<"StringAttr">:$libs); + let assemblyFormat = "`<` $libs `>`"; +} + #endif // LLVMIR_ATTRDEFS diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td index 46fae44f7b0fa..7f8b3aa833a37 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td @@ -83,6 +83,11 @@ def LLVM_Dialect : Dialect { return "llvm.emit_c_interface"; } + /// Name of the dependent libraries attribute. + static StringRef getDependentLibrariesAttrName() { + return "llvm.dependent_libraries"; + } + /// Returns `true` if the given type is compatible with the LLVM dialect. static bool isCompatibleType(Type); diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h index 3b164927d41fd..3dc848c413905 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -229,6 +229,10 @@ class ModuleImport { /// attribute. LogicalResult convertCommandlineMetadata(); + /// Converts !llvm.dependent-libraries metadata to llvm.dependent_libraries + /// LLVM ModuleOp attribute. + LogicalResult convertDependentLibrariesMetadata(); + /// Converts all LLVM metadata nodes that translate to attributes such as /// alias analysis or access group metadata, and builds a map from the /// metadata nodes to the converted attributes. diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h index 01dda6238d8f3..99b1b65aeb6a5 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -363,6 +363,9 @@ class ModuleTranslation { /// Process the llvm.commandline LLVM Metadata, if it exists. LogicalResult createCommandlineMetadata(); + /// Process the llvm.dependent_libraries LLVM Metadata, if it exists. + LogicalResult createDependentLibrariesMetadata(); + /// Translates dialect attributes attached to the given operation. LogicalResult convertDialectAttributes(Operation *op, diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index c0711f7dded71..fead71052f6db 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -563,6 +563,23 @@ LogicalResult ModuleImport::convertLinkerOptionsMetadata() { return success(); } +LogicalResult ModuleImport::convertDependentLibrariesMetadata() { + for (const llvm::NamedMDNode &named : llvmModule->named_metadata()) { + if (named.getName() != "llvm.dependent-libraries") + continue; + SmallVector libraries; + for (const llvm::MDNode *node : named.operands()) { + if (node->getNumOperands() == 1) + if (auto *mdString = dyn_cast(node->getOperand(0))) + libraries.push_back(mdString->getString()); + } + if (!libraries.empty()) + mlirModule->setAttr(LLVM::LLVMDialect::getDependentLibrariesAttrName(), + builder.getStrArrayAttr(libraries)); + } + return success(); +} + LogicalResult ModuleImport::convertIdentMetadata() { for (const llvm::NamedMDNode &named : llvmModule->named_metadata()) { // llvm.ident should have a single operand. That operand is itself an @@ -625,6 +642,8 @@ LogicalResult ModuleImport::convertMetadata() { } if (failed(convertLinkerOptionsMetadata())) return failure(); + if (failed(convertDependentLibrariesMetadata())) + return failure(); if (failed(convertModuleFlagsMetadata())) return failure(); if (failed(convertIdentMetadata())) diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 1e2f2c0468045..d30cb8a7d7974 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -2036,6 +2036,22 @@ LogicalResult ModuleTranslation::createCommandlineMetadata() { return success(); } +LogicalResult ModuleTranslation::createDependentLibrariesMetadata() { + if (auto dependentLibrariesAttr = mlirModule->getDiscardableAttr( + LLVM::LLVMDialect::getDependentLibrariesAttrName())) { + auto *nmd = + llvmModule->getOrInsertNamedMetadata("llvm.dependent-libraries"); + llvm::LLVMContext &ctx = llvmModule->getContext(); + for (auto libAttr : + cast(dependentLibrariesAttr).getAsRange()) { + auto *md = + llvm::MDNode::get(ctx, llvm::MDString::get(ctx, libAttr.getValue())); + nmd->addOperand(md); + } + } + return success(); +} + void ModuleTranslation::setLoopMetadata(Operation *op, llvm::Instruction *inst) { LoopAnnotationAttr attr = @@ -2201,6 +2217,8 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, return nullptr; if (failed(translator.createCommandlineMetadata())) return nullptr; + if (failed(translator.createDependentLibrariesMetadata())) + return nullptr; // Convert other top-level operations if possible. for (Operation &o : getModuleBody(module).getOperations()) { diff --git a/mlir/test/Target/LLVMIR/Import/metadata-dependent-libraries.ll b/mlir/test/Target/LLVMIR/Import/metadata-dependent-libraries.ll new file mode 100644 index 0000000000000..4a6d438046a36 --- /dev/null +++ b/mlir/test/Target/LLVMIR/Import/metadata-dependent-libraries.ll @@ -0,0 +1,6 @@ +; RUN: mlir-translate -import-llvm %s | FileCheck %s + +; CHECK: llvm.dependent_libraries = ["foo", "bar"] +!llvm.dependent-libraries = !{!0, !1} +!0 = !{!"foo"} +!1 = !{!"bar"} diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 0238c95835a0f..21d50531c5083 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -2796,6 +2796,14 @@ module { // ----- +module attributes {llvm.dependent_libraries = ["foo", "bar"]} {} + +// CHECK: !llvm.dependent-libraries = !{![[#LIBFOO:]], ![[#LIBBAR:]]} +// CHECK: ![[#LIBFOO]] = !{!"foo"} +// CHECK: ![[#LIBBAR]] = !{!"bar"} + +// ----- + llvm.mlir.global external constant @const() {addr_space = 0 : i32, dso_local} : i32 { %0 = llvm.mlir.addressof @const : !llvm.ptr %1 = llvm.ptrtoint %0 : !llvm.ptr to i64