[bazel build] (manually) port da47ec3ca076
[llvm-project.git] / libclc / CMakeLists.txt
blobec39ea63f2d0287f05d350a68e3d266c5865df5f
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;
7   amdgcn/lib/SOURCES;
8   amdgcn-mesa3d/lib/SOURCES;
9   amdgpu/lib/SOURCES;
10   clspv/lib/SOURCES;
11   generic/lib/SOURCES;
12   ptx/lib/SOURCES;
13   ptx-nvidiacl/lib/SOURCES;
14   r600/lib/SOURCES;
15   spirv/lib/SOURCES;
16   spirv64/lib/SOURCES
19 # List of all targets
20 set( LIBCLC_TARGETS_ALL
21   amdgcn--
22   amdgcn--amdhsa
23   clspv--
24   r600--
25   nvptx--
26   nvptx64--
27   nvptx--nvidiacl
28   nvptx64--nvidiacl
29   spirv-mesa3d-
30   spirv64-mesa3d-
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."
39 OFF )
41 if( NOT LLVM_CONFIG )
42         find_program( LLVM_CONFIG llvm-config )
43 endif()
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}" )
51 endif()
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 )
56 endif()
58 if( LIBCLC_TARGETS_TO_BUILD STREQUAL "all" )
59         set( LIBCLC_TARGETS_TO_BUILD ${LIBCLC_TARGETS_ALL} )
60 endif()
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}" )
94 message( "" )
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 )
102 # Print toolchain
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}" )
108 message( "" )
109 if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK )
110         message( FATAL_ERROR "toolchain incomplete!" )
111 endif()
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 )
116         if( NOT LLVM_SPIRV )
117                 message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
118         endif()
119 endif()
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 )
139 endif()
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} )
153 # Setup arch devices
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 )
166 # Setup aliases
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 )
177 endif()
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 )
182 endif()
184 # pkg-config file
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 )
196 endif()
198 find_package( Python3 REQUIRED COMPONENTS Interpreter )
199 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/generic/lib/gen_convert.py script_loc )
200 add_custom_command(
201         OUTPUT convert.cl
202         COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl
203         DEPENDS ${script_loc} )
204 add_custom_target( "generate_convert.cl" DEPENDS convert.cl )
206 enable_testing()
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 )
215         set( dirs )
217         if ( NOT ${ARCH} STREQUAL spirv AND NOT ${ARCH} STREQUAL spirv64 AND NOT ${ARCH} STREQUAL clspv )
218                 LIST( APPEND dirs generic )
219         endif()
221         if( ${ARCH} STREQUAL r600 OR ${ARCH} STREQUAL amdgcn )
222                 list( APPEND dirs amdgpu )
223         endif()
225         #nvptx is special
226         if( ${ARCH} STREQUAL nvptx OR ${ARCH} STREQUAL nvptx64 )
227                 set( DARCH ptx )
228         else()
229                 set( DARCH ${ARCH} )
230         endif()
232         # Enumerate SOURCES* files
233         set( source_list )
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
240                         if( EXISTS ${loc} )
241                                 set( source_list ${file_loc} ${source_list} )
242                         endif()
243                 endforeach()
244         endforeach()
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 )
253                 endif()
254         else()
255                 set( rel_files )
256                 set( objects )
257         endif()
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 )
265                         if( found EQUAL  -1 )
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}" )
274                         endif()
275                 endforeach()
276         endforeach()
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" )
281                         set( mcpu )
282                         set( arch_suffix "${t}" )
283                 else()
284                         set( mcpu "-mcpu=${d}" )
285                         set( arch_suffix "${d}-${t}" )
286                 endif()
287                 message( "      DEVICE: ${d} ( ${${d}_aliases} )" )
289                 if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
290                         if( ${ARCH} STREQUAL "spirv" )
291                                 set( t "spir--" )
292                         else()
293                                 set( t "spir64--" )
294                         endif()
295                         set( build_flags -O0 -finline-hint-functions )
296                         set( opt_flags )
297                         set( spvflags --spirv-max-version=1.1 )
298                 elseif( ${ARCH} STREQUAL "clspv" )
299                         set( t "spir--" )
300                         set( build_flags )
301                         set( opt_flags -O3 )
302                 else()
303                         set( build_flags )
304                         set( opt_flags -O3 )
305                 endif()
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
314                         "generic/include" )
315                 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
316                         "__CLC_INTERNAL" )
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 )
327                 # Add opt target
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}
340                                             -o "${spv_suffix}"
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 )
347                 else()
349                         # Add prepare target
350                         add_custom_command( OUTPUT "${obj_suffix}"
351                                             COMMAND prepare_builtins -o
352                                             "${obj_suffix}"
353                                             "builtins.opt.${obj_suffix}"
354                                             DEPENDS "opt.${obj_suffix}"
355                                                     "builtins.opt.${obj_suffix}"
356                                                     prepare_builtins )
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}" )
367                         endif()
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}
375                                                    ${alias_suffix}
376                                                    DEPENDS "prepare-${obj_suffix}" )
377                                 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${alias_suffix} DESTINATION ${CMAKE_INSTALL_DATADIR}/clc )
378                         endforeach( a )
379                 endif()
380         endforeach( d )
381 endforeach( t )