Skip to content

Commit 0881d0f

Browse files
authored
[libc] Refactor _build_gpu_objects cmake function. (#80631)
1 parent 8cb2de7 commit 0881d0f

File tree

8 files changed

+129
-96
lines changed

8 files changed

+129
-96
lines changed

libc/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ set(TARGET_ENTRYPOINT_NAME_LIST "")
340340
foreach(entrypoint IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
341341
string(FIND ${entrypoint} "." last_dot_loc REVERSE)
342342
if(${last_dot_loc} EQUAL -1)
343-
message(FATAL "Invalid entrypoint target name ${entrypoint}; Expected a '.' "
344-
"(dot) in the name.")
343+
message(FATAL_ERROR "Invalid entrypoint target name ${entrypoint}; Expected"
344+
" a '.' (dot) in the name.")
345345
endif()
346346
math(EXPR name_loc "${last_dot_loc} + 1")
347347
string(SUBSTRING ${entrypoint} ${name_loc} -1 entrypoint_name)

libc/cmake/modules/LLVMLibCObjectRules.cmake

Lines changed: 107 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -145,21 +145,78 @@ function(get_nvptx_compile_options output_var gpu_arch)
145145
set(${output_var} ${nvptx_options} PARENT_SCOPE)
146146
endfunction()
147147

148-
# Builds the object target for the GPU.
148+
# Build the object target for a single GPU arch.
149+
# Usage:
150+
# _build_gpu_object_for_single_arch(
151+
# <target_name>
152+
# <gpu_arch>
153+
# SRCS <list of .cpp files>
154+
# HDRS <list of .h files>
155+
# DEPENDS <list of dependencies>
156+
# COMPILE_OPTIONS <optional list of special compile options for this target>
157+
# FLAGS <optional list of flags>
158+
# )
159+
function(_build_gpu_object_for_single_arch fq_target_name gpu_arch)
160+
cmake_parse_arguments(
161+
"ADD_GPU_OBJ"
162+
"" # No optional arguments
163+
"NAME;CXX_STANDARD" # Single value arguments
164+
"SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;FLAGS" # Multi value arguments
165+
${ARGN}
166+
)
167+
168+
if(NOT ADD_GPU_OBJ_CXX_STANDARD)
169+
set(ADD_GPU_OBJ_CXX_STANDARD ${CMAKE_CXX_STANDARD})
170+
endif()
171+
172+
set(compile_options ${ADD_GPU_OBJ_COMPILE_OPTIONS})
173+
# Derive the triple from the specified architecture.
174+
if("${gpu_arch}" IN_LIST all_amdgpu_architectures)
175+
set(gpu_target_triple ${AMDGPU_TARGET_TRIPLE})
176+
list(APPEND compile_options "-mcpu=${gpu_arch}")
177+
list(APPEND compile_options "SHELL:-Xclang -mcode-object-version=none")
178+
list(APPEND compile_options "-emit-llvm")
179+
elseif("${gpu_arch}" IN_LIST all_nvptx_architectures)
180+
set(gpu_target_triple ${NVPTX_TARGET_TRIPLE})
181+
get_nvptx_compile_options(nvptx_options ${gpu_arch})
182+
list(APPEND compile_options "${nvptx_options}")
183+
else()
184+
message(FATAL_ERROR "Unknown GPU architecture '${gpu_arch}'")
185+
endif()
186+
list(APPEND compile_options "--target=${gpu_target_triple}")
187+
188+
# Build the library for this target architecture. We always emit LLVM-IR for
189+
# packaged GPU binaries.
190+
add_library(${fq_target_name}
191+
EXCLUDE_FROM_ALL
192+
OBJECT
193+
${ADD_GPU_OBJ_SRCS}
194+
${ADD_GPU_OBJ_HDRS}
195+
)
196+
197+
target_compile_options(${fq_target_name} PRIVATE ${compile_options})
198+
target_include_directories(${fq_target_name} SYSTEM PRIVATE ${LIBC_INCLUDE_DIR})
199+
target_include_directories(${fq_target_name} PRIVATE ${LIBC_SOURCE_DIR})
200+
set_target_properties(${fq_target_name} PROPERTIES CXX_STANDARD ${ADD_GPU_OBJ_CXX_STANDARD})
201+
if(ADD_GPU_OBJ_DEPENDS)
202+
add_dependencies(${fq_target_name} ${ADD_GPU_OBJ_DEPENDS})
203+
set_target_properties(${fq_target_name} PROPERTIES DEPS "${ADD_GPU_OBJ_DEPENDS}")
204+
endif()
205+
endfunction(_build_gpu_object_for_single_arch)
206+
207+
# Build the object target for the GPU.
149208
# This compiles the target for all supported architectures and embeds it into
150-
# host binary for installing. The internal target contains the GPU code directly
151-
# compiled for a single architecture used internally.
209+
# host binary for installing.
152210
# Usage:
153-
# _build_gpu_objects(
211+
# _build_gpu_object_bundle(
154212
# <target_name>
155-
# <internal_target_name>
156213
# SRCS <list of .cpp files>
157214
# HDRS <list of .h files>
158215
# DEPENDS <list of dependencies>
159216
# COMPILE_OPTIONS <optional list of special compile options for this target>
160217
# FLAGS <optional list of flags>
161218
# )
162-
function(_build_gpu_objects fq_target_name internal_target_name)
219+
function(_build_gpu_object_bundle fq_target_name)
163220
cmake_parse_arguments(
164221
"ADD_GPU_OBJ"
165222
"" # No optional arguments
@@ -168,7 +225,6 @@ function(_build_gpu_objects fq_target_name internal_target_name)
168225
${ARGN}
169226
)
170227

171-
set(common_compile_options ${ADD_GPU_OBJ_COMPILE_OPTIONS})
172228
if(NOT ADD_GPU_OBJ_CXX_STANDARD)
173229
set(ADD_GPU_OBJ_CXX_STANDARD ${CMAKE_CXX_STANDARD})
174230
endif()
@@ -179,49 +235,28 @@ function(_build_gpu_objects fq_target_name internal_target_name)
179235
foreach(gpu_arch ${LIBC_GPU_ARCHITECTURES})
180236
get_filename_component(src_name ${add_gpu_obj_src} NAME)
181237
set(gpu_target_name ${fq_target_name}.${src_name}.${gpu_arch})
182-
set(compile_options ${ADD_GPU_OBJ_COMPILE_OPTIONS})
183-
# Derive the triple from the specified architecture.
184-
if("${gpu_arch}" IN_LIST all_amdgpu_architectures)
185-
set(gpu_target_triple "amdgcn-amd-amdhsa")
186-
list(APPEND compile_options "-mcpu=${gpu_arch}")
187-
list(APPEND compile_options "SHELL:-Xclang -mcode-object-version=none")
188-
elseif("${gpu_arch}" IN_LIST all_nvptx_architectures)
189-
set(gpu_target_triple "nvptx64-nvidia-cuda")
190-
get_nvptx_compile_options(nvptx_options ${gpu_arch})
191-
list(APPEND compile_options "${nvptx_options}")
192-
else()
193-
message(FATAL_ERROR "Unknown GPU architecture '${gpu_arch}'")
194-
endif()
195-
list(APPEND compile_options "--target=${gpu_target_triple}")
196-
list(APPEND compile_options "-emit-llvm")
197-
198-
# Build the library for this target architecture. We always emit LLVM-IR for
199-
# packaged GPU binaries.
200-
add_library(${gpu_target_name}
201-
EXCLUDE_FROM_ALL
202-
OBJECT
203-
${add_gpu_obj_src}
204-
${ADD_GPU_OBJ_HDRS}
205-
)
206-
207-
target_compile_options(${gpu_target_name} PRIVATE ${compile_options})
208-
target_include_directories(${gpu_target_name} SYSTEM PRIVATE ${LIBC_INCLUDE_DIR})
209-
target_include_directories(${gpu_target_name} PRIVATE ${LIBC_SOURCE_DIR})
210-
target_compile_definitions(${gpu_target_name} PRIVATE LIBC_COPT_PUBLIC_PACKAGING)
211-
set_target_properties(${gpu_target_name} PROPERTIES CXX_STANDARD ${ADD_GPU_OBJ_CXX_STANDARD})
212-
if(ADD_GPU_OBJ_DEPENDS)
213-
add_dependencies(${gpu_target_name} ${ADD_GPU_OBJ_DEPENDS})
214-
endif()
215238

239+
_build_gpu_object_for_single_arch(
240+
${gpu_target_name}
241+
${gpu_arch}
242+
CXX_STANDARD ${ADD_GPU_OBJ_CXX_STANDARD}
243+
HDRS ${ADD_GPU_OBJ_HDRS}
244+
SRCS ${add_gpu_obj_src}
245+
COMPILE_OPTIONS
246+
${ADD_GPU_OBJ_COMPILE_OPTIONS}
247+
"-emit-llvm"
248+
DEPENDS ${ADD_GPU_OBJ_DEPENDS}
249+
)
216250
# Append this target to a list of images to package into a single binary.
217251
set(input_file $<TARGET_OBJECTS:${gpu_target_name}>)
218252
if("${gpu_arch}" IN_LIST all_nvptx_architectures)
253+
get_nvptx_compile_options(nvptx_options ${gpu_arch})
219254
string(REGEX MATCH "\\+ptx[0-9]+" nvptx_ptx_feature ${nvptx_options})
220255
list(APPEND packager_images
221-
--image=file=${input_file},arch=${gpu_arch},triple=${gpu_target_triple},feature=${nvptx_ptx_feature})
256+
--image=file=${input_file},arch=${gpu_arch},triple=${NVPTX_TARGET_TRIPLE},feature=${nvptx_ptx_feature})
222257
else()
223258
list(APPEND packager_images
224-
--image=file=${input_file},arch=${gpu_arch},triple=${gpu_target_triple})
259+
--image=file=${input_file},arch=${gpu_arch},triple=${AMDGPU_TARGET_TRIPLE})
225260
endif()
226261
list(APPEND gpu_target_objects ${input_file})
227262
endforeach()
@@ -269,7 +304,7 @@ function(_build_gpu_objects fq_target_name internal_target_name)
269304
${CMAKE_CURRENT_BINARY_DIR}/stubs/${stub_filename}
270305
)
271306
target_compile_options(${fq_target_name} BEFORE PRIVATE
272-
${common_compile_options} -nostdlib)
307+
${ADD_GPU_OBJ_COMPILE_OPTIONS} -nostdlib)
273308
foreach(packaged_gpu_binary ${packaged_gpu_binaries})
274309
target_compile_options(${fq_target_name} PRIVATE
275310
"SHELL:-Xclang -fembed-offload-object=${packaged_gpu_binary}")
@@ -278,33 +313,6 @@ function(_build_gpu_objects fq_target_name internal_target_name)
278313
target_include_directories(${fq_target_name} PRIVATE ${LIBC_SOURCE_DIR})
279314
add_dependencies(${fq_target_name}
280315
${full_deps_list} ${packaged_gpu_names} ${stub_target_name})
281-
282-
# We only build the internal target for a single supported architecture.
283-
if(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU OR
284-
LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
285-
add_library(
286-
${internal_target_name}
287-
EXCLUDE_FROM_ALL
288-
OBJECT
289-
${ADD_GPU_OBJ_SRCS}
290-
${ADD_GPU_OBJ_HDRS}
291-
)
292-
target_compile_options(${internal_target_name} BEFORE PRIVATE
293-
${common_compile_options} --target=${LIBC_GPU_TARGET_TRIPLE})
294-
if(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU)
295-
target_compile_options(${internal_target_name} PRIVATE
296-
"SHELL:-Xclang -mcode-object-version=none"
297-
-mcpu=${LIBC_GPU_TARGET_ARCHITECTURE} -flto)
298-
elseif(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
299-
get_nvptx_compile_options(nvptx_options ${LIBC_GPU_TARGET_ARCHITECTURE})
300-
target_compile_options(${internal_target_name} PRIVATE ${nvptx_options})
301-
endif()
302-
target_include_directories(${internal_target_name} SYSTEM PRIVATE ${LIBC_INCLUDE_DIR})
303-
target_include_directories(${internal_target_name} PRIVATE ${LIBC_SOURCE_DIR})
304-
if(full_deps_list)
305-
add_dependencies(${internal_target_name} ${full_deps_list})
306-
endif()
307-
endif()
308316
endfunction()
309317

310318
# Rule which is essentially a wrapper over add_library to compile a set of
@@ -354,24 +362,38 @@ function(create_object_library fq_target_name)
354362
# The GPU build uses a separate internal file.
355363
if(LIBC_TARGET_ARCHITECTURE_IS_GPU AND NOT ${ADD_OBJECT_NO_GPU_BUNDLE})
356364
set(internal_target_name ${fq_target_name}.__internal__)
365+
set(public_packaging_for_internal "")
357366
else()
358367
set(internal_target_name ${fq_target_name})
368+
set(public_packaging_for_internal "-DLIBC_COPT_PUBLIC_PACKAGING")
359369
endif()
360370

361371
_get_common_compile_options(compile_options "${ADD_OBJECT_FLAGS}")
362372
list(APPEND compile_options ${ADD_OBJECT_COMPILE_OPTIONS})
363373

364374
# GPU builds require special handling for the objects because we want to
365375
# export several different targets at once, e.g. for both Nvidia and AMD.
366-
if(LIBC_TARGET_ARCHITECTURE_IS_GPU AND NOT ${ADD_OBJECT_NO_GPU_BUNDLE})
367-
_build_gpu_objects(
368-
${fq_target_name}
376+
if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
377+
if(NOT ${ADD_OBJECT_NO_GPU_BUNDLE})
378+
_build_gpu_object_bundle(
379+
${fq_target_name}
380+
SRCS ${ADD_OBJECT_SRCS}
381+
HDRS ${ADD_OBJECT_HDRS}
382+
CXX_STANDARD ${ADD_OBJECT_CXX_STANDARD}
383+
COMPILE_OPTIONS ${compile_options} "-DLIBC_COPT_PUBLIC_PACKAGING"
384+
DEPENDS ${fq_deps_list}
385+
)
386+
endif()
387+
# When the target for GPU is not bundled, internal_target_name is the same
388+
# as fq_targetname
389+
_build_gpu_object_for_single_arch(
369390
${internal_target_name}
391+
${LIBC_GPU_TARGET_ARCHITECTURE}
370392
SRCS ${ADD_OBJECT_SRCS}
371393
HDRS ${ADD_OBJECT_HDRS}
372-
DEPENDS ${fq_deps_list}
373394
CXX_STANDARD ${ADD_OBJECT_CXX_STANDARD}
374-
COMPILE_OPTIONS ${compile_options}
395+
COMPILE_OPTIONS ${compile_options} ${public_packaging_for_internal}
396+
DEPENDS ${fq_deps_list}
375397
)
376398
else()
377399
add_library(
@@ -567,9 +589,18 @@ function(create_entrypoint_object fq_target_name)
567589
# GPU builds require special handling for the objects because we want to
568590
# export several different targets at once, e.g. for both Nvidia and AMD.
569591
if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
570-
_build_gpu_objects(
592+
_build_gpu_object_bundle(
571593
${fq_target_name}
594+
SRCS ${ADD_ENTRYPOINT_OBJ_SRCS}
595+
HDRS ${ADD_ENTRYPOINT_OBJ_HDRS}
596+
COMPILE_OPTIONS ${common_compile_options} "-DLIBC_COPT_PUBLIC_PACKAGING"
597+
CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD}
598+
DEPENDS ${full_deps_list}
599+
FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}"
600+
)
601+
_build_gpu_object_for_single_arch(
572602
${internal_target_name}
603+
${LIBC_GPU_TARGET_ARCHITECTURE}
573604
SRCS ${ADD_ENTRYPOINT_OBJ_SRCS}
574605
HDRS ${ADD_ENTRYPOINT_OBJ_HDRS}
575606
COMPILE_OPTIONS ${common_compile_options}

libc/cmake/modules/prepare_libc_gpu_build.cmake

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ set(all_gpu_architectures
1515
"${all_amdgpu_architectures};${all_nvptx_architectures}")
1616
set(LIBC_GPU_ARCHITECTURES "all" CACHE STRING
1717
"List of GPU architectures to build the libc for.")
18+
set(AMDGPU_TARGET_TRIPLE "amdgcn-amd-amdhsa")
19+
set(NVPTX_TARGET_TRIPLE "nvptx64-nvidia-cuda")
1820

1921
# Ensure the compiler is a valid clang when building the GPU target.
2022
set(req_ver "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
@@ -96,18 +98,25 @@ elseif(detected_gpu_architectures)
9698
message(STATUS "Using GPU architecture detected on the system for testing: "
9799
"'${gpu_test_architecture}'")
98100
else()
99-
message(STATUS "No GPU architecture set for testing. GPU tests will not be "
100-
"availibe. Set 'LIBC_GPU_TEST_ARCHITECTURE' to override.")
101-
return()
101+
list(LENGTH LIBC_GPU_ARCHITECTURES n_gpu_archs)
102+
if (${n_gpu_archs} EQUAL 1)
103+
set(gpu_test_architecture ${LIBC_GPU_ARCHITECTURES})
104+
message(STATUS "Using user-specified GPU architecture for testing: "
105+
"'${gpu_test_architecture}'")
106+
else()
107+
message(STATUS "No GPU architecture set for testing. GPU tests will not be "
108+
"availibe. Set 'LIBC_GPU_TEST_ARCHITECTURE' to override.")
109+
return()
110+
endif()
102111
endif()
103112

104113
if("${gpu_test_architecture}" IN_LIST all_amdgpu_architectures)
105114
set(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU TRUE)
106-
set(LIBC_GPU_TARGET_TRIPLE "amdgcn-amd-amdhsa")
115+
set(LIBC_GPU_TARGET_TRIPLE ${AMDGPU_TARGET_TRIPLE})
107116
set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
108117
elseif("${gpu_test_architecture}" IN_LIST all_nvptx_architectures)
109118
set(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX TRUE)
110-
set(LIBC_GPU_TARGET_TRIPLE "nvptx64-nvidia-cuda")
119+
set(LIBC_GPU_TARGET_TRIPLE ${NVPTX_TARGET_TRIPLE})
111120
set(LIBC_GPU_TARGET_ARCHITECTURE "${gpu_test_architecture}")
112121
else()
113122
message(FATAL_ERROR "Unknown GPU architecture '${gpu_test_architecture}'")

libc/startup/gpu/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ function(add_startup_object name)
1717
add_object_library(
1818
${name}
1919
SRCS ${ADD_STARTUP_OBJECT_SRC}
20-
DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS}
2120
COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS}
21+
${ADD_STARTUP_OBJECT_UNPARSED_ARGUMENTS}
22+
DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS}
2223
)
2324
set_target_properties(
2425
${fq_target_name}

libc/startup/gpu/amdgpu/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_startup_object(
22
crt1
3+
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
34
SRC
45
start.cpp
56
DEPENDS
@@ -10,12 +11,7 @@ add_startup_object(
1011
COMPILE_OPTIONS
1112
-ffreestanding # To avoid compiler warnings about calling the main function.
1213
-fno-builtin
13-
-nogpulib # Do not include any GPU vendor libraries.
14-
-mcpu=${LIBC_GPU_TARGET_ARCHITECTURE}
15-
-emit-llvm # AMDGPU's intermediate object file format is bitcode.
1614
-mcode-object-version=${LIBC_GPU_CODE_OBJECT_VERSION} # Manually set the ABI.
17-
--target=${LIBC_GPU_TARGET_TRIPLE}
18-
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
1915
)
2016
get_fq_target_name(crt1 fq_name)
2117

libc/startup/gpu/nvptx/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
get_nvptx_compile_options(nvptx_options ${LIBC_GPU_TARGET_ARCHITECTURE})
21
add_startup_object(
32
crt1
3+
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
44
SRC
55
start.cpp
66
DEPENDS
@@ -11,10 +11,6 @@ add_startup_object(
1111
COMPILE_OPTIONS
1212
-ffreestanding # To avoid compiler warnings about calling the main function.
1313
-fno-builtin
14-
-nogpulib # Do not include any GPU vendor libraries.
15-
--target=${LIBC_GPU_TARGET_TRIPLE}
16-
${nvptx_options}
17-
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
1814
)
1915
get_fq_target_name(crt1 fq_name)
2016

libc/test/IntegrationTest/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ endif()
1515

1616
add_object_library(
1717
test
18+
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
1819
SRCS
1920
test.cpp
2021
COMPILE_OPTIONS
@@ -23,5 +24,4 @@ add_object_library(
2324
test.h
2425
DEPENDS
2526
libc.src.__support.OSUtil.osutil
26-
NO_GPU_BUNDLE # Compile this file directly without special GPU handling.
2727
)

libc/test/src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function(add_fp_unittest name)
2121
endif()
2222
if(MATH_UNITTEST_NEED_MPFR)
2323
if(MATH_UNITTEST_HERMETIC_TEST_ONLY)
24-
message(FATAL "Hermetic math test cannot require MPFR.")
24+
message(FATAL_ERROR "Hermetic math test cannot require MPFR.")
2525
endif()
2626
set(test_type UNIT_TEST_ONLY)
2727
list(APPEND MATH_UNITTEST_LINK_LIBRARIES libcMPFRWrapper libc_math_test_utils -lmpfr -lgmp)

0 commit comments

Comments
 (0)