From 7ed894ab0acc8ff09262113fdb08940d22654a30 Mon Sep 17 00:00:00 2001 From: Jakub Chlanda Date: Thu, 14 Dec 2023 20:08:51 +0100 Subject: [PATCH] [SYCL][LIBCLC] Allow custom tools location when building libclc (#12034) Use `LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR` to specify the location of custom toolchain to be used for creation of libclc. This helps with debug build times: * debug build of sycl-toolchain with libclc built with debug tools: ```sh $ for f in $(ls lib/clc/*.bc); touch $f; time ninja sycl-toolchain [0/2] Re-checking globbed directories... [6/6] Generating ../../lib/clc/remangled-l64-signed_char.libspirv-amdgcn-amd-amdhsa.bc ninja sycl-toolchain 682.55s user 1.33s system 112% cpu 10:07.81 total ``` * debug build of sycl-toolchain with libclc built with release tools: ```sh $ for f in $(ls lib/clc/*.bc); touch $f; time ninja sycl-toolchain [0/2] Re-checking globbed directories... [6/6] Generating ../../lib/clc/remangled-l64-signed_char.libspirv-amdgcn-amd-amdhsa.bc ninja sycl-toolchain 158.51s user 1.15s system 189% cpu 1:24.31 total ``` Fixes: https://github.com/intel/llvm/issues/6925 --- libclc/CMakeLists.txt | 58 ++++++++++++++++++++++++++++++++----- sycl/doc/GetStartedGuide.md | 15 ++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 76e0c0a83b8d2..bd68b7d788cb5 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -116,19 +116,63 @@ execute_process( COMMAND ${LLVM_CONFIG} "--bindir" # These were not properly reported in early LLVM and we don't need them list( APPEND LLVM_CXX_FLAGS -fno-rtti -fno-exceptions ) +# List containing all the toolchain variables. +list( APPEND BINARY_VARIABLES LLVM_CLANG LLVM_AS LLVM_LINK LLVM_OPT LLVM_SPIRV + LIBCLC_REMANGLER ) +# List containing all the names of toolchain binaries. +# NOTE: both lists (BINARY_VARIABLES and BINARY_NAMES) must be in sync. +list( APPEND BINARY_NAMES clang llvm-as llvm-link opt llvm-spirv + libclc-remangler ) + +# find_program needs the variable to be cleared in order to perform a search. +# Make sure that the cached entries are cleared as well. +function( ClearVariables BINARY_VARIABLES_LIST ) + foreach( V ${BINARY_VARIABLES_LIST} ) + unset( ${V} CACHE ) + unset( ${V} PARENT_SCOPE ) + endforeach( V ) +endfunction() + +# Use find_program to locate toolchain binaries. +function( FindToolBinary BINARY_VARIABLES_LIST BINARY_NAMES_LIST PATH_NAME ) + list( LENGTH BINARY_NAMES_LIST COUNT ) + math( EXPR COUNT "${COUNT}-1" ) + foreach( I RANGE ${COUNT} ) + list( GET BINARY_VARIABLES_LIST ${I} BV ) + list( GET BINARY_NAMES_LIST ${I} BN ) + find_program( ${BV} ${BN} PATHS ${PATH_NAME} NO_DEFAULT_PATH ) + endforeach( I ) +endfunction() + +# Use custom toolchain to build libclc, this can be useful when dealing with +# debug builds, that do not need libclc bitcode to be built using debug tools. +if ( EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) + message( WARNING "Using custom LLVM tools to build libclc: " + "${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR}, " + " make sure that the tools are up to date." ) + + # First clear the variables, + ClearVariables( "${BINARY_VARIABLES}" ) + # then set. + FindToolBinary( "${BINARY_VARIABLES}" "${BINARY_NAMES}" + ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) + + if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK + OR NOT LIBCLC_REMANGLER ) + message( FATAL_ERROR "Custom toolchain incomplete!" ) + endif() +endif() + # Print LLVM variables message( "LLVM libdir: ${LLVM_LIBRARY_DIR}" ) message( "LLVM bindir: ${LLVM_TOOLS_BINARY_DIR}" ) message( "LLVM cxx flags: ${LLVM_CXX_FLAGS}" ) message( "" ) -find_program( LLVM_CLANG clang PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) -find_program( LLVM_AS llvm-as PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) -find_program( LLVM_LINK llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) -find_program( LLVM_OPT opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) -find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) -find_program( LIBCLC_REMANGLER libclc-remangler PATHS ${LLVM_TOOLS_BINARY_DIR} - NO_DEFAULT_PATH ) +# It's OK to call find program again, if the variables have been set in the +# custom location clause, find_program returns immediately. +FindToolBinary( "${BINARY_VARIABLES}" "${BINARY_NAMES}" + ${LLVM_TOOLS_BINARY_DIR} ) # Print toolchain message( "clang: ${LLVM_CLANG}" ) diff --git a/sycl/doc/GetStartedGuide.md b/sycl/doc/GetStartedGuide.md index 564dbe0dcdec6..2dc2abf704642 100644 --- a/sycl/doc/GetStartedGuide.md +++ b/sycl/doc/GetStartedGuide.md @@ -377,6 +377,21 @@ control which revision of Unified Runtime should be used when building DPC++: * `SYCL_PI_UR_SOURCE_DIR` is a variable used to specify the path to the Unified Runtime repository when `SYCL_PI_UR_USE_FETCH_CONTENT` is set of `OFF`. +### Build DPC++ libclc with a custom toolchain + +libclc is an implementation of the OpenCL required libraries, as described in +the [OpenCL C specification](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html), +additionally providing definitions of SPIR-V builtins. It is built to +target-specific bitcode, that is linked against SYCL binaries. By default, the +built system uses the SYCL toolchain currently being built to create libclc +bitcode. This can be suboptimal in case of debug builds, in which case debug +tools are used to build non-debug libclc bitcode (the notion of debug builds +doesn't really apply to libclc), resulting in very long compilation time. In +order to specify a directory containing custom toolchain users can set: +`LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR` variable. Care is required, as the +changes to the local SYCL tree might not be reflected in the custom location +during the build time. + ### Deployment TODO: add instructions how to deploy built DPC++ toolchain.