[llvm] [offload] Fix link issues when LLVM_LINK_LLVM_DYLIB on (PR #106583)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 10 09:40:54 PDT 2024
https://github.com/macurtis-amd updated https://github.com/llvm/llvm-project/pull/106583
>From 67333add1da6da9b2cb5fce1da96fa932e9cc631 Mon Sep 17 00:00:00 2001
From: Matthew Curtis <macurtis at amd.com>
Date: Thu, 29 Aug 2024 10:43:31 -0500
Subject: [PATCH] [offload] Fix link issues when LLVM_LINK_LLVM_DYLIB on
When LLVM_LINK_LLVM_DYLIB is on, link against LLVM (shared library) rather than
individual (static) libraries. Otherwise, global initializers may get called
multiple times as multiple copies of LLVM libraries are loaded.
This typically results in a runtime error such as:
Error: CommandLine Error: Option ... registered more than once
See related commit ea8bb4d633683f5cbfd82491620be3056f347a02
---
offload/plugins-nextgen/CMakeLists.txt | 3 +
offload/plugins-nextgen/amdgpu/CMakeLists.txt | 24 +++++---
offload/plugins-nextgen/common/CMakeLists.txt | 32 +++++-----
offload/src/CMakeLists.txt | 61 +++++++++++++++++++
4 files changed, 95 insertions(+), 25 deletions(-)
diff --git a/offload/plugins-nextgen/CMakeLists.txt b/offload/plugins-nextgen/CMakeLists.txt
index d31bf557669eac..07ae6175aed726 100644
--- a/offload/plugins-nextgen/CMakeLists.txt
+++ b/offload/plugins-nextgen/CMakeLists.txt
@@ -2,6 +2,8 @@
set(common_dir ${CMAKE_CURRENT_SOURCE_DIR}/common)
add_subdirectory(common)
function(add_target_library target_name lib_name)
+ cmake_parse_arguments(ARG "" "" "LINK_COMPONENTS" ${ARGN})
+
add_llvm_library(${target_name} STATIC
LINK_COMPONENTS
AggressiveInstCombine
@@ -27,6 +29,7 @@ function(add_target_library target_name lib_name)
TargetParser
TransformUtils
Vectorize
+ ${ARG_LINK_COMPONENTS}
NO_INSTALL_RPATH
BUILDTREE_ONLY
diff --git a/offload/plugins-nextgen/amdgpu/CMakeLists.txt b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
index b40c62d43226f4..fb04fc85baf90c 100644
--- a/offload/plugins-nextgen/amdgpu/CMakeLists.txt
+++ b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
@@ -1,23 +1,27 @@
# As of rocm-3.7, hsa is installed with cmake packages and kmt is found via hsa
find_package(hsa-runtime64 QUIET 1.2.0 HINTS ${CMAKE_INSTALL_PREFIX} PATHS /opt/rocm)
-# Create the library and add the default arguments.
-add_target_library(omptarget.rtl.amdgpu AMDGPU)
-
-target_sources(omptarget.rtl.amdgpu PRIVATE src/rtl.cpp)
-target_include_directories(omptarget.rtl.amdgpu PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}/utils)
+set(inc_dirs ${CMAKE_CURRENT_SOURCE_DIR}/utils)
+set(link_libs)
+set(tgt_srcs src/rtl.cpp)
if(hsa-runtime64_FOUND AND NOT "amdgpu" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
message(STATUS "Building AMDGPU plugin linked against libhsa")
- target_link_libraries(omptarget.rtl.amdgpu PRIVATE hsa-runtime64::hsa-runtime64 LLVMFrontendOffloading)
+ list(APPEND link_comps FrontendOffloading)
+ list(APPEND link_libs hsa-runtime64::hsa-runtime64)
else()
message(STATUS "Building AMDGPU plugin for dlopened libhsa")
- target_include_directories(omptarget.rtl.amdgpu PRIVATE dynamic_hsa)
- target_sources(omptarget.rtl.amdgpu PRIVATE dynamic_hsa/hsa.cpp)
- target_link_libraries(omptarget.rtl.amdgpu PRIVATE LLVMFrontendOffloading)
+ list(APPEND inc_dirs dynamic_hsa)
+ list(APPEND tgt_srcs dynamic_hsa/hsa.cpp)
+ list(APPEND link_comps FrontendOffloading)
endif()
+# Create the library and add the default arguments.
+add_target_library(omptarget.rtl.amdgpu AMDGPU LINK_COMPONENTS ${link_comps})
+target_sources(omptarget.rtl.amdgpu PRIVATE ${tgt_srcs})
+target_include_directories(omptarget.rtl.amdgpu PRIVATE ${inc_dirs})
+target_link_libraries(omptarget.rtl.amdgpu PRIVATE ${link_libs})
+
# Configure testing for the AMDGPU plugin. We will build tests if we could a
# functional AMD GPU on the system, or if manually specifies by the user.
option(LIBOMPTARGET_FORCE_AMDGPU_TESTS "Build AMDGPU libomptarget tests" OFF)
diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt
index 4dca5422087bba..b9f27caa5b5c1c 100644
--- a/offload/plugins-nextgen/common/CMakeLists.txt
+++ b/offload/plugins-nextgen/common/CMakeLists.txt
@@ -1,25 +1,28 @@
-# NOTE: Don't try to build `PluginInterface` using `add_llvm_library` because we
-# don't want to export `PluginInterface` while `add_llvm_library` requires that.
-add_library(PluginCommon OBJECT
+# Only enable JIT for those targets that LLVM can support.
+set(jit_targets_to_build "AMDGPU;NVPTX")
+set(jit_targets_not_to_build ${jit_targets_to_build})
+list(REMOVE_ITEM jit_targets_not_to_build ${LLVM_TARGETS_TO_BUILD})
+list(REMOVE_ITEM jit_targets_to_build ${jit_targets_not_to_build})
+
+add_llvm_library(PluginCommon STATIC
src/PluginInterface.cpp
src/GlobalHandler.cpp
src/JIT.cpp
src/RPC.cpp
src/Utils/ELF.cpp
+
+ LINK_COMPONENTS
+ ProfileData
+ ${jit_targets_to_build}
+
+ BUILDTREE_ONLY
)
add_dependencies(PluginCommon intrinsics_gen LLVMProfileData)
-# Only enable JIT for those targets that LLVM can support.
-set(supported_jit_targets AMDGPU NVPTX)
-if (NOT LLVM_LINK_LLVM_DYLIB)
- foreach(target IN LISTS supported_jit_targets)
- if("${target}" IN_LIST LLVM_TARGETS_TO_BUILD)
- target_compile_definitions(PluginCommon PRIVATE "LIBOMPTARGET_JIT_${target}")
- llvm_map_components_to_libnames(llvm_libs ${target})
- target_link_libraries(PluginCommon PRIVATE ${llvm_libs})
- endif()
- endforeach()
-endif()
+list(TRANSFORM jit_targets_to_build
+ PREPEND "LIBOMPTARGET_JIT_" OUTPUT_VARIABLE compile_defs
+)
+target_compile_definitions(PluginCommon PRIVATE ${compile_defs})
# Include the RPC server from the `libc` project if availible.
if(TARGET llvmlibc_rpc_server AND ${LIBOMPTARGET_GPU_LIBC_SUPPORT})
@@ -52,7 +55,6 @@ target_compile_definitions(PluginCommon PRIVATE
target_compile_options(PluginCommon PUBLIC ${offload_compile_flags})
target_link_options(PluginCommon PUBLIC ${offload_link_flags})
-target_link_libraries(PluginCommon PRIVATE LLVMProfileData)
target_include_directories(PluginCommon PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
diff --git a/offload/src/CMakeLists.txt b/offload/src/CMakeLists.txt
index c5f5d902fad14c..d1584ccc34863d 100644
--- a/offload/src/CMakeLists.txt
+++ b/offload/src/CMakeLists.txt
@@ -69,3 +69,64 @@ set_target_properties(omptarget PROPERTIES
INSTALL_RPATH "$ORIGIN"
BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
install(TARGETS omptarget LIBRARY COMPONENT omptarget DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+
+#===============================================================================
+# Ensure that omptarget does not contain a mixture of static and dynamically
+# linked LLVM libs.
+#===============================================================================
+if (LLVM_LINK_LLVM_DYLIB)
+ if(LLVM_AVAILABLE_LIBS)
+ set(llvm_libs ${LLVM_AVAILABLE_LIBS})
+ else()
+ # Inside LLVM itself available libs are in a global property.
+ get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS)
+ endif()
+
+ #-----------------------------------------------------------------------------
+ # Helper function to recursively get the llvm targets that 'tgt' links against
+ #-----------------------------------------------------------------------------
+ function(get_llvm_link_targets var tgt visited)
+ list(APPEND visited ${tgt})
+
+ get_target_property(link_libs ${tgt} LINK_LIBRARIES)
+ if(NOT link_libs)
+ set(link_libs "")
+ endif()
+ get_target_property(i_link_libs ${tgt} INTERFACE_LINK_LIBRARIES)
+ if(i_link_libs)
+ list(APPEND link_libs ${i_link_libs})
+ endif()
+ if(NOT link_libs)
+ return()
+ endif()
+ list(REMOVE_DUPLICATES link_libs)
+ list(REMOVE_ITEM link_libs ${visited})
+
+ foreach(lib ${link_libs})
+ if(${lib} IN_LIST llvm_libs)
+ list(APPEND rv ${lib})
+ endif()
+ if(TARGET ${lib})
+ get_llvm_link_targets(indirect ${lib} ${visited})
+ list(APPEND rv ${indirect})
+ endif()
+ list(REMOVE_DUPLICATES rv)
+ endforeach()
+
+ set(visited ${visited} PARENT_SCOPE)
+ set(${var} ${rv} PARENT_SCOPE)
+ endfunction()
+
+ #-----------------------------------------------------------------------------
+ # Check for extraneous libs
+ #-----------------------------------------------------------------------------
+ get_llvm_link_targets(llvm_link_targets omptarget "" 0)
+ list(REMOVE_ITEM llvm_link_targets "LLVM")
+ if(llvm_link_targets)
+ list(JOIN llvm_link_targets " " pp_list)
+ message(
+ FATAL_ERROR
+ "'omptarget' should only link against 'LLVM' when 'LLVM_LINK_LLVM_DYLIB' "
+ "is on. Extraneous LLVM Libraries: ${pp_list}")
+ endif()
+endif()
More information about the llvm-commits
mailing list