172f9881cSFraser Cormack# Compiles an OpenCL C - or assembles an LL file - to bytecode 272f9881cSFraser Cormack# 372f9881cSFraser Cormack# Arguments: 472f9881cSFraser Cormack# * TRIPLE <string> 572f9881cSFraser Cormack# Target triple for which to compile the bytecode file. 672f9881cSFraser Cormack# * INPUT <string> 772f9881cSFraser Cormack# File to compile/assemble to bytecode 872f9881cSFraser Cormack# * OUTPUT <string> 972f9881cSFraser Cormack# Bytecode file to generate 1072f9881cSFraser Cormack# * EXTRA_OPTS <string> ... 1172f9881cSFraser Cormack# List of compiler options to use. Note that some are added by default. 1272f9881cSFraser Cormack# * DEPENDENCIES <string> ... 1372f9881cSFraser Cormack# List of extra dependencies to inject 1472f9881cSFraser Cormack# 155ee53d41SHarald van Dijk# Depends on the clang, llvm-as, and llvm-link targets for compiling, 165ee53d41SHarald van Dijk# assembling, and linking, respectively. 1772f9881cSFraser Cormackfunction(compile_to_bc) 1872f9881cSFraser Cormack cmake_parse_arguments(ARG 1972f9881cSFraser Cormack "" 2072f9881cSFraser Cormack "TRIPLE;INPUT;OUTPUT" 2172f9881cSFraser Cormack "EXTRA_OPTS;DEPENDENCIES" 2272f9881cSFraser Cormack ${ARGN} 2372f9881cSFraser Cormack ) 2472f9881cSFraser Cormack 2572f9881cSFraser Cormack # If this is an LLVM IR file (identified soley by its file suffix), 2672f9881cSFraser Cormack # pre-process it with clang to a temp file, then assemble that to bytecode. 2772f9881cSFraser Cormack set( TMP_SUFFIX ) 2872f9881cSFraser Cormack get_filename_component( FILE_EXT ${ARG_INPUT} EXT ) 2972f9881cSFraser Cormack if( NOT ${FILE_EXT} STREQUAL ".ll" ) 3072f9881cSFraser Cormack # Pass '-c' when not running the preprocessor 3172f9881cSFraser Cormack set( PP_OPTS -c ) 3272f9881cSFraser Cormack else() 3372f9881cSFraser Cormack set( PP_OPTS -E;-P ) 3472f9881cSFraser Cormack set( TMP_SUFFIX .tmp ) 3572f9881cSFraser Cormack endif() 3672f9881cSFraser Cormack 3772f9881cSFraser Cormack set( TARGET_ARG ) 3872f9881cSFraser Cormack if( ARG_TRIPLE ) 3972f9881cSFraser Cormack set( TARGET_ARG "-target" ${ARG_TRIPLE} ) 4072f9881cSFraser Cormack endif() 4172f9881cSFraser Cormack 42e614e037SFraser Cormack # Ensure the directory we are told to output to exists 43e614e037SFraser Cormack get_filename_component( ARG_OUTPUT_DIR ${ARG_OUTPUT} DIRECTORY ) 44e614e037SFraser Cormack file( MAKE_DIRECTORY ${ARG_OUTPUT_DIR} ) 45e614e037SFraser Cormack 4672f9881cSFraser Cormack add_custom_command( 4772f9881cSFraser Cormack OUTPUT ${ARG_OUTPUT}${TMP_SUFFIX} 485ee53d41SHarald van Dijk COMMAND ${clang_exe} 4972f9881cSFraser Cormack ${TARGET_ARG} 5072f9881cSFraser Cormack ${PP_OPTS} 5172f9881cSFraser Cormack ${ARG_EXTRA_OPTS} 5272f9881cSFraser Cormack -MD -MF ${ARG_OUTPUT}.d -MT ${ARG_OUTPUT}${TMP_SUFFIX} 5372f9881cSFraser Cormack # LLVM 13 enables standard includes by default - we don't want 5472f9881cSFraser Cormack # those when pre-processing IR. We disable it unconditionally. 5572f9881cSFraser Cormack $<$<VERSION_GREATER_EQUAL:${LLVM_PACKAGE_VERSION},13.0.0>:-cl-no-stdinc> 5672f9881cSFraser Cormack -emit-llvm 5772f9881cSFraser Cormack -o ${ARG_OUTPUT}${TMP_SUFFIX} 5872f9881cSFraser Cormack -x cl 5972f9881cSFraser Cormack ${ARG_INPUT} 6072f9881cSFraser Cormack DEPENDS 615ee53d41SHarald van Dijk ${clang_target} 6272f9881cSFraser Cormack ${ARG_INPUT} 6372f9881cSFraser Cormack ${ARG_DEPENDENCIES} 6472f9881cSFraser Cormack DEPFILE ${ARG_OUTPUT}.d 6572f9881cSFraser Cormack ) 6672f9881cSFraser Cormack 6772f9881cSFraser Cormack if( ${FILE_EXT} STREQUAL ".ll" ) 6872f9881cSFraser Cormack add_custom_command( 6972f9881cSFraser Cormack OUTPUT ${ARG_OUTPUT} 705ee53d41SHarald van Dijk COMMAND ${llvm-as_exe} -o ${ARG_OUTPUT} ${ARG_OUTPUT}${TMP_SUFFIX} 715ee53d41SHarald van Dijk DEPENDS ${llvm-as_target} ${ARG_OUTPUT}${TMP_SUFFIX} 7272f9881cSFraser Cormack ) 7372f9881cSFraser Cormack endif() 7472f9881cSFraser Cormackendfunction() 7572f9881cSFraser Cormack 7672f9881cSFraser Cormack# Links together one or more bytecode files 7772f9881cSFraser Cormack# 7872f9881cSFraser Cormack# Arguments: 79b2bdd8bdSFraser Cormack# * INTERNALIZE 80b2bdd8bdSFraser Cormack# Set if -internalize flag should be passed when linking 8172f9881cSFraser Cormack# * TARGET <string> 8272f9881cSFraser Cormack# Custom target to create 8372f9881cSFraser Cormack# * INPUT <string> ... 8472f9881cSFraser Cormack# List of bytecode files to link together 8564796044STim Creech# * DEPENDENCIES <string> ... 8664796044STim Creech# List of extra dependencies to inject 8772f9881cSFraser Cormackfunction(link_bc) 8872f9881cSFraser Cormack cmake_parse_arguments(ARG 89b2bdd8bdSFraser Cormack "INTERNALIZE" 9072f9881cSFraser Cormack "TARGET" 9164796044STim Creech "INPUTS;DEPENDENCIES" 9272f9881cSFraser Cormack ${ARGN} 9372f9881cSFraser Cormack ) 9472f9881cSFraser Cormack 95effb2f19SFraser Cormack set( LINK_INPUT_ARG ${ARG_INPUTS} ) 96effb2f19SFraser Cormack if( WIN32 OR CYGWIN ) 97effb2f19SFraser Cormack # Create a response file in case the number of inputs exceeds command-line 98effb2f19SFraser Cormack # character limits on certain platforms. 99effb2f19SFraser Cormack file( TO_CMAKE_PATH ${LIBCLC_ARCH_OBJFILE_DIR}/${ARG_TARGET}.rsp RSP_FILE ) 100effb2f19SFraser Cormack # Turn it into a space-separate list of input files 101effb2f19SFraser Cormack list( JOIN ARG_INPUTS " " RSP_INPUT ) 102b2bdd8bdSFraser Cormack file( GENERATE OUTPUT ${RSP_FILE} CONTENT ${RSP_INPUT} ) 103effb2f19SFraser Cormack # Ensure that if this file is removed, we re-run CMake 104effb2f19SFraser Cormack set_property( DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS 105effb2f19SFraser Cormack ${RSP_FILE} 106effb2f19SFraser Cormack ) 107effb2f19SFraser Cormack set( LINK_INPUT_ARG "@${RSP_FILE}" ) 108effb2f19SFraser Cormack endif() 109effb2f19SFraser Cormack 11072f9881cSFraser Cormack add_custom_command( 11172f9881cSFraser Cormack OUTPUT ${ARG_TARGET}.bc 112b2bdd8bdSFraser Cormack COMMAND ${llvm-link_exe} $<$<BOOL:${ARG_INTERNALIZE}>:--internalize> -o ${ARG_TARGET}.bc ${LINK_INPUT_ARG} 1135ee53d41SHarald van Dijk DEPENDS ${llvm-link_target} ${ARG_DEPENDENCIES} ${ARG_INPUTS} ${RSP_FILE} 11472f9881cSFraser Cormack ) 11572f9881cSFraser Cormack 11672f9881cSFraser Cormack add_custom_target( ${ARG_TARGET} ALL DEPENDS ${ARG_TARGET}.bc ) 1176838c7afSMichael Kruse set_target_properties( ${ARG_TARGET} PROPERTIES 1189f3728d1SFraser Cormack TARGET_FILE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.bc 1196838c7afSMichael Kruse FOLDER "libclc/Device IR/Linking" 1206838c7afSMichael Kruse ) 12172f9881cSFraser Cormackendfunction() 12272f9881cSFraser Cormack 12372f9881cSFraser Cormack# Decomposes and returns variables based on a libclc triple and architecture 12472f9881cSFraser Cormack# combination. Returns data via one or more optional output variables. 12572f9881cSFraser Cormack# 12672f9881cSFraser Cormack# Arguments: 12772f9881cSFraser Cormack# * TRIPLE <string> 12872f9881cSFraser Cormack# libclc target triple to query 12972f9881cSFraser Cormack# * DEVICE <string> 13072f9881cSFraser Cormack# libclc device to query 13172f9881cSFraser Cormack# 13272f9881cSFraser Cormack# Optional Arguments: 13372f9881cSFraser Cormack# * CPU <var> 13472f9881cSFraser Cormack# Variable name to be set to the target CPU 13572f9881cSFraser Cormack# * ARCH_SUFFIX <var> 13672f9881cSFraser Cormack# Variable name to be set to the triple/architecture suffix 13772f9881cSFraser Cormack# * CLANG_TRIPLE <var> 13872f9881cSFraser Cormack# Variable name to be set to the normalized clang triple 13972f9881cSFraser Cormackfunction(get_libclc_device_info) 14072f9881cSFraser Cormack cmake_parse_arguments(ARG 14172f9881cSFraser Cormack "" 14272f9881cSFraser Cormack "TRIPLE;DEVICE;CPU;ARCH_SUFFIX;CLANG_TRIPLE" 14372f9881cSFraser Cormack "" 14472f9881cSFraser Cormack ${ARGN} 14572f9881cSFraser Cormack ) 14672f9881cSFraser Cormack 14772f9881cSFraser Cormack if( NOT ARG_TRIPLE OR NOT ARG_DEVICE ) 14872f9881cSFraser Cormack message( FATAL_ERROR "Must provide both TRIPLE and DEVICE" ) 14972f9881cSFraser Cormack endif() 15072f9881cSFraser Cormack 15172f9881cSFraser Cormack string( REPLACE "-" ";" TRIPLE ${ARG_TRIPLE} ) 15272f9881cSFraser Cormack list( GET TRIPLE 0 ARCH ) 15372f9881cSFraser Cormack 15472f9881cSFraser Cormack # Some targets don't have a specific device architecture to target 15572f9881cSFraser Cormack if( ARG_DEVICE STREQUAL none OR ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 ) 15672f9881cSFraser Cormack set( cpu ) 15772f9881cSFraser Cormack set( arch_suffix "${ARG_TRIPLE}" ) 15872f9881cSFraser Cormack else() 15972f9881cSFraser Cormack set( cpu "${ARG_DEVICE}" ) 16072f9881cSFraser Cormack set( arch_suffix "${ARG_DEVICE}-${ARG_TRIPLE}" ) 16172f9881cSFraser Cormack endif() 16272f9881cSFraser Cormack 16372f9881cSFraser Cormack if( ARG_CPU ) 16472f9881cSFraser Cormack set( ${ARG_CPU} ${cpu} PARENT_SCOPE ) 16572f9881cSFraser Cormack endif() 16672f9881cSFraser Cormack 16772f9881cSFraser Cormack if( ARG_ARCH_SUFFIX ) 16872f9881cSFraser Cormack set( ${ARG_ARCH_SUFFIX} ${arch_suffix} PARENT_SCOPE ) 16972f9881cSFraser Cormack endif() 17072f9881cSFraser Cormack 17172f9881cSFraser Cormack # Some libclc targets are not real clang triples: return their canonical 17272f9881cSFraser Cormack # triples. 17372f9881cSFraser Cormack if( ARCH STREQUAL spirv OR ARCH STREQUAL clspv ) 17472f9881cSFraser Cormack set( ARG_TRIPLE "spir--" ) 17572f9881cSFraser Cormack elseif( ARCH STREQUAL spirv64 OR ARCH STREQUAL clspv64 ) 17672f9881cSFraser Cormack set( ARG_TRIPLE "spir64--" ) 17772f9881cSFraser Cormack endif() 17872f9881cSFraser Cormack 17972f9881cSFraser Cormack if( ARG_CLANG_TRIPLE ) 18072f9881cSFraser Cormack set( ${ARG_CLANG_TRIPLE} ${ARG_TRIPLE} PARENT_SCOPE ) 18172f9881cSFraser Cormack endif() 18272f9881cSFraser Cormackendfunction() 183183b38ebSFraser Cormack 184183b38ebSFraser Cormack# Compiles a list of library source files (provided by LIB_FILES/GEN_FILES) and 185183b38ebSFraser Cormack# compiles them to LLVM bytecode (or SPIR-V), links them together and optimizes 186183b38ebSFraser Cormack# them. 187183b38ebSFraser Cormack# 188183b38ebSFraser Cormack# For bytecode libraries, a list of ALIASES may optionally be provided to 189183b38ebSFraser Cormack# produce additional symlinks. 190183b38ebSFraser Cormack# 191183b38ebSFraser Cormack# Arguments: 192183b38ebSFraser Cormack# * ARCH <string> 193183b38ebSFraser Cormack# libclc architecture being built 194183b38ebSFraser Cormack# * ARCH_SUFFIX <string> 195183b38ebSFraser Cormack# libclc architecture/triple suffix 196183b38ebSFraser Cormack# * TRIPLE <string> 197183b38ebSFraser Cormack# Triple used to compile 198183b38ebSFraser Cormack# 199183b38ebSFraser Cormack# Optional Arguments: 200b2bdd8bdSFraser Cormack# * CLC_INTERNAL 201b2bdd8bdSFraser Cormack# Pass if compiling the internal CLC builtin libraries, which are not 202b2bdd8bdSFraser Cormack# optimized and do not have aliases created. 203183b38ebSFraser Cormack# * LIB_FILES <string> ... 204183b38ebSFraser Cormack# List of files that should be built for this library 205183b38ebSFraser Cormack# * GEN_FILES <string> ... 206183b38ebSFraser Cormack# List of generated files (in build dir) that should be built for this library 207183b38ebSFraser Cormack# * COMPILE_FLAGS <string> ... 208183b38ebSFraser Cormack# Compilation options (for clang) 209183b38ebSFraser Cormack# * OPT_FLAGS <string> ... 210183b38ebSFraser Cormack# Optimization options (for opt) 211183b38ebSFraser Cormack# * ALIASES <string> ... 212183b38ebSFraser Cormack# List of aliases 213b2bdd8bdSFraser Cormack# * INTERNAL_LINK_DEPENDENCIES <string> ... 214b2bdd8bdSFraser Cormack# A list of extra bytecode files to link into the builtin library. Symbols 215b2bdd8bdSFraser Cormack# from these link dependencies will be internalized during linking. 216183b38ebSFraser Cormackfunction(add_libclc_builtin_set) 217183b38ebSFraser Cormack cmake_parse_arguments(ARG 218b2bdd8bdSFraser Cormack "CLC_INTERNAL" 219183b38ebSFraser Cormack "ARCH;TRIPLE;ARCH_SUFFIX" 220b2bdd8bdSFraser Cormack "LIB_FILES;GEN_FILES;COMPILE_FLAGS;OPT_FLAGS;ALIASES;INTERNAL_LINK_DEPENDENCIES" 221183b38ebSFraser Cormack ${ARGN} 222183b38ebSFraser Cormack ) 223183b38ebSFraser Cormack 224183b38ebSFraser Cormack if( NOT ARG_ARCH OR NOT ARG_ARCH_SUFFIX OR NOT ARG_TRIPLE ) 225183b38ebSFraser Cormack message( FATAL_ERROR "Must provide ARCH, ARCH_SUFFIX, and TRIPLE" ) 226183b38ebSFraser Cormack endif() 227183b38ebSFraser Cormack 228183b38ebSFraser Cormack set( bytecode_files "" ) 229183b38ebSFraser Cormack foreach( file IN LISTS ARG_GEN_FILES ARG_LIB_FILES ) 230183b38ebSFraser Cormack # We need to take each file and produce an absolute input file, as well 231183b38ebSFraser Cormack # as a unique architecture-specific output file. We deal with a mix of 232183b38ebSFraser Cormack # different input files, which makes this trickier. 233183b38ebSFraser Cormack if( ${file} IN_LIST ARG_GEN_FILES ) 234183b38ebSFraser Cormack # Generated files are given just as file names, which we must make 235183b38ebSFraser Cormack # absolute to the binary directory. 236183b38ebSFraser Cormack set( input_file ${CMAKE_CURRENT_BINARY_DIR}/${file} ) 237183b38ebSFraser Cormack set( output_file "${LIBCLC_ARCH_OBJFILE_DIR}/${file}.bc" ) 238183b38ebSFraser Cormack else() 239183b38ebSFraser Cormack # Other files are originally relative to each SOURCE file, which are 240183b38ebSFraser Cormack # then make relative to the libclc root directory. We must normalize 241183b38ebSFraser Cormack # the path (e.g., ironing out any ".."), then make it relative to the 242183b38ebSFraser Cormack # root directory again, and use that relative path component for the 243183b38ebSFraser Cormack # binary path. 244183b38ebSFraser Cormack get_filename_component( abs_path ${file} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) 245183b38ebSFraser Cormack file( RELATIVE_PATH root_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${abs_path} ) 246183b38ebSFraser Cormack set( input_file ${CMAKE_CURRENT_SOURCE_DIR}/${file} ) 247183b38ebSFraser Cormack set( output_file "${LIBCLC_ARCH_OBJFILE_DIR}/${root_rel_path}.bc" ) 248183b38ebSFraser Cormack endif() 249183b38ebSFraser Cormack 250183b38ebSFraser Cormack get_filename_component( file_dir ${file} DIRECTORY ) 251183b38ebSFraser Cormack 252183b38ebSFraser Cormack compile_to_bc( 253183b38ebSFraser Cormack TRIPLE ${ARG_TRIPLE} 254183b38ebSFraser Cormack INPUT ${input_file} 255183b38ebSFraser Cormack OUTPUT ${output_file} 256183b38ebSFraser Cormack EXTRA_OPTS -fno-builtin -nostdlib 257183b38ebSFraser Cormack "${ARG_COMPILE_FLAGS}" -I${CMAKE_CURRENT_SOURCE_DIR}/${file_dir} 258183b38ebSFraser Cormack DEPENDENCIES generate_convert.cl clspv-generate_convert.cl 259183b38ebSFraser Cormack ) 260183b38ebSFraser Cormack list( APPEND bytecode_files ${output_file} ) 261183b38ebSFraser Cormack endforeach() 262183b38ebSFraser Cormack 263183b38ebSFraser Cormack set( builtins_comp_lib_tgt builtins.comp.${ARG_ARCH_SUFFIX} ) 264183b38ebSFraser Cormack add_custom_target( ${builtins_comp_lib_tgt} 265183b38ebSFraser Cormack DEPENDS ${bytecode_files} 266183b38ebSFraser Cormack ) 267183b38ebSFraser Cormack set_target_properties( ${builtins_comp_lib_tgt} PROPERTIES FOLDER "libclc/Device IR/Comp" ) 268183b38ebSFraser Cormack 269b2bdd8bdSFraser Cormack if( NOT bytecode_files ) 270b2bdd8bdSFraser Cormack message(FATAL_ERROR "Cannot create an empty builtins library") 271b2bdd8bdSFraser Cormack endif() 272b2bdd8bdSFraser Cormack 273183b38ebSFraser Cormack set( builtins_link_lib_tgt builtins.link.${ARG_ARCH_SUFFIX} ) 274b2bdd8bdSFraser Cormack 275b2bdd8bdSFraser Cormack if( NOT ARG_INTERNAL_LINK_DEPENDENCIES ) 276183b38ebSFraser Cormack link_bc( 277183b38ebSFraser Cormack TARGET ${builtins_link_lib_tgt} 278183b38ebSFraser Cormack INPUTS ${bytecode_files} 279183b38ebSFraser Cormack DEPENDENCIES ${builtins_comp_lib_tgt} 280183b38ebSFraser Cormack ) 281b2bdd8bdSFraser Cormack else() 282b2bdd8bdSFraser Cormack # If we have libraries to link while internalizing their symbols, we need 283b2bdd8bdSFraser Cormack # two separate link steps; the --internalize flag applies to all link 284b2bdd8bdSFraser Cormack # inputs but the first. 285b2bdd8bdSFraser Cormack set( builtins_link_lib_tmp_tgt builtins.link.pre-deps.${ARG_ARCH_SUFFIX} ) 286b2bdd8bdSFraser Cormack link_bc( 287b2bdd8bdSFraser Cormack TARGET ${builtins_link_lib_tmp_tgt} 288b2bdd8bdSFraser Cormack INPUTS ${bytecode_files} 289b2bdd8bdSFraser Cormack DEPENDENCIES ${builtins_comp_lib_tgt} 290b2bdd8bdSFraser Cormack ) 291b2bdd8bdSFraser Cormack link_bc( 292b2bdd8bdSFraser Cormack INTERNALIZE 293b2bdd8bdSFraser Cormack TARGET ${builtins_link_lib_tgt} 294b2bdd8bdSFraser Cormack INPUTS $<TARGET_PROPERTY:${builtins_link_lib_tmp_tgt},TARGET_FILE> 295b2bdd8bdSFraser Cormack ${ARG_INTERNAL_LINK_DEPENDENCIES} 296b2bdd8bdSFraser Cormack DEPENDENCIES ${builtins_link_lib_tmp_tgt} 297b2bdd8bdSFraser Cormack ) 298b2bdd8bdSFraser Cormack endif() 299b2bdd8bdSFraser Cormack 300b2bdd8bdSFraser Cormack # For the CLC internal builtins, exit here - we only optimize the targets' 301b2bdd8bdSFraser Cormack # entry points once we've linked the CLC buitins into them 302b2bdd8bdSFraser Cormack if( ARG_CLC_INTERNAL ) 303b2bdd8bdSFraser Cormack return() 304b2bdd8bdSFraser Cormack endif() 305183b38ebSFraser Cormack 306183b38ebSFraser Cormack set( builtins_link_lib $<TARGET_PROPERTY:${builtins_link_lib_tgt},TARGET_FILE> ) 307183b38ebSFraser Cormack 308183b38ebSFraser Cormack if( ARG_ARCH STREQUAL spirv OR ARG_ARCH STREQUAL spirv64 ) 309183b38ebSFraser Cormack set( spv_suffix ${ARG_ARCH_SUFFIX}.spv ) 310183b38ebSFraser Cormack add_custom_command( OUTPUT ${spv_suffix} 311183b38ebSFraser Cormack COMMAND ${llvm-spirv_exe} ${spvflags} -o ${spv_suffix} ${builtins_link_lib} 312183b38ebSFraser Cormack DEPENDS ${llvm-spirv_target} ${builtins_link_lib} ${builtins_link_lib_tgt} 313183b38ebSFraser Cormack ) 314183b38ebSFraser Cormack add_custom_target( "prepare-${spv_suffix}" ALL DEPENDS "${spv_suffix}" ) 315183b38ebSFraser Cormack set_target_properties( "prepare-${spv_suffix}" PROPERTIES FOLDER "libclc/Device IR/Prepare" ) 316183b38ebSFraser Cormack install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${spv_suffix} 317183b38ebSFraser Cormack DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) 318183b38ebSFraser Cormack 319183b38ebSFraser Cormack return() 320183b38ebSFraser Cormack endif() 321183b38ebSFraser Cormack 322183b38ebSFraser Cormack set( builtins_opt_lib_tgt builtins.opt.${ARG_ARCH_SUFFIX} ) 323183b38ebSFraser Cormack 324183b38ebSFraser Cormack # Add opt target 325183b38ebSFraser Cormack add_custom_command( OUTPUT ${builtins_opt_lib_tgt}.bc 326183b38ebSFraser Cormack COMMAND ${opt_exe} ${ARG_OPT_FLAGS} -o ${builtins_opt_lib_tgt}.bc 327183b38ebSFraser Cormack ${builtins_link_lib} 328183b38ebSFraser Cormack DEPENDS ${opt_target} ${builtins_link_lib} ${builtins_link_lib_tgt} 329183b38ebSFraser Cormack ) 330183b38ebSFraser Cormack add_custom_target( ${builtins_opt_lib_tgt} 331183b38ebSFraser Cormack ALL DEPENDS ${builtins_opt_lib_tgt}.bc 332183b38ebSFraser Cormack ) 333183b38ebSFraser Cormack set_target_properties( ${builtins_opt_lib_tgt} PROPERTIES 334183b38ebSFraser Cormack TARGET_FILE ${CMAKE_CURRENT_BINARY_DIR}/${builtins_opt_lib_tgt}.bc 335183b38ebSFraser Cormack FOLDER "libclc/Device IR/Opt" 336183b38ebSFraser Cormack ) 337183b38ebSFraser Cormack 338183b38ebSFraser Cormack set( builtins_opt_lib $<TARGET_PROPERTY:${builtins_opt_lib_tgt},TARGET_FILE> ) 339183b38ebSFraser Cormack 340183b38ebSFraser Cormack # Add prepare target 341183b38ebSFraser Cormack set( obj_suffix ${ARG_ARCH_SUFFIX}.bc ) 342183b38ebSFraser Cormack add_custom_command( OUTPUT ${obj_suffix} 343183b38ebSFraser Cormack COMMAND ${prepare_builtins_exe} -o ${obj_suffix} ${builtins_opt_lib} 344183b38ebSFraser Cormack DEPENDS ${builtins_opt_lib} ${builtins_opt_lib_tgt} ${prepare_builtins_target} ) 345183b38ebSFraser Cormack add_custom_target( prepare-${obj_suffix} ALL DEPENDS ${obj_suffix} ) 346183b38ebSFraser Cormack set_target_properties( "prepare-${obj_suffix}" PROPERTIES FOLDER "libclc/Device IR/Prepare" ) 347183b38ebSFraser Cormack 348183b38ebSFraser Cormack # nvptx-- targets don't include workitem builtins 349183b38ebSFraser Cormack if( NOT ARG_TRIPLE MATCHES ".*ptx.*--$" ) 350183b38ebSFraser Cormack add_test( NAME external-calls-${obj_suffix} 351183b38ebSFraser Cormack COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} ${LLVM_TOOLS_BINARY_DIR} 352183b38ebSFraser Cormack WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) 353183b38ebSFraser Cormack endif() 354183b38ebSFraser Cormack 355183b38ebSFraser Cormack install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) 356183b38ebSFraser Cormack foreach( a ${ARG_ALIASES} ) 357183b38ebSFraser Cormack set( alias_suffix "${a}-${ARG_TRIPLE}.bc" ) 358*76befc86SFraser Cormack add_custom_command( 359*76befc86SFraser Cormack OUTPUT ${alias_suffix} 360183b38ebSFraser Cormack COMMAND ${CMAKE_COMMAND} -E create_symlink ${obj_suffix} ${alias_suffix} 361183b38ebSFraser Cormack DEPENDS prepare-${obj_suffix} ) 362*76befc86SFraser Cormack add_custom_target( alias-${alias_suffix} ALL DEPENDS ${alias_suffix} ) 363*76befc86SFraser Cormack set_target_properties( alias-${alias_suffix} PROPERTIES FOLDER "libclc/Device IR/Aliases" ) 364*76befc86SFraser Cormack install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${alias_suffix} 365*76befc86SFraser Cormack DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) 366183b38ebSFraser Cormack endforeach( a ) 367183b38ebSFraser Cormackendfunction(add_libclc_builtin_set) 368183b38ebSFraser Cormack 369183b38ebSFraser Cormack# Produces a list of libclc source files by walking over SOURCES files in a 370183b38ebSFraser Cormack# given directory. Outputs the list of files in LIB_FILE_LIST. 371183b38ebSFraser Cormack# 372183b38ebSFraser Cormack# LIB_FILE_LIST may be pre-populated and is appended to. 373183b38ebSFraser Cormack# 374183b38ebSFraser Cormack# Arguments: 375b2bdd8bdSFraser Cormack# * CLC_INTERNAL 376b2bdd8bdSFraser Cormack# Pass if compiling the internal CLC builtin libraries, which have a 377b2bdd8bdSFraser Cormack# different directory structure. 378183b38ebSFraser Cormack# * LIB_ROOT_DIR <string> 379183b38ebSFraser Cormack# Root directory containing target's lib files, relative to libclc root 380183b38ebSFraser Cormack# directory. If not provided, is set to '.'. 381183b38ebSFraser Cormack# * DIRS <string> ... 382183b38ebSFraser Cormack# List of directories under LIB_ROOT_DIR to walk over searching for SOURCES 383183b38ebSFraser Cormack# files 384183b38ebSFraser Cormackfunction(libclc_configure_lib_source LIB_FILE_LIST) 385183b38ebSFraser Cormack cmake_parse_arguments(ARG 386b2bdd8bdSFraser Cormack "CLC_INTERNAL" 387183b38ebSFraser Cormack "LIB_ROOT_DIR" 388183b38ebSFraser Cormack "DIRS" 389183b38ebSFraser Cormack ${ARGN} 390183b38ebSFraser Cormack ) 391183b38ebSFraser Cormack 392183b38ebSFraser Cormack if( NOT ARG_LIB_ROOT_DIR ) 393183b38ebSFraser Cormack set(ARG_LIB_ROOT_DIR ".") 394183b38ebSFraser Cormack endif() 395183b38ebSFraser Cormack 396183b38ebSFraser Cormack # Enumerate SOURCES* files 397183b38ebSFraser Cormack set( source_list ) 398183b38ebSFraser Cormack foreach( l ${ARG_DIRS} ) 399183b38ebSFraser Cormack foreach( s "SOURCES" "SOURCES_${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}" ) 400b2bdd8bdSFraser Cormack if( ARG_CLC_INTERNAL ) 401b2bdd8bdSFraser Cormack file( TO_CMAKE_PATH ${ARG_LIB_ROOT_DIR}/lib/${l}/${s} file_loc ) 402b2bdd8bdSFraser Cormack else() 403183b38ebSFraser Cormack file( TO_CMAKE_PATH ${ARG_LIB_ROOT_DIR}/${l}/lib/${s} file_loc ) 404b2bdd8bdSFraser Cormack endif() 405183b38ebSFraser Cormack file( TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file_loc} loc ) 406183b38ebSFraser Cormack # Prepend the location to give higher priority to 407183b38ebSFraser Cormack # specialized implementation 408183b38ebSFraser Cormack if( EXISTS ${loc} ) 409183b38ebSFraser Cormack set( source_list ${file_loc} ${source_list} ) 410183b38ebSFraser Cormack endif() 411183b38ebSFraser Cormack endforeach() 412183b38ebSFraser Cormack endforeach() 413183b38ebSFraser Cormack 414183b38ebSFraser Cormack ## Add the generated convert files here to prevent adding the ones listed in 415183b38ebSFraser Cormack ## SOURCES 416183b38ebSFraser Cormack set( rel_files ${${LIB_FILE_LIST}} ) # Source directory input files, relative to the root dir 417183b38ebSFraser Cormack set( objects ${${LIB_FILE_LIST}} ) # A "set" of already-added input files 418183b38ebSFraser Cormack 419183b38ebSFraser Cormack foreach( l ${source_list} ) 420183b38ebSFraser Cormack file( READ ${l} file_list ) 421183b38ebSFraser Cormack string( REPLACE "\n" ";" file_list ${file_list} ) 422183b38ebSFraser Cormack get_filename_component( dir ${l} DIRECTORY ) 423183b38ebSFraser Cormack foreach( f ${file_list} ) 424183b38ebSFraser Cormack # Only add each file once, so that targets can 'specialize' builtins 425183b38ebSFraser Cormack if( NOT ${f} IN_LIST objects ) 426183b38ebSFraser Cormack list( APPEND objects ${f} ) 427183b38ebSFraser Cormack list( APPEND rel_files ${dir}/${f} ) 428183b38ebSFraser Cormack endif() 429183b38ebSFraser Cormack endforeach() 430183b38ebSFraser Cormack endforeach() 431183b38ebSFraser Cormack 432183b38ebSFraser Cormack set( ${LIB_FILE_LIST} ${rel_files} PARENT_SCOPE ) 433183b38ebSFraser Cormackendfunction(libclc_configure_lib_source LIB_FILE_LIST) 434