diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index 3f8445833695..334faa1a0266 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -24,8 +24,8 @@ option( # List of all supported architectures. set( LIBCLC_ARCHS_ALL amdgpu amdgcn nvptx64 ) -set( LIBCLC_ARCHS_SPIRV spirv spirv32 spirv64) -list( APPEND LIBCLC_ARCHS_ALL ${LIBCLC_ARCHS_SPIRV}) +set( LIBCLC_ARCHS_SPIRV spirv spirv32 spirv64 ) +list( APPEND LIBCLC_ARCHS_ALL ${LIBCLC_ARCHS_SPIRV} ) set(LIBCLC_TARGET ${LLVM_DEFAULT_TARGET_TRIPLE}) @@ -33,10 +33,13 @@ if(NOT LIBCLC_TARGET) message(FATAL_ERROR "libclc target is empty\n") endif() -string( REPLACE "-" ";" _target_components ${LIBCLC_TARGET} ) -list(GET _target_components 0 _target_arch) -if(NOT "${_target_arch}" IN_LIST LIBCLC_ARCHS_ALL) - message(FATAL_ERROR "Unknown libclc target architecture: ${_target_arch}\n" +# Parse the target triple into arch and OS components. +string(REPLACE "-" ";" triple_components ${LIBCLC_TARGET}) +list(GET triple_components 0 LIBCLC_TARGET_ARCH) +list(GET triple_components 2 LIBCLC_TARGET_OS) + +if(NOT "${LIBCLC_TARGET_ARCH}" IN_LIST LIBCLC_ARCHS_ALL) + message(FATAL_ERROR "Unknown libclc target architecture: ${LIBCLC_TARGET_ARCH}\n" "Target was: ${LIBCLC_TARGET}\n" "Valid architectures are: ${LIBCLC_ARCHS_ALL}\n") endif() @@ -98,12 +101,17 @@ endif() message(STATUS "libclc target '${LIBCLC_TARGET}' is enabled") -string( REPLACE "-" ";" TRIPLE ${LIBCLC_TARGET} ) -list(GET TRIPLE 0 ARCH) -list(GET TRIPLE 2 OS) +# Map the LLVM target architecture to the standard directory name. +if(LIBCLC_TARGET_ARCH STREQUAL amdgcn OR LIBCLC_TARGET_ARCH STREQUAL amdgpu) + set(LIBCLC_ARCH_DIR amdgpu) +elseif(LIBCLC_TARGET_ARCH STREQUAL nvptx64) + set(LIBCLC_ARCH_DIR nvptx) +elseif(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV) + set(LIBCLC_ARCH_DIR spirv) +endif() -if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV) - if(NOT OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND AND NOT llvm-spirv_exe) +if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV) + if(NOT LIBCLC_TARGET_OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND AND NOT llvm-spirv_exe) message(FATAL_ERROR "SPIR-V backend or llvm-spirv is required for libclc ${LIBCLC_TARGET}") endif() endif() @@ -114,35 +122,12 @@ foreach( tool IN ITEMS opt llvm-link ) endif() endforeach() -add_subdirectory(clc/lib/generic) -add_subdirectory(opencl/lib/generic) - -if(ARCH STREQUAL amdgcn) - add_subdirectory(clc/lib/amdgpu) - add_subdirectory(opencl/lib/amdgpu) -elseif(ARCH STREQUAL nvptx64) - add_subdirectory(clc/lib/ptx-nvidiacl) -elseif(ARCH STREQUAL spirv OR ARCH STREQUAL spirv32 OR ARCH STREQUAL spirv64) - if(OS STREQUAL vulkan) - add_subdirectory(clc/lib/vulkan) - add_subdirectory(opencl/lib/vulkan) - else() - add_subdirectory(clc/lib/spirv) - add_subdirectory(opencl/lib/spirv) - endif() -endif() - -add_custom_target( libclc ALL ) - -add_custom_target( libclc-opencl-builtins COMMENT "Build libclc OpenCL builtins" ) -add_dependencies( libclc libclc-opencl-builtins ) - # Determine the clang target triple. Vulkan and SPIR-V backend targets use the # triple directly; other SPIR-V targets fall back to the legacy SPIR target. set(clang_triple ${LIBCLC_TARGET}) -if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV) - if(NOT OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND) - if(ARCH STREQUAL spirv) +if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV) + if(NOT LIBCLC_TARGET_OS STREQUAL vulkan AND NOT LIBCLC_USE_SPIRV_BACKEND) + if(LIBCLC_TARGET_ARCH STREQUAL spirv) set(clang_triple spir--) else() set(clang_triple spir64--) @@ -153,10 +138,10 @@ endif() # Address space values. set(private_addrspace_val 0) set(generic_addrspace_val 0) -if(ARCH STREQUAL amdgcn) +if(LIBCLC_TARGET_ARCH STREQUAL amdgcn) set(private_addrspace_val 5) endif() -if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT OS STREQUAL vulkan) +if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT LIBCLC_TARGET_OS STREQUAL vulkan) set(generic_addrspace_val 4) endif() @@ -165,50 +150,18 @@ set(target_compile_flags) set(target_extra_defines) set(opt_flags -O3) -if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV) - if(OS STREQUAL vulkan) +if(LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV) + if(LIBCLC_TARGET_OS STREQUAL vulkan) list(APPEND target_compile_flags -Wno-unknown-assumption -U__opencl_c_int64) else() list(APPEND target_compile_flags -O0 -finline-hint-functions) list(APPEND target_extra_defines CLC_SPIRV) set(opt_flags) endif() -elseif(ARCH STREQUAL amdgcn) +elseif(LIBCLC_TARGET_ARCH STREQUAL amdgcn) list(APPEND target_compile_flags "SHELL:-Xclang -mcode-object-version=none") endif() -# Collect CLC sources; target-specific sources override generic ones by basename. -set(_clc_overrides) -if(ARCH STREQUAL amdgcn) - list(APPEND _clc_overrides ${CLC_AMDGPU_SOURCES}) -elseif(ARCH STREQUAL nvptx64 AND (OS STREQUAL nvidiacl OR OS STREQUAL cuda)) - list(APPEND _clc_overrides ${CLC_PTX_NVIDIACL_SOURCES}) -elseif(ARCH IN_LIST LIBCLC_ARCHS_SPIRV) - if(OS STREQUAL vulkan) - list(APPEND _clc_overrides ${CLC_VULKAN_SOURCES}) - else() - list(APPEND _clc_overrides ${CLC_SPIRV_SOURCES}) - endif() -endif() -libclc_merge_sources(clc_sources ${CLC_GENERIC_SOURCES} ${_clc_overrides}) - -# Collect OpenCL sources. SPIR-V and Vulkan targets use self-contained -# subsets while others merge with target-specific overrides. -if(ARCH IN_LIST LIBCLC_ARCHS_SPIRV) - if(OS STREQUAL vulkan) - set(opencl_sources ${OPENCL_VULKAN_SOURCES}) - else() - set(opencl_sources ${OPENCL_SPIRV_SOURCES}) - endif() -else() - set(_opencl_overrides) - if(ARCH STREQUAL amdgcn) - list(APPEND _opencl_overrides ${OPENCL_AMDGCN_SOURCES}) - endif() - libclc_merge_sources(opencl_sources - ${OPENCL_GENERIC_SOURCES} ${_opencl_overrides}) -endif() - # Common compile options shared by CLC and OpenCL libraries. set(compile_flags -flto @@ -227,35 +180,45 @@ set(compile_flags ${target_compile_flags} ) -set(_common_defs +set(common_defs ${target_extra_defines} __CLC_PRIVATE_ADDRSPACE_VAL=${private_addrspace_val} __CLC_GENERIC_ADDRSPACE_VAL=${generic_addrspace_val} ) -# Build the CLC internal builtins library. -string(REPLACE "-" "_" lib_suffix ${LIBCLC_TARGET}) -set(clc_lib clc_builtins_${lib_suffix}) -add_libclc_builtin_library(${clc_lib} - SOURCES ${clc_sources} +add_custom_target(libclc ALL) +add_custom_target(libclc-opencl-builtins COMMENT "Build libclc OpenCL builtins") +add_dependencies(libclc libclc-opencl-builtins) + +# Configure the CLC internal builtins library. +set(LIBCLC_CLC_TARGET clc) +libclc_add_builtin_library(${LIBCLC_CLC_TARGET} COMPILE_OPTIONS ${compile_flags} INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/clc/include - COMPILE_DEFINITIONS ${_common_defs} + COMPILE_DEFINITIONS ${common_defs} FOLDER "libclc/Device IR/CLC" ) -# Build, link, and install the final OpenCL builtins library. -add_libclc_library(libclc-${LIBCLC_TARGET} - ARCH ${ARCH} - TRIPLE ${clang_triple} - TARGET_TRIPLE ${LIBCLC_TARGET} - SOURCES ${opencl_sources} +set(LIBCLC_OPENCL_TARGET opencl) +libclc_add_builtin_library(${LIBCLC_OPENCL_TARGET} COMPILE_OPTIONS ${compile_flags} "SHELL:-Xclang -fdeclare-opencl-builtins" INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/clc/include ${CMAKE_CURRENT_SOURCE_DIR}/opencl/include - COMPILE_DEFINITIONS ${_common_defs} - INTERNALIZE_LIBRARIES ${clc_lib} + COMPILE_DEFINITIONS ${common_defs} + FOLDER "libclc/Device IR/Intermediate" +) + +add_subdirectory(clc) +add_subdirectory(opencl) + +# Link and install the final OpenCL builtins library. +libclc_add_library(libclc-${LIBCLC_TARGET} + ARCH ${LIBCLC_TARGET_ARCH} + TRIPLE ${clang_triple} + TARGET_TRIPLE ${LIBCLC_TARGET} + LIBRARIES ${LIBCLC_OPENCL_TARGET} + INTERNALIZE_LIBRARIES ${LIBCLC_CLC_TARGET} OPT_FLAGS ${opt_flags} OUTPUT_FILENAME libclc PARENT_TARGET libclc-opencl-builtins diff --git a/libclc/clc/CMakeLists.txt b/libclc/clc/CMakeLists.txt new file mode 100644 index 000000000000..bd75adcf7524 --- /dev/null +++ b/libclc/clc/CMakeLists.txt @@ -0,0 +1,5 @@ +# Add the target specific files first so they can override the generic fallback. +if(LIBCLC_ARCH_DIR AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR}) + add_subdirectory(lib/${LIBCLC_ARCH_DIR}) +endif() +add_subdirectory(lib/generic) diff --git a/libclc/clc/lib/amdgpu/CMakeLists.txt b/libclc/clc/lib/amdgpu/CMakeLists.txt index a5cd47fab446..910a0cf1765d 100644 --- a/libclc/clc/lib/amdgpu/CMakeLists.txt +++ b/libclc/clc/lib/amdgpu/CMakeLists.txt @@ -1,5 +1,4 @@ -libclc_configure_source_list(CLC_AMDGPU_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_CLC_TARGET} FILES address_space/clc_qualifier.cl math/clc_cbrt.cl math/clc_exp.cl @@ -45,9 +44,10 @@ libclc_configure_source_list(CLC_AMDGPU_SOURCES workitem/clc_get_num_sub_groups.cl workitem/clc_get_sub_group_id.cl workitem/clc_get_sub_group_size.cl - workitem/clc_get_work_dim.cl) + workitem/clc_get_work_dim.cl +) -libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func +libclc_set_source_options(-fapprox-func math/clc_native_exp.cl math/clc_native_exp2.cl math/clc_native_log10.cl diff --git a/libclc/clc/lib/generic/CMakeLists.txt b/libclc/clc/lib/generic/CMakeLists.txt index 168a0f1ff1e8..40261545fce9 100644 --- a/libclc/clc/lib/generic/CMakeLists.txt +++ b/libclc/clc/lib/generic/CMakeLists.txt @@ -1,5 +1,4 @@ -libclc_configure_source_list(CLC_GENERIC_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_CLC_TARGET} FILES async/clc_prefetch.cl atomic/clc_atomic_compare_exchange.cl atomic/clc_atomic_dec.cl @@ -209,7 +208,7 @@ libclc_configure_source_list(CLC_GENERIC_SOURCES workitem/clc_get_sub_group_size.cl ) -libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func +libclc_set_source_options(-fapprox-func math/clc_native_cos.cl math/clc_native_divide.cl math/clc_native_exp.cl @@ -226,8 +225,10 @@ libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func math/clc_native_tan.cl math/clc_div_fast.cl math/clc_recip_fast.cl - math/clc_sqrt_fast.cl) + math/clc_sqrt_fast.cl +) -libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -cl-fp32-correctly-rounded-divide-sqrt +libclc_set_source_options(-cl-fp32-correctly-rounded-divide-sqrt math/clc_div_cr.cl - math/clc_sqrt_cr.cl) + math/clc_sqrt_cr.cl +) diff --git a/libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt b/libclc/clc/lib/nvptx/CMakeLists.txt similarity index 83% rename from libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt rename to libclc/clc/lib/nvptx/CMakeLists.txt index 6eb0baab1c0b..2345d5aeed77 100644 --- a/libclc/clc/lib/ptx-nvidiacl/CMakeLists.txt +++ b/libclc/clc/lib/nvptx/CMakeLists.txt @@ -1,5 +1,4 @@ -libclc_configure_source_list(CLC_PTX_NVIDIACL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_CLC_TARGET} FILES math/clc_log.cl math/clc_rsqrt.cl math/clc_sinpi.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_log.cl b/libclc/clc/lib/nvptx/math/clc_log.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/math/clc_log.cl rename to libclc/clc/lib/nvptx/math/clc_log.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_rsqrt.cl b/libclc/clc/lib/nvptx/math/clc_rsqrt.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/math/clc_rsqrt.cl rename to libclc/clc/lib/nvptx/math/clc_rsqrt.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_sinpi.cl b/libclc/clc/lib/nvptx/math/clc_sinpi.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/math/clc_sinpi.cl rename to libclc/clc/lib/nvptx/math/clc_sinpi.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/math/clc_sqrt.cl b/libclc/clc/lib/nvptx/math/clc_sqrt.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/math/clc_sqrt.cl rename to libclc/clc/lib/nvptx/math/clc_sqrt.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/relational/clc_isinf.cl b/libclc/clc/lib/nvptx/relational/clc_isinf.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/relational/clc_isinf.cl rename to libclc/clc/lib/nvptx/relational/clc_isinf.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/synchronization/clc_work_group_barrier.cl b/libclc/clc/lib/nvptx/synchronization/clc_work_group_barrier.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/synchronization/clc_work_group_barrier.cl rename to libclc/clc/lib/nvptx/synchronization/clc_work_group_barrier.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_id.cl b/libclc/clc/lib/nvptx/workitem/clc_get_global_id.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_id.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_global_id.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_size.cl b/libclc/clc/lib/nvptx/workitem/clc_get_global_size.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_global_size.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_global_size.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_group_id.cl b/libclc/clc/lib/nvptx/workitem/clc_get_group_id.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_group_id.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_group_id.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_id.cl b/libclc/clc/lib/nvptx/workitem/clc_get_local_id.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_id.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_local_id.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_size.cl b/libclc/clc/lib/nvptx/workitem/clc_get_local_size.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_local_size.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_local_size.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_max_sub_group_size.cl b/libclc/clc/lib/nvptx/workitem/clc_get_max_sub_group_size.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_max_sub_group_size.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_max_sub_group_size.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_num_groups.cl b/libclc/clc/lib/nvptx/workitem/clc_get_num_groups.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_num_groups.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_num_groups.cl diff --git a/libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_sub_group_local_id.cl b/libclc/clc/lib/nvptx/workitem/clc_get_sub_group_local_id.cl similarity index 100% rename from libclc/clc/lib/ptx-nvidiacl/workitem/clc_get_sub_group_local_id.cl rename to libclc/clc/lib/nvptx/workitem/clc_get_sub_group_local_id.cl diff --git a/libclc/clc/lib/spirv/CMakeLists.txt b/libclc/clc/lib/spirv/CMakeLists.txt index b7481615b941..5f361c95c400 100644 --- a/libclc/clc/lib/spirv/CMakeLists.txt +++ b/libclc/clc/lib/spirv/CMakeLists.txt @@ -1,5 +1,8 @@ -libclc_configure_source_list(CLC_SPIRV_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +if(LIBCLC_TARGET_OS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBCLC_TARGET_OS}) + add_subdirectory(${LIBCLC_TARGET_OS}) +endif() + +libclc_add_sources(${LIBCLC_CLC_TARGET} FILES math/clc_fmax.cl math/clc_fmin.cl subnormal_config.cl diff --git a/libclc/clc/lib/spirv/vulkan/CMakeLists.txt b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt new file mode 100644 index 000000000000..499ce274a500 --- /dev/null +++ b/libclc/clc/lib/spirv/vulkan/CMakeLists.txt @@ -0,0 +1,4 @@ +libclc_add_sources(${LIBCLC_CLC_TARGET} FILES + integer/clc_mul_hi.cl + math/clc_sw_fma.cl +) diff --git a/libclc/clc/lib/vulkan/integer/clc_mul_hi.cl b/libclc/clc/lib/spirv/vulkan/integer/clc_mul_hi.cl similarity index 100% rename from libclc/clc/lib/vulkan/integer/clc_mul_hi.cl rename to libclc/clc/lib/spirv/vulkan/integer/clc_mul_hi.cl diff --git a/libclc/clc/lib/vulkan/math/clc_sw_fma.cl b/libclc/clc/lib/spirv/vulkan/math/clc_sw_fma.cl similarity index 100% rename from libclc/clc/lib/vulkan/math/clc_sw_fma.cl rename to libclc/clc/lib/spirv/vulkan/math/clc_sw_fma.cl diff --git a/libclc/clc/lib/vulkan/CMakeLists.txt b/libclc/clc/lib/vulkan/CMakeLists.txt deleted file mode 100644 index 172e3be32d65..000000000000 --- a/libclc/clc/lib/vulkan/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -libclc_configure_source_list(CLC_VULKAN_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} - integer/clc_mul_hi.cl - math/clc_sw_fma.cl -) diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake index 41297e8eb1e9..2d547e13a4e0 100644 --- a/libclc/cmake/modules/AddLibclc.cmake +++ b/libclc/cmake/modules/AddLibclc.cmake @@ -1,67 +1,71 @@ -# Converts a list of relative source paths to absolute paths and exports -# it to the parent scope. -macro(libclc_configure_source_list variable path) - set(${variable} ${ARGN}) - list(TRANSFORM ${variable} PREPEND "${path}/") - set(${variable} ${${variable}} PARENT_SCOPE) -endmacro() - -# Appends a compile option to the given source files. Paths are relative -# to `path` and the property is set in the top-level libclc directory scope. -macro(libclc_configure_source_options path option) - set(_option_srcs ${ARGN}) - list(TRANSFORM _option_srcs PREPEND "${path}/") - set_property(SOURCE ${_option_srcs} - DIRECTORY ${LIBCLC_SOURCE_DIR} - APPEND PROPERTY COMPILE_OPTIONS ${option} - ) -endmacro() - -# Merges OpenCL C source file lists with priority deduplication. +# Adds source files to a libclc builtin library target with deduplication. If a +# source with the same basename already exists in the target's SOURCES property +# the new file is skipped. This enables target-specific directories to override +# generic implementations when they are included first. # -# All arguments after the output variable name are treated as source file -# paths. When multiple files share the same basename, the last occurrence -# wins. This allows target-specific files to automatically override generic -# ones. -function(libclc_merge_sources output) - set(all_sources ${ARGN}) - set(result) - set(seen_names) +# Sources are specified as paths relative to CMAKE_CURRENT_SOURCE_DIR, or +# relative to BASE_DIR if provided. +function(libclc_add_sources target) + cmake_parse_arguments(ARG "" "BASE_DIR" "FILES" ${ARGN}) + if(NOT ARG_BASE_DIR) + set(ARG_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + endif() - list(REVERSE all_sources) - foreach(f ${all_sources}) - get_filename_component(name "${f}" NAME) - if(NOT name IN_LIST seen_names) - list(APPEND seen_names "${name}") - list(PREPEND result "${f}") + get_target_property(existing ${target} SOURCES) + + set(seen) + foreach(file IN LISTS existing) + get_filename_component(name "${file}" NAME) + list(APPEND seen "${name}") + endforeach() + + set(new_sources) + foreach(rel_src IN LISTS ARG_FILES) + get_filename_component(name "${rel_src}" NAME) + if(NOT name IN_LIST seen) + list(APPEND new_sources "${ARG_BASE_DIR}/${rel_src}") + list(APPEND seen "${name}") endif() endforeach() - set(${output} ${result} PARENT_SCOPE) + if(new_sources) + target_sources(${target} PRIVATE ${new_sources}) + set(inc_dirs) + foreach(file IN LISTS new_sources) + get_filename_component(dir "${file}" DIRECTORY) + list(APPEND inc_dirs "${dir}") + endforeach() + list(REMOVE_DUPLICATES inc_dirs) + target_include_directories(${target} PRIVATE ${inc_dirs}) + endif() endfunction() -# Creates a static library target for libclc builtins. Derives include -# directories to locate `.inc` files in the same directory. -function(add_libclc_builtin_library target_name) +# Appends a compile option to the given source files. Source paths are +# relative to CMAKE_CURRENT_SOURCE_DIR. The property is set in the +# top-level libclc directory scope. +function(libclc_set_source_options option) + set(srcs ${ARGN}) + list(TRANSFORM srcs PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") + set_property(SOURCE ${srcs} + DIRECTORY ${LIBCLC_SOURCE_DIR} + APPEND PROPERTY COMPILE_OPTIONS ${option} + ) +endfunction() + +# Creates a static library target for libclc builtins and configures its +# compile options, include directories, and definitions. Subdirectories +# populate sources via libclc_add_sources() after this call. +function(libclc_add_builtin_library target_name) cmake_parse_arguments(ARG "" "FOLDER" - "SOURCES;COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS" + "COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS" ${ARGN} ) - set(_inc_dirs) - foreach(f ${ARG_SOURCES}) - get_filename_component(dir ${f} DIRECTORY) - list(APPEND _inc_dirs ${dir}) - endforeach() - list(REMOVE_DUPLICATES _inc_dirs) - - add_library(${target_name} STATIC ${ARG_SOURCES}) + add_library(${target_name} STATIC) target_compile_options(${target_name} PRIVATE ${ARG_COMPILE_OPTIONS}) - target_include_directories(${target_name} PRIVATE - ${ARG_INCLUDE_DIRS} ${_inc_dirs} - ) + target_include_directories(${target_name} PRIVATE ${ARG_INCLUDE_DIRS}) target_compile_definitions(${target_name} PRIVATE ${ARG_COMPILE_DEFINITIONS}) set_target_properties(${target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} @@ -71,7 +75,7 @@ endfunction() # Links one or more libclc builtin libraries together, optionally # internalizing dependencies, then produces a final .bc or .spv file. -function(link_libclc_builtin_library target_name) +function(libclc_link_library target_name) cmake_parse_arguments(ARG "" "ARCH;TRIPLE;TARGET_TRIPLE;FOLDER;OUTPUT_FILENAME" @@ -80,10 +84,10 @@ function(link_libclc_builtin_library target_name) ) if(NOT ARG_OUTPUT_FILENAME) - message(FATAL_ERROR "OUTPUT_FILENAME is required for link_libclc_builtin_library") + message(FATAL_ERROR "OUTPUT_FILENAME is required for libclc_link_library") endif() if(NOT ARG_LIBRARIES) - message(FATAL_ERROR "LIBRARIES is required for link_libclc_builtin_library") + message(FATAL_ERROR "LIBRARIES is required for libclc_link_library") endif() set(library_dir ${LIBCLC_OUTPUT_LIBRARY_DIR}/${ARG_TARGET_TRIPLE}) @@ -113,7 +117,7 @@ function(link_libclc_builtin_library target_name) string(REPLACE "-" ";" triple_parts "${ARG_TRIPLE}") list(GET triple_parts 2 triple_os) - if((ARG_ARCH STREQUAL spirv OR ARG_ARCH STREQUAL spirv32 OR ARG_ARCH STREQUAL spirv64) AND NOT triple_os STREQUAL vulkan) + if(ARG_ARCH IN_LIST LIBCLC_ARCHS_SPIRV AND NOT triple_os STREQUAL vulkan) # SPIR-V targets produce a .spv file from the linked bitcode. set(builtins_lib ${library_dir}/${ARG_OUTPUT_FILENAME}.spv) if(LIBCLC_USE_SPIRV_BACKEND) @@ -148,41 +152,31 @@ function(link_libclc_builtin_library target_name) ) endfunction() -# Builds a builtins library from sources, links it with any internalized -# dependencies via link_libclc_builtin_library, and adds a verification test -# for unresolved symbols. -function(add_libclc_library target_name) +# Links builtin library targets, produces the final output file, and +# registers it for installation. +function(libclc_add_library target_name) cmake_parse_arguments(ARG "" "ARCH;TRIPLE;TARGET_TRIPLE;OUTPUT_FILENAME;PARENT_TARGET" - "SOURCES;COMPILE_OPTIONS;INCLUDE_DIRS;COMPILE_DEFINITIONS;INTERNALIZE_LIBRARIES;OPT_FLAGS" + "LIBRARIES;INTERNALIZE_LIBRARIES;OPT_FLAGS" ${ARGN} ) if(NOT ARG_OUTPUT_FILENAME) - message(FATAL_ERROR "OUTPUT_FILENAME is required for add_libclc_library") + message(FATAL_ERROR "OUTPUT_FILENAME is required for libclc_add_library") endif() if(NOT ARG_PARENT_TARGET) - message(FATAL_ERROR "PARENT_TARGET is required for add_libclc_library") + message(FATAL_ERROR "PARENT_TARGET is required for libclc_add_library") endif() - if(NOT ARG_SOURCES) - message(FATAL_ERROR "SOURCES is required for add_libclc_library") + if(NOT ARG_LIBRARIES) + message(FATAL_ERROR "LIBRARIES is required for libclc_add_library") endif() - set(builtins_target ${target_name}_clc_builtins) - add_libclc_builtin_library(${builtins_target} - SOURCES ${ARG_SOURCES} - COMPILE_OPTIONS ${ARG_COMPILE_OPTIONS} - INCLUDE_DIRS ${ARG_INCLUDE_DIRS} - COMPILE_DEFINITIONS ${ARG_COMPILE_DEFINITIONS} - FOLDER "libclc/Device IR/Intermediate" - ) - - link_libclc_builtin_library(${target_name} + libclc_link_library(${target_name} ARCH ${ARG_ARCH} TRIPLE ${ARG_TRIPLE} TARGET_TRIPLE ${ARG_TARGET_TRIPLE} - LIBRARIES ${builtins_target} + LIBRARIES ${ARG_LIBRARIES} INTERNALIZE_LIBRARIES ${ARG_INTERNALIZE_LIBRARIES} OPT_FLAGS ${ARG_OPT_FLAGS} OUTPUT_FILENAME "${ARG_OUTPUT_FILENAME}" diff --git a/libclc/opencl/CMakeLists.txt b/libclc/opencl/CMakeLists.txt new file mode 100644 index 000000000000..8b4ac40ea827 --- /dev/null +++ b/libclc/opencl/CMakeLists.txt @@ -0,0 +1,9 @@ +# Add the target specific files first so they can override the generic fallback. +if(LIBCLC_ARCH_DIR AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIBCLC_ARCH_DIR}) + add_subdirectory(lib/${LIBCLC_ARCH_DIR}) +endif() + +# SPIR-V targets cannot use the generic list of generic functions yet. +if(NOT LIBCLC_TARGET_ARCH IN_LIST LIBCLC_ARCHS_SPIRV) + add_subdirectory(lib/generic) +endif() diff --git a/libclc/opencl/lib/amdgpu/CMakeLists.txt b/libclc/opencl/lib/amdgpu/CMakeLists.txt index a42f2751906b..16a75349d8a4 100644 --- a/libclc/opencl/lib/amdgpu/CMakeLists.txt +++ b/libclc/opencl/lib/amdgpu/CMakeLists.txt @@ -1,5 +1,4 @@ -libclc_configure_source_list(OPENCL_AMDGCN_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES async/wait_group_events.cl printf/__printf_alloc.cl ) diff --git a/libclc/opencl/lib/generic/CMakeLists.txt b/libclc/opencl/lib/generic/CMakeLists.txt index 4ad60248139a..5768ba9446ff 100644 --- a/libclc/opencl/lib/generic/CMakeLists.txt +++ b/libclc/opencl/lib/generic/CMakeLists.txt @@ -1,5 +1,4 @@ -libclc_configure_source_list(OPENCL_GENERIC_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES address_space/qualifier.cl async/async_work_group_copy.cl async/async_work_group_strided_copy.cl @@ -227,7 +226,7 @@ libclc_configure_source_list(OPENCL_GENERIC_SOURCES workitem/get_work_dim.cl ) -libclc_configure_source_options(${CMAKE_CURRENT_SOURCE_DIR} -fapprox-func +libclc_set_source_options(-fapprox-func math/native_cos.cl math/native_divide.cl math/native_exp.cl diff --git a/libclc/opencl/lib/spirv/CMakeLists.txt b/libclc/opencl/lib/spirv/CMakeLists.txt index ab6fea0692c0..ea35940f60d7 100644 --- a/libclc/opencl/lib/spirv/CMakeLists.txt +++ b/libclc/opencl/lib/spirv/CMakeLists.txt @@ -1,9 +1,12 @@ -set(_gen ${CMAKE_CURRENT_SOURCE_DIR}/../generic) +if(LIBCLC_TARGET_OS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBCLC_TARGET_OS}) + add_subdirectory(${LIBCLC_TARGET_OS}) + return() +endif() -# SPIR-V uses a curated subset of generic builtins, so this list is -# self-contained rather than merged with the generic set. -libclc_configure_source_list(OPENCL_SPIRV_SOURCES - ${_gen} +# Non-Vulkan SPIR-V uses a curated subset of generic builtins. +libclc_add_sources(${LIBCLC_OPENCL_TARGET} + BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../generic + FILES async/async_work_group_strided_copy.cl async/wait_group_events.cl common/degrees.cl diff --git a/libclc/opencl/lib/vulkan/CMakeLists.txt b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt similarity index 85% rename from libclc/opencl/lib/vulkan/CMakeLists.txt rename to libclc/opencl/lib/spirv/vulkan/CMakeLists.txt index 5fa2e7a36767..d04959027f0d 100644 --- a/libclc/opencl/lib/vulkan/CMakeLists.txt +++ b/libclc/opencl/lib/spirv/vulkan/CMakeLists.txt @@ -1,9 +1,6 @@ -set(_gen ${CMAKE_CURRENT_SOURCE_DIR}/../generic) - # Vulkan uses a curated subset of generic builtins plus its own overrides, # so this list is self-contained rather than merged with the generic set. -libclc_configure_source_list(_vulkan_sources - ${CMAKE_CURRENT_SOURCE_DIR} +libclc_add_sources(${LIBCLC_OPENCL_TARGET} FILES conversion/convert_float2float.cl conversion/convert_float2int.cl conversion/convert_int2float.cl @@ -12,8 +9,9 @@ libclc_configure_source_list(_vulkan_sources shared/vstore_half.cl ) -libclc_configure_source_list(_gen_sources - ${_gen} +libclc_add_sources(${LIBCLC_OPENCL_TARGET} + BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../generic + FILES geometric/distance.cl geometric/length.cl math/acos.cl @@ -84,5 +82,3 @@ libclc_configure_source_list(_gen_sources math/tanpi.cl math/tgamma.cl ) - -set(OPENCL_VULKAN_SOURCES ${_vulkan_sources} ${_gen_sources} PARENT_SCOPE) diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float.inc b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float.inc similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_float.inc rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float.inc diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float2float.cl b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float2float.cl similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_float2float.cl rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float2float.cl diff --git a/libclc/opencl/lib/vulkan/conversion/convert_float2int.cl b/libclc/opencl/lib/spirv/vulkan/conversion/convert_float2int.cl similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_float2int.cl rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_float2int.cl diff --git a/libclc/opencl/lib/vulkan/conversion/convert_int2float.cl b/libclc/opencl/lib/spirv/vulkan/conversion/convert_int2float.cl similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_int2float.cl rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_int2float.cl diff --git a/libclc/opencl/lib/vulkan/conversion/convert_integer.cl b/libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.cl similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_integer.cl rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.cl diff --git a/libclc/opencl/lib/vulkan/conversion/convert_integer.inc b/libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.inc similarity index 100% rename from libclc/opencl/lib/vulkan/conversion/convert_integer.inc rename to libclc/opencl/lib/spirv/vulkan/conversion/convert_integer.inc diff --git a/libclc/opencl/lib/vulkan/math/fma.cl b/libclc/opencl/lib/spirv/vulkan/math/fma.cl similarity index 100% rename from libclc/opencl/lib/vulkan/math/fma.cl rename to libclc/opencl/lib/spirv/vulkan/math/fma.cl diff --git a/libclc/opencl/lib/vulkan/shared/vstore_half.cl b/libclc/opencl/lib/spirv/vulkan/shared/vstore_half.cl similarity index 100% rename from libclc/opencl/lib/vulkan/shared/vstore_half.cl rename to libclc/opencl/lib/spirv/vulkan/shared/vstore_half.cl diff --git a/libclc/opencl/lib/vulkan/shared/vstore_half.inc b/libclc/opencl/lib/spirv/vulkan/shared/vstore_half.inc similarity index 100% rename from libclc/opencl/lib/vulkan/shared/vstore_half.inc rename to libclc/opencl/lib/spirv/vulkan/shared/vstore_half.inc