1 cmake_minimum_required(VERSION 3.13.4)
3 project( libclc VERSION 0.2.0 LANGUAGES CXX )
4 include( GNUInstallDirs )
5 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
6 amdgcn-amdhsa/lib/SOURCES;
8 amdgcn-mesa3d/lib/SOURCES;
13 ptx-nvidiacl/lib/SOURCES;
20 set( LIBCLC_TARGETS_ALL
33 set( LIBCLC_MIN_LLVM "3.9.0" )
35 set( LIBCLC_TARGETS_TO_BUILD "all"
36 CACHE STRING "Semicolon-separated list of targets to build, or 'all'." )
38 option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support."
42 find_program( LLVM_CONFIG llvm-config )
44 execute_process( COMMAND ${LLVM_CONFIG} "--version"
45 OUTPUT_VARIABLE LLVM_VERSION
46 OUTPUT_STRIP_TRAILING_WHITESPACE )
47 message( "LLVM version: ${LLVM_VERSION}" )
49 if( ${LLVM_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} )
50 message( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM}" )
53 # mesa3d environment is only available since LLVM 4.0
54 if( ${LLVM_VERSION} VERSION_GREATER "3.9.0" )
55 set( LIBCLC_TARGETS_ALL ${LIBCLC_TARGETS_ALL} amdgcn-mesa-mesa3d )
58 if( LIBCLC_TARGETS_TO_BUILD STREQUAL "all" )
59 set( LIBCLC_TARGETS_TO_BUILD ${LIBCLC_TARGETS_ALL} )
62 execute_process( COMMAND ${LLVM_CONFIG} "--system-libs"
63 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS
64 OUTPUT_STRIP_TRAILING_WHITESPACE )
65 separate_arguments( LLVM_SYSTEM_LIBS )
66 execute_process( COMMAND ${LLVM_CONFIG} "--libs" "core" "bitreader" "bitwriter"
67 OUTPUT_VARIABLE LLVM_LIBS
68 OUTPUT_STRIP_TRAILING_WHITESPACE )
69 separate_arguments( LLVM_LIBS )
70 execute_process( COMMAND ${LLVM_CONFIG} "--libdir"
71 OUTPUT_VARIABLE LLVM_LIBDIR
72 OUTPUT_STRIP_TRAILING_WHITESPACE )
73 execute_process( COMMAND ${LLVM_CONFIG} "--ldflags"
74 OUTPUT_VARIABLE LLVM_LD_FLAGS
75 OUTPUT_STRIP_TRAILING_WHITESPACE )
76 execute_process( COMMAND ${LLVM_CONFIG} "--cxxflags"
77 OUTPUT_VARIABLE LLVM_CXX_FLAGS
78 OUTPUT_STRIP_TRAILING_WHITESPACE )
79 separate_arguments( LLVM_CXX_FLAGS )
80 execute_process( COMMAND ${LLVM_CONFIG} "--bindir"
81 OUTPUT_VARIABLE LLVM_BINDIR
82 OUTPUT_STRIP_TRAILING_WHITESPACE )
84 # These were not properly reported in early LLVM and we don't need them
85 list( APPEND LLVM_CXX_FLAGS -fno-rtti -fno-exceptions )
87 # Print LLVM variables
88 message( "LLVM system libs: ${LLVM_SYSTEM_LIBS}" )
89 message( "LLVM libs: ${LLVM_LIBS}" )
90 message( "LLVM libdir: ${LLVM_LIBDIR}" )
91 message( "LLVM bindir: ${LLVM_BINDIR}" )
92 message( "LLVM ld flags: ${LLVM_LD_FLAGS}" )
93 message( "LLVM cxx flags: ${LLVM_CXX_FLAGS}" )
96 find_program( LLVM_CLANG clang PATHS ${LLVM_BINDIR} NO_DEFAULT_PATH )
97 find_program( LLVM_AS llvm-as PATHS ${LLVM_BINDIR} NO_DEFAULT_PATH )
98 find_program( LLVM_LINK llvm-link PATHS ${LLVM_BINDIR} NO_DEFAULT_PATH )
99 find_program( LLVM_OPT opt PATHS ${LLVM_BINDIR} NO_DEFAULT_PATH )
100 find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_BINDIR} NO_DEFAULT_PATH )
103 message( "clang: ${LLVM_CLANG}" )
104 message( "llvm-as: ${LLVM_AS}" )
105 message( "llvm-link: ${LLVM_LINK}" )
106 message( "opt: ${LLVM_OPT}" )
107 message( "llvm-spirv: ${LLVM_SPIRV}" )
109 if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK )
110 message( FATAL_ERROR "toolchain incomplete!" )
113 list( SORT LIBCLC_TARGETS_TO_BUILD )
115 if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD )
117 message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
121 set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake )
122 set( CMAKE_CLC_COMPILER ${LLVM_CLANG} )
123 set( CMAKE_CLC_ARCHIVE ${LLVM_LINK} )
124 set( CMAKE_LLAsm_PREPROCESSOR ${LLVM_CLANG} )
125 set( CMAKE_LLAsm_COMPILER ${LLVM_AS} )
126 set( CMAKE_LLAsm_ARCHIVE ${LLVM_LINK} )
128 # Construct LLVM version define
129 string( REPLACE "." ";" LLVM_VERSION_LIST ${LLVM_VERSION} )
130 list( GET LLVM_VERSION_LIST 0 LLVM_MAJOR )
131 list( GET LLVM_VERSION_LIST 1 LLVM_MINOR )
132 set( LLVM_VERSION_DEFINE "-DHAVE_LLVM=0x${LLVM_MAJOR}0${LLVM_MINOR}" )
135 # LLVM 13 enables standard includes by default
136 if( ${LLVM_VERSION} VERSION_GREATER "12.99.99" )
137 set( CMAKE_LLAsm_FLAGS ${CMAKE_LLAsm_FLAGS} -cl-no-stdinc )
138 set( CMAKE_CLC_FLAGS ${CMAKE_CLC_FLAGS} -cl-no-stdinc )
141 enable_language( CLC LLAsm )
143 # This needs to be set before any target that needs it
144 link_directories( ${LLVM_LIBDIR} )
146 # Setup prepare_builtins tools
147 add_executable( prepare_builtins utils/prepare-builtins.cpp )
148 target_compile_options( prepare_builtins PRIVATE ${LLVM_CXX_FLAGS} )
149 target_compile_definitions( prepare_builtins PRIVATE ${LLVM_VERSION_DEFINE} )
150 target_link_libraries( prepare_builtins PRIVATE ${LLVM_LIBS} )
151 target_link_libraries( prepare_builtins PRIVATE ${LLVM_SYSTEM_LIBS} )
154 set( r600--_devices cedar cypress barts cayman )
155 set( amdgcn--_devices tahiti )
156 set( amdgcn-mesa-mesa3d_devices ${amdgcn--_devices} )
157 set( amdgcn--amdhsa_devices none )
158 set( clspv--_devices none )
159 set( nvptx--_devices none )
160 set( nvptx64--_devices none )
161 set( nvptx--nvidiacl_devices none )
162 set( nvptx64--nvidiacl_devices none )
163 set( spirv-mesa3d-_devices none )
164 set( spirv64-mesa3d-_devices none )
167 set( cedar_aliases palm sumo sumo2 redwood juniper )
168 set( cypress_aliases hemlock )
169 set( barts_aliases turks caicos )
170 set( cayman_aliases aruba )
171 set( tahiti_aliases pitcairn verde oland hainan bonaire kabini kaveri hawaii
172 mullins tonga iceland carrizo fiji stoney polaris10 polaris11 )
174 # Support for gfx9 was added in LLVM 5.0 (r295554)
175 if( ${LLVM_VERSION} VERSION_GREATER "4.99.99" )
176 set( tahiti_aliases ${tahiti_aliases} gfx900 gfx902 )
179 # Support for Vega12 and Vega20 was added in LLVM 7 (r331215)
180 if( ${LLVM_VERSION} VERSION_GREATER "6.99.99" )
181 set( tahiti_aliases ${tahiti_aliases} gfx904 gfx906 )
185 configure_file( libclc.pc.in libclc.pc @ONLY )
186 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libclc.pc DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig )
187 install( DIRECTORY generic/include/clc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
189 if( ENABLE_RUNTIME_SUBNORMAL )
190 add_library( subnormal_use_default STATIC
191 generic/lib/subnormal_use_default.ll )
192 add_library( subnormal_disable STATIC
193 generic/lib/subnormal_disable.ll )
194 install( TARGETS subnormal_use_default subnormal_disable ARCHIVE
195 DESTINATION ${CMAKE_INSTALL_DATADIR}/clc )
198 find_package( Python3 REQUIRED COMPONENTS Interpreter )
199 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/generic/lib/gen_convert.py script_loc )
202 COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl
203 DEPENDS ${script_loc} )
204 add_custom_target( "generate_convert.cl" DEPENDS convert.cl )
208 foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
209 message( "BUILDING ${t}" )
210 string( REPLACE "-" ";" TRIPLE ${t} )
211 list( GET TRIPLE 0 ARCH )
212 list( GET TRIPLE 1 VENDOR )
213 list( GET TRIPLE 2 OS )
217 if ( NOT ${ARCH} STREQUAL spirv AND NOT ${ARCH} STREQUAL spirv64 AND NOT ${ARCH} STREQUAL clspv )
218 LIST( APPEND dirs generic )
221 if( ${ARCH} STREQUAL r600 OR ${ARCH} STREQUAL amdgcn )
222 list( APPEND dirs amdgpu )
226 if( ${ARCH} STREQUAL nvptx OR ${ARCH} STREQUAL nvptx64 )
232 # Enumerate SOURCES* files
234 foreach( l ${dirs} ${DARCH} ${DARCH}-${OS} ${DARCH}-${VENDOR}-${OS} )
235 foreach( s "SOURCES" "SOURCES_${LLVM_MAJOR}.${LLVM_MINOR}" )
236 file( TO_CMAKE_PATH ${l}/lib/${s} file_loc )
237 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${file_loc} loc )
238 # Prepend the location to give higher priority to
239 # specialized implementation
241 set( source_list ${file_loc} ${source_list} )
246 # Add the generated convert.cl here to prevent adding
247 # the one listed in SOURCES
248 if( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" AND NOT ${ARCH} STREQUAL "clspv" )
249 set( rel_files convert.cl )
250 set( objects convert.cl )
251 if( NOT ENABLE_RUNTIME_SUBNORMAL )
252 list( APPEND rel_files generic/lib/subnormal_use_default.ll )
259 foreach( l ${source_list} )
260 file( READ ${l} file_list )
261 string( REPLACE "\n" ";" file_list ${file_list} )
262 get_filename_component( dir ${l} DIRECTORY )
263 foreach( f ${file_list} )
264 list( FIND objects ${f} found )
266 list( APPEND objects ${f} )
267 list( APPEND rel_files ${dir}/${f} )
268 # FIXME: This should really go away
269 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${dir}/${f} src_loc )
270 get_filename_component( fdir ${src_loc} DIRECTORY )
272 set_source_files_properties( ${dir}/${f}
273 PROPERTIES COMPILE_FLAGS "-I ${fdir}" )
278 foreach( d ${${t}_devices} )
279 # Some targets don't have a specific GPU to target
280 if( ${d} STREQUAL "none" OR ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
282 set( arch_suffix "${t}" )
284 set( mcpu "-mcpu=${d}" )
285 set( arch_suffix "${d}-${t}" )
287 message( " DEVICE: ${d} ( ${${d}_aliases} )" )
289 if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
290 if( ${ARCH} STREQUAL "spirv" )
295 set( build_flags -O0 -finline-hint-functions )
297 set( spvflags --spirv-max-version=1.1 )
298 elseif( ${ARCH} STREQUAL "clspv" )
307 add_library( builtins.link.${arch_suffix} STATIC ${rel_files} )
308 # Make sure we depend on the pseudo target to prevent
309 # multiple invocations
310 add_dependencies( builtins.link.${arch_suffix}
311 generate_convert.cl )
312 # CMake will turn this include into absolute path
313 target_include_directories( builtins.link.${arch_suffix} PRIVATE
315 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
317 string( TOUPPER "-DCLC_${ARCH}" CLC_TARGET_DEFINE )
318 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
319 ${CLC_TARGET_DEFINE} )
320 target_compile_options( builtins.link.${arch_suffix} PRIVATE -target
321 ${t} ${mcpu} -fno-builtin -nostdlib ${build_flags} )
322 set_target_properties( builtins.link.${arch_suffix} PROPERTIES
323 LINKER_LANGUAGE CLC )
325 set( obj_suffix ${arch_suffix}.bc )
328 add_custom_command( OUTPUT "builtins.opt.${obj_suffix}"
329 COMMAND ${LLVM_OPT} ${opt_flags} -o
330 "builtins.opt.${obj_suffix}"
331 "builtins.link.${obj_suffix}"
332 DEPENDS "builtins.link.${arch_suffix}" )
333 add_custom_target( "opt.${obj_suffix}" ALL
334 DEPENDS "builtins.opt.${obj_suffix}" )
336 if( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
337 set( spv_suffix ${arch_suffix}.spv )
338 add_custom_command( OUTPUT "${spv_suffix}"
339 COMMAND ${LLVM_SPIRV} ${spvflags}
341 "builtins.link.${obj_suffix}"
342 DEPENDS "builtins.link.${arch_suffix}" )
343 add_custom_target( "prepare-${spv_suffix}" ALL
344 DEPENDS "${spv_suffix}" )
345 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${spv_suffix}
346 DESTINATION ${CMAKE_INSTALL_DATADIR}/clc )
350 add_custom_command( OUTPUT "${obj_suffix}"
351 COMMAND prepare_builtins -o
353 "builtins.opt.${obj_suffix}"
354 DEPENDS "opt.${obj_suffix}"
355 "builtins.opt.${obj_suffix}"
357 add_custom_target( "prepare-${obj_suffix}" ALL
358 DEPENDS "${obj_suffix}" )
360 # nvptx-- targets don't include workitem builtins
361 if( NOT ${t} MATCHES ".*ptx.*--$" )
362 add_test( NAME external-calls-${obj_suffix}
363 COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix}
364 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} )
365 set_tests_properties( external-calls-${obj_suffix}
366 PROPERTIES ENVIRONMENT "LLVM_CONFIG=${LLVM_CONFIG}" )
369 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} DESTINATION ${CMAKE_INSTALL_DATADIR}/clc )
370 foreach( a ${${d}_aliases} )
371 set( alias_suffix "${a}-${t}.bc" )
372 add_custom_target( ${alias_suffix} ALL
373 COMMAND ${CMAKE_COMMAND} -E
374 create_symlink ${obj_suffix}
376 DEPENDS "prepare-${obj_suffix}" )
377 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${alias_suffix} DESTINATION ${CMAKE_INSTALL_DATADIR}/clc )