Skip to content

[libc] Install a single LLVM-IR version of the GPU library #82791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions libc/cmake/modules/LLVMLibCLibraryRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ endfunction()
# add_gpu_entrypoint_library(
# DEPENDS <list of add_entrypoint_object targets>
# )
function(add_gpu_entrypoint_library target_name)
function(add_gpu_entrypoint_library target_name base_target_name)
cmake_parse_arguments(
"ENTRYPOINT_LIBRARY"
"" # No optional arguments
Expand Down Expand Up @@ -127,7 +127,7 @@ function(add_gpu_entrypoint_library target_name)
COMMAND ${LIBC_CLANG_OFFLOAD_PACKAGER}
"${prefix},file=$<JOIN:${object},,file=>" -o
${CMAKE_CURRENT_BINARY_DIR}/binary/${name}.gpubin
DEPENDS ${dep}
DEPENDS ${dep} ${base_target_name}
COMMENT "Packaging LLVM offloading binary for '${object}'"
)
add_custom_target(${dep}.__gpubin__ DEPENDS ${dep}
Expand All @@ -140,7 +140,7 @@ function(add_gpu_entrypoint_library target_name)
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/stubs/${name}.cpp"
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/stubs
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/stubs/${name}.cpp
DEPENDS ${dep} ${dep}.__gpubin__
DEPENDS ${dep} ${dep}.__gpubin__ ${base_target_name}
)
add_custom_target(${dep}.__stub__
DEPENDS ${dep}.__gpubin__ "${CMAKE_CURRENT_BINARY_DIR}/stubs/${name}.cpp")
Expand All @@ -156,7 +156,8 @@ function(add_gpu_entrypoint_library target_name)
target_compile_options(${dep}.__fatbin__ PRIVATE
--target=${LLVM_HOST_TRIPLE}
"SHELL:-Xclang -fembed-offload-object=${CMAKE_CURRENT_BINARY_DIR}/binary/${name}.gpubin")
add_dependencies(${dep}.__fatbin__ ${dep} ${dep}.__stub__ ${dep}.__gpubin__)
add_dependencies(${dep}.__fatbin__
${dep} ${dep}.__stub__ ${dep}.__gpubin__ ${base_target_name})

# Set the list of newly create fat binaries containing embedded device code.
list(APPEND objects $<TARGET_OBJECTS:${dep}.__fatbin__>)
Expand All @@ -170,6 +171,46 @@ function(add_gpu_entrypoint_library target_name)
set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
endfunction(add_gpu_entrypoint_library)

# A rule to build a library from a collection of entrypoint objects and bundle
# it in a single LLVM-IR bitcode file.
# Usage:
# add_gpu_entrypoint_library(
# DEPENDS <list of add_entrypoint_object targets>
# )
function(add_bitcode_entrypoint_library target_name base_target_name)
cmake_parse_arguments(
"ENTRYPOINT_LIBRARY"
"" # No optional arguments
"" # No single value arguments
"DEPENDS" # Multi-value arguments
${ARGN}
)
if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
"of 'add_entrypoint_object' targets.")
endif()

get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS})
get_all_object_file_deps(all_deps "${fq_deps_list}")

set(objects "")
foreach(dep IN LISTS all_deps)
set(object $<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${dep}>,${dep}>:$<TARGET_OBJECTS:${dep}>>)
list(APPEND objects ${object})
endforeach()

set(output ${CMAKE_CURRENT_BINARY_DIR}/${target_name}.bc)
add_custom_command(
OUTPUT ${output}
COMMAND ${LIBC_LLVM_LINK} ${objects} -o ${output}
DEPENDS ${all_deps} ${base_target_name}
COMMENT "Linking LLVM-IR bitcode for ${base_target_name}"
COMMAND_EXPAND_LISTS
)
add_custom_target(${target_name} DEPENDS ${output} ${all_deps})
set_target_properties(${target_name} PROPERTIES TARGET_OBJECT ${output})
endfunction(add_bitcode_entrypoint_library)

# A rule to build a library from a collection of entrypoint objects.
# Usage:
# add_entrypoint_library(
Expand Down
8 changes: 8 additions & 0 deletions libc/cmake/modules/prepare_libc_gpu_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ if(NOT LIBC_CLANG_OFFLOAD_PACKAGER)
"build")
endif()

# Identify llvm-link program so we can merge the output IR into a single blob.
find_program(LIBC_LLVM_LINK
NAMES llvm-link NO_DEFAULT_PATH
PATHS ${LLVM_BINARY_DIR}/bin ${compiler_path})
if(NOT LIBC_LLVM_LINK)
message(FATAL_ERROR "Cannot find 'llvm-link' for the GPU build")
endif()

# Optionally set up a job pool to limit the number of GPU tests run in parallel.
# This is sometimes necessary as running too many tests in parallel can cause
# the GPU or driver to run out of resources.
Expand Down
36 changes: 27 additions & 9 deletions libc/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,33 @@ foreach(archive IN ZIP_LISTS
# Add the offloading version of the library for offloading languages. These
# are installed in the standard search path separate from the other libraries.
if(LIBC_TARGET_OS_IS_GPU)
set(libc_gpu_archive_target ${archive_1}gpu)
set(libc_gpu_archive_name ${archive_0}gpu-${LIBC_TARGET_ARCHITECTURE})

add_gpu_entrypoint_library(
${libc_gpu_archive_target}
${archive_1}gpu
${archive_1}
DEPENDS
${${archive_2}}
)
set_target_properties(
${libc_gpu_archive_target}
${archive_1}gpu
PROPERTIES
ARCHIVE_OUTPUT_NAME ${libc_gpu_archive_name}
ARCHIVE_OUTPUT_NAME ${archive_0}gpu-${LIBC_TARGET_ARCHITECTURE}
ARCHIVE_OUTPUT_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR}
)
list(APPEND added_gpu_archive_targets ${archive_1}gpu)

add_bitcode_entrypoint_library(
${archive_1}bitcode
${archive_1}
DEPENDS
${${archive_2}}
)
set_target_properties(${libc_gpu_archive_target} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR})
list(APPEND added_gpu_archive_targets ${libc_gpu_archive_target})
set_target_properties(
${archive_1}bitcode
PROPERTIES
OUTPUT_NAME ${archive_1}.bc
)
add_dependencies(${archive_1}gpu ${archive_1}bitcode)
list(APPEND added_gpu_bitcode_targets ${archive_1}bitcode)
endif()
endforeach()

Expand All @@ -71,6 +82,13 @@ if(LIBC_TARGET_OS_IS_GPU)
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
COMPONENT libc
)
foreach(file ${added_gpu_bitcode_targets})
install(FILES $<TARGET_PROPERTY:${file},TARGET_OBJECT>
DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
RENAME $<TARGET_PROPERTY:${file},OUTPUT_NAME>
COMPONENT libc
)
endforeach()
endif()

if(NOT LIBC_TARGET_OS_IS_BAREMETAL)
Expand Down