blob: 6ec0cc2b61bc0993d11f3aeb1b4aa31ea6b20e9d [file] [log] [blame]
Jonas Hahnfeld37bbe1a2018-05-16 17:20:21 +00001#
2#//===----------------------------------------------------------------------===//
3#//
Chandler Carruth57b08b02019-01-19 10:56:40 +00004#// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5#// See https://llvm.org/LICENSE.txt for license information.
6#// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Jonas Hahnfeld37bbe1a2018-05-16 17:20:21 +00007#//
8#//===----------------------------------------------------------------------===//
9#
10
11# We use the compiler and linker provided by the user, attempt to use the one
12# used to build libomptarget or just fail.
13set(LIBOMPTARGET_NVPTX_BCLIB_SUPPORTED FALSE)
14
15if (NOT LIBOMPTARGET_NVPTX_CUDA_COMPILER STREQUAL "")
16 set(LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER ${LIBOMPTARGET_NVPTX_CUDA_COMPILER})
17elseif(${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
18 set(LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER ${CMAKE_C_COMPILER})
19else()
20 return()
21endif()
22
23# Get compiler directory to try to locate a suitable linker.
24get_filename_component(compiler_dir ${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER} DIRECTORY)
25set(llvm_link "${compiler_dir}/llvm-link")
26
27if (NOT LIBOMPTARGET_NVPTX_BC_LINKER STREQUAL "")
28 set(LIBOMPTARGET_NVPTX_SELECTED_BC_LINKER ${LIBOMPTARGET_NVPTX_BC_LINKER})
29elseif (EXISTS "${llvm_link}")
30 # Use llvm-link from the compiler directory.
31 set(LIBOMPTARGET_NVPTX_SELECTED_BC_LINKER "${llvm_link}")
32else()
33 return()
34endif()
35
36function(try_compile_bitcode output source)
37 set(srcfile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cu)
38 file(WRITE ${srcfile} "${source}\n")
39 set(bcfile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/out.bc)
40
41 # The remaining arguments are the flags to be tested.
42 # FIXME: Don't hardcode GPU version. This is currently required because
43 # Clang refuses to compile its default of sm_20 with CUDA 9.
44 execute_process(
45 COMMAND ${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER} ${ARGN}
46 --cuda-gpu-arch=sm_35 -c ${srcfile} -o ${bcfile}
47 RESULT_VARIABLE result
48 OUTPUT_QUIET ERROR_QUIET)
49 if (result EQUAL 0)
50 set(${output} TRUE PARENT_SCOPE)
51 else()
52 set(${output} FALSE PARENT_SCOPE)
53 endif()
54endfunction()
55
56# Save for which compiler we are going to do the following checks so that we
57# can discard cached values if the user specifies a different value.
58set(discard_cached FALSE)
59if (DEFINED LIBOMPTARGET_NVPTX_CHECKED_CUDA_COMPILER AND
60 NOT("${LIBOMPTARGET_NVPTX_CHECKED_CUDA_COMPILER}" STREQUAL "${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER}"))
61 set(discard_cached TRUE)
62endif()
63set(LIBOMPTARGET_NVPTX_CHECKED_CUDA_COMPILER "${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER}" CACHE INTERNAL "" FORCE)
64
65function(check_bitcode_compilation output source)
66 if (${discard_cached} OR NOT DEFINED ${output})
67 message(STATUS "Performing Test ${output}")
68 # Forward additional arguments which contain the flags.
69 try_compile_bitcode(result "${source}" ${ARGN})
70 set(${output} ${result} CACHE INTERNAL "" FORCE)
71 if(${result})
72 message(STATUS "Performing Test ${output} - Success")
73 else()
74 message(STATUS "Performing Test ${output} - Failed")
75 endif()
76 endif()
77endfunction()
78
79# These flags are required to emit LLVM Bitcode. We check them together because
80# if any of them are not supported, there is no point in finding out which are.
Johannes Doerfert3ff4e2e2020-02-11 17:08:48 -060081set(compiler_flags_required -emit-llvm -O1 --cuda-device-only -std=c++14 --cuda-path=${CUDA_TOOLKIT_ROOT_DIR})
Jonas Hahnfeld37bbe1a2018-05-16 17:20:21 +000082set(compiler_flags_required_src "extern \"C\" __device__ int thread() { return threadIdx.x; }")
83check_bitcode_compilation(LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_FLAGS_REQUIRED "${compiler_flags_required_src}" ${compiler_flags_required})
84
85# It makes no sense to continue given that the compiler doesn't support
86# emitting basic LLVM Bitcode
87if (NOT LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_FLAGS_REQUIRED)
88 return()
89endif()
90
91set(LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER_FLAGS ${compiler_flags_required})
92
93# Declaring external shared device variables might need an additional flag
94# since Clang 7.0 and was entirely unsupported since version 4.0.
95set(extern_device_shared_src "extern __device__ __shared__ int test;")
96
97check_bitcode_compilation(LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_EXTERN_SHARED "${extern_device_shared_src}" ${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER_FLAGS})
98if (NOT LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_EXTERN_SHARED)
99 set(compiler_flag_fcuda_rdc -fcuda-rdc)
100 set(compiler_flag_fcuda_rdc_full ${LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER_FLAGS} ${compiler_flag_fcuda_rdc})
101 check_bitcode_compilation(LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_FCUDA_RDC "${extern_device_shared_src}" ${compiler_flag_fcuda_rdc_full})
102
103 if (NOT LIBOMPTARGET_NVPTX_CUDA_COMPILER_SUPPORTS_FCUDA_RDC)
104 return()
105 endif()
106
107 set(LIBOMPTARGET_NVPTX_SELECTED_CUDA_COMPILER_FLAGS "${compiler_flag_fcuda_rdc_full}")
108endif()
109
110# We can compile LLVM Bitcode from CUDA source code!
111set(LIBOMPTARGET_NVPTX_BCLIB_SUPPORTED TRUE)