11# Compiles an OpenCL C - or assembles an LL file - to bytecode
22#
33# Arguments:
4- # * TARGET <string>
5- # Custom target to create
64# * TRIPLE <string>
75# Target triple for which to compile the bytecode file.
86# * INPUT <string>
1917function (compile_to_bc)
2018 cmake_parse_arguments (ARG
2119 ""
22- "TARGET; TRIPLE;INPUT;OUTPUT"
20+ "TRIPLE;INPUT;OUTPUT"
2321 "EXTRA_OPTS;DEPENDENCIES"
2422 ${ARGN}
2523 )
@@ -65,12 +63,6 @@ function(compile_to_bc)
6563 ${ARG_DEPENDENCIES}
6664 DEPFILE ${ARG_OUTPUT} .d
6765 )
68- # FIXME: The target is added to ensure the parallel build of source files.
69- # However, this may result in a large number of targets.
70- # Starting with CMake 3.27, DEPENDS_EXPLICIT_ONLY can be used with
71- # add_custom_command to enable parallel build.
72- # Refer to https://gitlab.kitware.com/cmake/cmake/-/issues/17097 for details.
73- add_custom_target ( ${ARG_TARGET} DEPENDS ${ARG_OUTPUT}${TMP_SUFFIX} )
7466
7567 if ( ${FILE_EXT} STREQUAL ".ll" )
7668 add_custom_command (
@@ -132,6 +124,37 @@ function(link_bc)
132124 )
133125endfunction ()
134126
127+ # Create a custom target for each bitcode file, which is the output of a custom
128+ # command. This is required for parallel compilation of the custom commands that
129+ # generate the bitcode files when using the CMake MSVC generator on Windows.
130+ #
131+ # Arguments:
132+ # * compile_tgts
133+ # Output list of compile targets
134+ # * ARCH_SUFFIX <string>
135+ # libclc architecture/triple suffix
136+ # * FILES <string> ...
137+ # List of bitcode files
138+ function (create_compile_targets compile_tgts)
139+ cmake_parse_arguments ( ARG "" "ARCH_SUFFIX" "FILES" ${ARGN} )
140+
141+ if ( NOT ARG_ARCH_SUFFIX OR NOT ARG_FILES )
142+ message ( FATAL_ERROR "Must provide ARCH_SUFFIX, and FILES" )
143+ endif ()
144+
145+ set ( tgts )
146+ foreach ( file IN LISTS ARG_FILES )
147+ cmake_path( GET file STEM stem )
148+ cmake_path( GET file PARENT_PATH parent_path )
149+ cmake_path( GET parent_path STEM parent_path_stem )
150+ set ( tgt compile-${ARG_ARCH_SUFFIX} -${parent_path_stem} -${stem} )
151+ add_custom_target ( ${tgt} DEPENDS ${file} )
152+ list ( APPEND tgts ${tgt} )
153+ endforeach ()
154+
155+ set ( compile_tgts ${tgts} PARENT_SCOPE )
156+ endfunction ()
157+
135158# Decomposes and returns variables based on a libclc triple and architecture
136159# combination. Returns data via one or more optional output variables.
137160#
@@ -275,7 +298,6 @@ function(add_libclc_builtin_set)
275298
276299 set ( bytecode_files )
277300 set ( bytecode_ir_files )
278- set ( compile_tgts )
279301 foreach ( file IN LISTS ARG_GEN_FILES ARG_LIB_FILES )
280302 # We need to take each file and produce an absolute input file, as well
281303 # as a unique architecture-specific output file. We deal with a mix of
@@ -305,17 +327,13 @@ function(add_libclc_builtin_set)
305327
306328 get_filename_component ( file_dir ${file} DIRECTORY )
307329
308- string ( REPLACE "/" "-" replaced ${file} )
309- set ( tgt compile_tgt-${ARG_ARCH_SUFFIX}${replaced} )
310-
311330 set ( file_specific_compile_options )
312331 get_source_file_property ( compile_opts ${file} COMPILE_OPTIONS)
313332 if ( compile_opts )
314333 set ( file_specific_compile_options "${compile_opts} " )
315334 endif ()
316335
317336 compile_to_bc(
318- TARGET ${tgt}
319337 TRIPLE ${ARG_TRIPLE}
320338 INPUT ${input_file}
321339 OUTPUT ${output_file}
@@ -324,7 +342,6 @@ function(add_libclc_builtin_set)
324342 -I${CMAKE_CURRENT_SOURCE_DIR} /${file_dir}
325343 DEPENDENCIES ${input_file_dep}
326344 )
327- list ( APPEND compile_tgts ${tgt} )
328345
329346 # Collect all files originating in LLVM IR separately
330347 get_filename_component ( file_ext ${file} EXT )
@@ -335,19 +352,29 @@ function(add_libclc_builtin_set)
335352 endif ()
336353 endforeach ()
337354
355+ set ( builtins_comp_lib_tgt builtins.comp.${ARG_ARCH_SUFFIX} )
356+ if ( CMAKE_GENERATOR MATCHES "Visual Studio" )
357+ # Don't put commands in one custom target to avoid serialized compilation.
358+ create_compile_targets( compile_tgts
359+ ARCH_SUFFIX ${ARG_ARCH_SUFFIX}
360+ FILES ${bytecode_files}
361+ )
362+ add_custom_target ( ${builtins_comp_lib_tgt} DEPENDS ${bytecode_ir_files} )
363+ add_dependencies ( ${builtins_comp_lib_tgt} ${compile_tgts} )
364+ else ()
365+ add_custom_target ( ${builtins_comp_lib_tgt}
366+ DEPENDS ${bytecode_files} ${bytecode_ir_files}
367+ )
368+ endif ()
369+ set_target_properties ( ${builtins_comp_lib_tgt} PROPERTIES FOLDER "libclc/Device IR/Comp" )
370+
338371 # Prepend all LLVM IR files to the list so they are linked into the final
339372 # bytecode modules first. This helps to suppress unnecessary warnings
340373 # regarding different data layouts while linking. Any LLVM IR files without a
341374 # data layout will (silently) be given the first data layout the linking
342375 # process comes across.
343376 list ( PREPEND bytecode_files ${bytecode_ir_files} )
344377
345- set ( builtins_comp_lib_tgt builtins.comp.${ARG_ARCH_SUFFIX} )
346- add_custom_target ( ${builtins_comp_lib_tgt}
347- DEPENDS ${bytecode_files} ${compile_tgts}
348- )
349- set_target_properties ( ${builtins_comp_lib_tgt} PROPERTIES FOLDER "libclc/Device IR/Comp" )
350-
351378 if ( NOT bytecode_files )
352379 message (FATAL_ERROR "Cannot create an empty builtins library" )
353380 endif ()
0 commit comments