1 cmake_minimum_required(VERSION 3.20.0)
3 project( libclc VERSION 0.2.0 LANGUAGES CXX C)
5 set(CMAKE_CXX_STANDARD 17)
7 include( GNUInstallDirs )
8 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
9 amdgcn-amdhsa/lib/SOURCES;
11 amdgcn-mesa3d/lib/SOURCES;
17 ptx-nvidiacl/lib/SOURCES;
24 set( LIBCLC_TARGETS_ALL
38 set( LIBCLC_MIN_LLVM "3.9.0" )
40 set( LIBCLC_TARGETS_TO_BUILD "all"
41 CACHE STRING "Semicolon-separated list of targets to build, or 'all'." )
43 option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support."
46 find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}")
49 message( "LLVM version: ${LLVM_PACKAGE_VERSION}" )
51 if( ${LLVM_PACKAGE_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} )
52 message( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM}" )
55 # mesa3d environment is only available since LLVM 4.0
56 if( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.9.0" )
57 set( LIBCLC_TARGETS_ALL ${LIBCLC_TARGETS_ALL} amdgcn-mesa-mesa3d )
60 if( LIBCLC_TARGETS_TO_BUILD STREQUAL "all" )
61 set( LIBCLC_TARGETS_TO_BUILD ${LIBCLC_TARGETS_ALL} )
64 find_program( LLVM_CLANG clang PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
65 find_program( LLVM_AS llvm-as PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
66 find_program( LLVM_LINK llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
67 find_program( LLVM_OPT opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
68 find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
71 message( "clang: ${LLVM_CLANG}" )
72 message( "llvm-as: ${LLVM_AS}" )
73 message( "llvm-link: ${LLVM_LINK}" )
74 message( "opt: ${LLVM_OPT}" )
75 message( "llvm-spirv: ${LLVM_SPIRV}" )
77 if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK )
78 message( FATAL_ERROR "toolchain incomplete!" )
81 list( SORT LIBCLC_TARGETS_TO_BUILD )
83 if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD )
85 message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
89 set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake )
90 set( CMAKE_CLC_COMPILER ${LLVM_CLANG} )
91 set( CMAKE_CLC_ARCHIVE ${LLVM_LINK} )
92 set( CMAKE_LLAsm_PREPROCESSOR ${LLVM_CLANG} )
93 set( CMAKE_LLAsm_COMPILER ${LLVM_AS} )
94 set( CMAKE_LLAsm_ARCHIVE ${LLVM_LINK} )
96 # Construct LLVM version define
97 set( LLVM_VERSION_DEFINE "-DHAVE_LLVM=0x${LLVM_VERSION_MAJOR}0${LLVM_VERSION_MINOR}" )
100 # LLVM 13 enables standard includes by default
101 if( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "12.99.99" )
102 set( CMAKE_LLAsm_FLAGS "${CMAKE_LLAsm_FLAGS} -cl-no-stdinc")
103 set( CMAKE_CLC_FLAGS "${CMAKE_CLC_FLAGS} -cl-no-stdinc")
106 enable_language( CLC LLAsm )
107 # This needs to be set before any target that needs it
108 # We need to use LLVM_INCLUDE_DIRS here, because if we are linking to an
109 # llvm build directory, this includes $src/llvm/include which is where all the
110 # headers are not $build/include/ which is what LLVM_INCLUDE_DIR is set to.
111 include_directories( ${LLVM_INCLUDE_DIRS} )
113 # Setup prepare_builtins tools
114 set(LLVM_LINK_COMPONENTS
120 add_llvm_executable( prepare_builtins utils/prepare-builtins.cpp )
121 target_compile_definitions( prepare_builtins PRIVATE ${LLVM_VERSION_DEFINE} )
122 # These were not properly reported in early LLVM and we don't need them
123 target_compile_options( prepare_builtins PRIVATE -fno-rtti -fno-exceptions )
126 set( r600--_devices cedar cypress barts cayman )
127 set( amdgcn--_devices tahiti )
128 set( amdgcn-mesa-mesa3d_devices ${amdgcn--_devices} )
129 set( amdgcn--amdhsa_devices none )
130 set( clspv--_devices none )
131 set( clspv64--_devices none )
132 set( nvptx--_devices none )
133 set( nvptx64--_devices none )
134 set( nvptx--nvidiacl_devices none )
135 set( nvptx64--nvidiacl_devices none )
136 set( spirv-mesa3d-_devices none )
137 set( spirv64-mesa3d-_devices none )
140 set( cedar_aliases palm sumo sumo2 redwood juniper )
141 set( cypress_aliases hemlock )
142 set( barts_aliases turks caicos )
143 set( cayman_aliases aruba )
144 set( tahiti_aliases pitcairn verde oland hainan bonaire kabini kaveri hawaii
145 mullins tonga tongapro iceland carrizo fiji stoney polaris10 polaris11
147 gfx900 gfx902 gfx904 gfx906 gfx908 gfx909 gfx90a gfx90c gfx940 gfx941 gfx942
148 gfx1010 gfx1011 gfx1012 gfx1013
149 gfx1030 gfx1031 gfx1032 gfx1033 gfx1034 gfx1035 gfx1036
150 gfx1100 gfx1101 gfx1102 gfx1103
156 configure_file( libclc.pc.in libclc.pc @ONLY )
157 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libclc.pc DESTINATION "${CMAKE_INSTALL_DATADIR}/pkgconfig" )
158 install( DIRECTORY generic/include/clc DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" )
160 if( ENABLE_RUNTIME_SUBNORMAL )
161 add_library( subnormal_use_default STATIC
162 generic/lib/subnormal_use_default.ll )
163 add_library( subnormal_disable STATIC
164 generic/lib/subnormal_disable.ll )
165 install( TARGETS subnormal_use_default subnormal_disable ARCHIVE
166 DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
169 find_package( Python3 REQUIRED COMPONENTS Interpreter )
170 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/generic/lib/gen_convert.py script_loc )
173 COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl
174 DEPENDS ${script_loc} )
175 add_custom_target( "generate_convert.cl" DEPENDS convert.cl )
179 foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
180 message( "BUILDING ${t}" )
181 string( REPLACE "-" ";" TRIPLE ${t} )
182 list( GET TRIPLE 0 ARCH )
183 list( GET TRIPLE 1 VENDOR )
184 list( GET TRIPLE 2 OS )
188 if ( NOT ${ARCH} STREQUAL spirv AND NOT ${ARCH} STREQUAL spirv64 AND
189 NOT ${ARCH} STREQUAL clspv AND NOT ${ARCH} STREQUAL clspv64)
190 LIST( APPEND dirs generic )
193 if( ${ARCH} STREQUAL r600 OR ${ARCH} STREQUAL amdgcn )
194 list( APPEND dirs amdgpu )
198 if( ${ARCH} STREQUAL nvptx OR ${ARCH} STREQUAL nvptx64 )
204 # Enumerate SOURCES* files
206 foreach( l ${dirs} ${DARCH} ${DARCH}-${OS} ${DARCH}-${VENDOR}-${OS} )
207 foreach( s "SOURCES" "SOURCES_${LLVM_MAJOR}.${LLVM_MINOR}" )
208 file( TO_CMAKE_PATH ${l}/lib/${s} file_loc )
209 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${file_loc} loc )
210 # Prepend the location to give higher priority to
211 # specialized implementation
213 set( source_list ${file_loc} ${source_list} )
218 # Add the generated convert.cl here to prevent adding
219 # the one listed in SOURCES
220 if( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" )
221 set( rel_files convert.cl )
222 set( objects convert.cl )
223 if( NOT ENABLE_RUNTIME_SUBNORMAL AND NOT ${ARCH} STREQUAL "clspv" AND
224 NOT ${ARCH} STREQUAL "clspv64" )
225 list( APPEND rel_files generic/lib/subnormal_use_default.ll )
232 foreach( l ${source_list} )
233 file( READ ${l} file_list )
234 string( REPLACE "\n" ";" file_list ${file_list} )
235 get_filename_component( dir ${l} DIRECTORY )
236 foreach( f ${file_list} )
237 list( FIND objects ${f} found )
239 list( APPEND objects ${f} )
240 list( APPEND rel_files ${dir}/${f} )
241 # FIXME: This should really go away
242 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${dir}/${f} src_loc )
243 get_filename_component( fdir ${src_loc} DIRECTORY )
245 set_source_files_properties( ${dir}/${f}
246 PROPERTIES COMPILE_FLAGS "-I ${fdir}" )
251 foreach( d ${${t}_devices} )
252 # Some targets don't have a specific GPU to target
253 if( ${d} STREQUAL "none" OR ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
255 set( arch_suffix "${t}" )
257 set( mcpu "-mcpu=${d}" )
258 set( arch_suffix "${d}-${t}" )
260 message( " DEVICE: ${d} ( ${${d}_aliases} )" )
262 if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
263 if( ${ARCH} STREQUAL "spirv" )
268 set( build_flags -O0 -finline-hint-functions )
270 set( spvflags --spirv-max-version=1.1 )
271 elseif( ${ARCH} STREQUAL "clspv" )
273 set( build_flags "-Wno-unknown-assumption")
275 elseif( ${ARCH} STREQUAL "clspv64" )
277 set( build_flags "-Wno-unknown-assumption")
284 add_library( builtins.link.${arch_suffix} STATIC ${rel_files} )
285 # Make sure we depend on the pseudo target to prevent
286 # multiple invocations
287 add_dependencies( builtins.link.${arch_suffix}
288 generate_convert.cl )
289 # CMake will turn this include into absolute path
290 target_include_directories( builtins.link.${arch_suffix} PRIVATE
292 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
294 string( TOUPPER "-DCLC_${ARCH}" CLC_TARGET_DEFINE )
295 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
296 ${CLC_TARGET_DEFINE} )
297 target_compile_options( builtins.link.${arch_suffix} PRIVATE -target
298 ${t} ${mcpu} -fno-builtin -nostdlib ${build_flags} )
299 set_target_properties( builtins.link.${arch_suffix} PROPERTIES
300 LINKER_LANGUAGE CLC )
302 set( obj_suffix ${arch_suffix}.bc )
305 add_custom_command( OUTPUT "builtins.opt.${obj_suffix}"
306 COMMAND ${LLVM_OPT} ${opt_flags} -o
307 "builtins.opt.${obj_suffix}"
308 "builtins.link.${obj_suffix}"
309 DEPENDS "builtins.link.${arch_suffix}" )
310 add_custom_target( "opt.${obj_suffix}" ALL
311 DEPENDS "builtins.opt.${obj_suffix}" )
313 if( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
314 set( spv_suffix ${arch_suffix}.spv )
315 add_custom_command( OUTPUT "${spv_suffix}"
316 COMMAND ${LLVM_SPIRV} ${spvflags}
318 "builtins.link.${obj_suffix}"
319 DEPENDS "builtins.link.${arch_suffix}" )
320 add_custom_target( "prepare-${spv_suffix}" ALL
321 DEPENDS "${spv_suffix}" )
322 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${spv_suffix}
323 DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
327 add_custom_command( OUTPUT "${obj_suffix}"
328 COMMAND prepare_builtins -o
330 "builtins.opt.${obj_suffix}"
331 DEPENDS "opt.${obj_suffix}"
332 "builtins.opt.${obj_suffix}"
334 add_custom_target( "prepare-${obj_suffix}" ALL
335 DEPENDS "${obj_suffix}" )
337 # nvptx-- targets don't include workitem builtins
338 if( NOT ${t} MATCHES ".*ptx.*--$" )
339 add_test( NAME external-calls-${obj_suffix}
340 COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} ${LLVM_TOOLS_BINARY_DIR}
341 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} )
344 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
345 foreach( a ${${d}_aliases} )
346 set( alias_suffix "${a}-${t}.bc" )
347 add_custom_target( ${alias_suffix} ALL
348 COMMAND ${CMAKE_COMMAND} -E
349 create_symlink ${obj_suffix}
351 DEPENDS "prepare-${obj_suffix}" )
352 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${alias_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )