The previous build system was adding custom "OpenCL" and "LLVM IR" languages in CMake to build the builtin libraries. This was making it harder to build in-tree because the tool binaries needed to be present at configure time. This commit refactors the build system to use custom commands to build the bytecode files one by one, and link them all together into the final bytecode library. It also enables in-tree builds by aliasing the clang/llvm-link/etc. tool targets to internal targets, which are imported from the LLVM installation directory when building out of tree. Diffing (with llvm-diff) all of the final bytecode libraries in an out-of-tree configuration against those built using the current tip system shows no changes. Note that there are textual changes to metadata IDs which confuse regular diff, and that llvm-diff 14 and below may show false-positives. This commit also removes a file listed in one of the SOURCEs which didn't exist and which was preventing the use of ENABLE_RUNTIME_SUBNORMAL when configuring CMake.
157 lines
4.3 KiB
CMake
157 lines
4.3 KiB
CMake
# Compiles an OpenCL C - or assembles an LL file - to bytecode
|
|
#
|
|
# Arguments:
|
|
# * TRIPLE <string>
|
|
# Target triple for which to compile the bytecode file.
|
|
# * INPUT <string>
|
|
# File to compile/assemble to bytecode
|
|
# * OUTPUT <string>
|
|
# Bytecode file to generate
|
|
# * EXTRA_OPTS <string> ...
|
|
# List of compiler options to use. Note that some are added by default.
|
|
# * DEPENDENCIES <string> ...
|
|
# List of extra dependencies to inject
|
|
#
|
|
# Depends on the libclc::clang and libclc::llvm-as targets for compiling and
|
|
# assembling, respectively.
|
|
function(compile_to_bc)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TRIPLE;INPUT;OUTPUT"
|
|
"EXTRA_OPTS;DEPENDENCIES"
|
|
${ARGN}
|
|
)
|
|
|
|
# If this is an LLVM IR file (identified soley by its file suffix),
|
|
# pre-process it with clang to a temp file, then assemble that to bytecode.
|
|
set( TMP_SUFFIX )
|
|
get_filename_component( FILE_EXT ${ARG_INPUT} EXT )
|
|
if( NOT ${FILE_EXT} STREQUAL ".ll" )
|
|
# Pass '-c' when not running the preprocessor
|
|
set( PP_OPTS -c )
|
|
else()
|
|
set( PP_OPTS -E;-P )
|
|
set( TMP_SUFFIX .tmp )
|
|
endif()
|
|
|
|
set( TARGET_ARG )
|
|
if( ARG_TRIPLE )
|
|
set( TARGET_ARG "-target" ${ARG_TRIPLE} )
|
|
endif()
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
COMMAND libclc::clang
|
|
${TARGET_ARG}
|
|
${PP_OPTS}
|
|
${ARG_EXTRA_OPTS}
|
|
-MD -MF ${ARG_OUTPUT}.d -MT ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
# LLVM 13 enables standard includes by default - we don't want
|
|
# those when pre-processing IR. We disable it unconditionally.
|
|
$<$<VERSION_GREATER_EQUAL:${LLVM_PACKAGE_VERSION},13.0.0>:-cl-no-stdinc>
|
|
-emit-llvm
|
|
-o ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
-x cl
|
|
${ARG_INPUT}
|
|
DEPENDS
|
|
libclc::clang
|
|
${ARG_INPUT}
|
|
${ARG_DEPENDENCIES}
|
|
DEPFILE ${ARG_OUTPUT}.d
|
|
)
|
|
|
|
if( ${FILE_EXT} STREQUAL ".ll" )
|
|
add_custom_command(
|
|
OUTPUT ${ARG_OUTPUT}
|
|
COMMAND libclc::llvm-as -o ${ARG_OUTPUT} ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
DEPENDS libclc::llvm-as ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
)
|
|
endif()
|
|
endfunction()
|
|
|
|
# Links together one or more bytecode files
|
|
#
|
|
# Arguments:
|
|
# * TARGET <string>
|
|
# Custom target to create
|
|
# * INPUT <string> ...
|
|
# List of bytecode files to link together
|
|
function(link_bc)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TARGET"
|
|
"INPUTS"
|
|
${ARGN}
|
|
)
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ARG_TARGET}.bc
|
|
COMMAND libclc::llvm-link -o ${ARG_TARGET}.bc ${ARG_INPUTS}
|
|
DEPENDS libclc::llvm-link ${ARG_INPUTS}
|
|
)
|
|
|
|
add_custom_target( ${ARG_TARGET} ALL DEPENDS ${ARG_TARGET}.bc )
|
|
set_target_properties( ${ARG_TARGET} PROPERTIES TARGET_FILE ${ARG_TARGET}.bc )
|
|
endfunction()
|
|
|
|
# Decomposes and returns variables based on a libclc triple and architecture
|
|
# combination. Returns data via one or more optional output variables.
|
|
#
|
|
# Arguments:
|
|
# * TRIPLE <string>
|
|
# libclc target triple to query
|
|
# * DEVICE <string>
|
|
# libclc device to query
|
|
#
|
|
# Optional Arguments:
|
|
# * CPU <var>
|
|
# Variable name to be set to the target CPU
|
|
# * ARCH_SUFFIX <var>
|
|
# Variable name to be set to the triple/architecture suffix
|
|
# * CLANG_TRIPLE <var>
|
|
# Variable name to be set to the normalized clang triple
|
|
function(get_libclc_device_info)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TRIPLE;DEVICE;CPU;ARCH_SUFFIX;CLANG_TRIPLE"
|
|
""
|
|
${ARGN}
|
|
)
|
|
|
|
if( NOT ARG_TRIPLE OR NOT ARG_DEVICE )
|
|
message( FATAL_ERROR "Must provide both TRIPLE and DEVICE" )
|
|
endif()
|
|
|
|
string( REPLACE "-" ";" TRIPLE ${ARG_TRIPLE} )
|
|
list( GET TRIPLE 0 ARCH )
|
|
|
|
# Some targets don't have a specific device architecture to target
|
|
if( ARG_DEVICE STREQUAL none OR ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
|
|
set( cpu )
|
|
set( arch_suffix "${ARG_TRIPLE}" )
|
|
else()
|
|
set( cpu "${ARG_DEVICE}" )
|
|
set( arch_suffix "${ARG_DEVICE}-${ARG_TRIPLE}" )
|
|
endif()
|
|
|
|
if( ARG_CPU )
|
|
set( ${ARG_CPU} ${cpu} PARENT_SCOPE )
|
|
endif()
|
|
|
|
if( ARG_ARCH_SUFFIX )
|
|
set( ${ARG_ARCH_SUFFIX} ${arch_suffix} PARENT_SCOPE )
|
|
endif()
|
|
|
|
# Some libclc targets are not real clang triples: return their canonical
|
|
# triples.
|
|
if( ARCH STREQUAL spirv OR ARCH STREQUAL clspv )
|
|
set( ARG_TRIPLE "spir--" )
|
|
elseif( ARCH STREQUAL spirv64 OR ARCH STREQUAL clspv64 )
|
|
set( ARG_TRIPLE "spir64--" )
|
|
endif()
|
|
|
|
if( ARG_CLANG_TRIPLE )
|
|
set( ${ARG_CLANG_TRIPLE} ${ARG_TRIPLE} PARENT_SCOPE )
|
|
endif()
|
|
endfunction()
|