@@ -4,6 +4,15 @@ project( libclc VERSION 0.2.0 LANGUAGES CXX C)
4
4
5
5
set (CMAKE_CXX_STANDARD 17 )
6
6
7
+ # Add path for custom modules
8
+ list ( INSERT CMAKE_MODULE_PATH 0 "${PROJECT_SOURCE_DIR} /cmake/modules" )
9
+
10
+ set ( LIBCLC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
11
+ set ( LIBCLC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
12
+ set ( LIBCLC_OBJFILE_DIR ${LIBCLC_BINARY_DIR} /obj.libclc.dir )
13
+
14
+ include ( AddLibclc )
15
+
7
16
include ( GNUInstallDirs )
8
17
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
9
18
amdgcn-amdhsa/lib/SOURCES;
@@ -27,31 +36,51 @@ set( LIBCLC_TARGETS_TO_BUILD "all"
27
36
28
37
option ( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support." OFF )
29
38
30
- find_package (LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR} " )
31
- include (AddLLVM )
39
+ if ( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
40
+ # Out-of-tree configuration
41
+ set ( LIBCLC_STANDALONE_BUILD TRUE )
32
42
33
- message ( STATUS "libclc LLVM version: ${LLVM_PACKAGE_VERSION} " )
43
+ find_package (LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR} " )
44
+ include (AddLLVM )
34
45
35
- if ( LLVM_PACKAGE_VERSION VERSION_LESS LIBCLC_MIN_LLVM )
36
- message ( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM} " )
37
- endif ()
46
+ message ( STATUS "libclc LLVM version: ${LLVM_PACKAGE_VERSION} " )
38
47
39
- find_program ( LLVM_CLANG clang PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
40
- find_program ( LLVM_AS llvm-as PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
41
- find_program ( LLVM_LINK llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
42
- find_program ( LLVM_OPT opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
43
- find_program ( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
48
+ if ( LLVM_PACKAGE_VERSION VERSION_LESS LIBCLC_MIN_LLVM )
49
+ message ( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM} " )
50
+ endif ()
51
+
52
+ # Import required tools as targets
53
+ foreach ( tool clang llvm-as llvm-link opt )
54
+ find_program ( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
55
+ add_executable ( libclc::${tool} IMPORTED GLOBAL )
56
+ set_target_properties ( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} )
57
+ endforeach ()
58
+ else ()
59
+ # In-tree configuration
60
+ set ( LIBCLC_STANDALONE_BUILD FALSE )
61
+
62
+ set ( LLVM_PACKAGE_VERSION ${LLVM_VERSION} )
44
63
45
- # Print toolchain
46
- message ( STATUS "libclc toolchain - clang: ${LLVM_CLANG} " )
47
- message ( STATUS "libclc toolchain - llvm-as: ${LLVM_AS} " )
48
- message ( STATUS "libclc toolchain - llvm-link: ${LLVM_LINK} " )
49
- message ( STATUS "libclc toolchain - opt: ${LLVM_OPT} " )
50
- message ( STATUS "libclc toolchain - llvm-spirv: ${LLVM_SPIRV} " )
51
- if ( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK )
64
+ # Note that we check this later (for both build types) but we can provide a
65
+ # more useful error message when built in-tree. We assume that LLVM tools are
66
+ # always available so don't warn here.
67
+ if ( NOT clang IN_LIST LLVM_ENABLE_PROJECTS )
68
+ message (FATAL_ERROR "Clang is not enabled, but is required to build libclc in-tree" )
69
+ endif ()
70
+
71
+ foreach ( tool clang llvm-as llvm-link opt )
72
+ add_executable (libclc::${tool} ALIAS ${tool} )
73
+ endforeach ()
74
+ endif ()
75
+
76
+ if ( NOT TARGET libclc::clang OR NOT TARGET libclc::opt
77
+ OR NOT TARGET libclc::llvm-as OR NOT TARGET libclc::llvm-link )
52
78
message ( FATAL_ERROR "libclc toolchain incomplete!" )
53
79
endif ()
54
80
81
+ # llvm-spirv is an optional dependency, used to build spirv-* targets.
82
+ find_program ( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
83
+
55
84
# List of all targets. Note that some are added dynamically below.
56
85
set ( LIBCLC_TARGETS_ALL
57
86
amdgcn--
@@ -90,24 +119,9 @@ if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST
90
119
endif ()
91
120
endif ()
92
121
93
- set ( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR} /cmake )
94
- set ( CMAKE_CLC_COMPILER ${LLVM_CLANG} )
95
- set ( CMAKE_CLC_ARCHIVE ${LLVM_LINK} )
96
- set ( CMAKE_LLAsm_PREPROCESSOR ${LLVM_CLANG} )
97
- set ( CMAKE_LLAsm_COMPILER ${LLVM_AS} )
98
- set ( CMAKE_LLAsm_ARCHIVE ${LLVM_LINK} )
99
-
100
122
# Construct LLVM version define
101
123
set ( LLVM_VERSION_DEFINE "-DHAVE_LLVM=0x${LLVM_VERSION_MAJOR} 0${LLVM_VERSION_MINOR} " )
102
124
103
-
104
- # LLVM 13 enables standard includes by default
105
- if ( LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL 13.0.0 )
106
- set ( CMAKE_LLAsm_FLAGS "${CMAKE_LLAsm_FLAGS} -cl-no-stdinc" )
107
- set ( CMAKE_CLC_FLAGS "${CMAKE_CLC_FLAGS} -cl-no-stdinc" )
108
- endif ()
109
-
110
- enable_language ( CLC LLAsm )
111
125
# This needs to be set before any target that needs it
112
126
# We need to use LLVM_INCLUDE_DIRS here, because if we are linking to an
113
127
# llvm build directory, this includes $src/llvm/include which is where all the
@@ -122,7 +136,7 @@ set(LLVM_LINK_COMPONENTS
122
136
IRReader
123
137
Support
124
138
)
125
- if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
139
+ if ( LIBCLC_STANDALONE_BUILD )
126
140
add_llvm_executable ( prepare_builtins utils/prepare-builtins.cpp )
127
141
else ()
128
142
add_llvm_utility ( prepare_builtins utils/prepare-builtins.cpp )
@@ -167,12 +181,14 @@ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libclc.pc DESTINATION "${CMAKE_INSTAL
167
181
install ( DIRECTORY generic/include/clc DESTINATION "${CMAKE_INSTALL_INCLUDEDIR} " )
168
182
169
183
if ( ENABLE_RUNTIME_SUBNORMAL )
170
- add_library ( subnormal_use_default STATIC
171
- generic/lib/subnormal_use_default.ll )
172
- add_library ( subnormal_disable STATIC
173
- generic/lib/subnormal_disable.ll )
174
- install ( TARGETS subnormal_use_default subnormal_disable ARCHIVE
175
- DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
184
+ foreach ( file subnormal_use_default subnormal_disable )
185
+ link_bc (
186
+ TARGET ${file}
187
+ INPUTS ${PROJECT_SOURCE_DIR} /generic/lib/${file}.ll
188
+ )
189
+ install ( FILES $< TARGET_PROPERTY:${file} ,TARGET_FILE> ARCHIVE
190
+ DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
191
+ endforeach ()
176
192
endif ()
177
193
178
194
find_package ( Python3 REQUIRED COMPONENTS Interpreter )
@@ -232,131 +248,164 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
232
248
233
249
# Add the generated convert.cl here to prevent adding the one listed in
234
250
# SOURCES
251
+ set ( objects ) # A "set" of already-added input files
252
+ set ( rel_files ) # Source directory input files, relative to the root dir
253
+ set ( gen_files ) # Generated binary input files, relative to the binary dir
235
254
if ( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" )
236
255
if ( NOT ENABLE_RUNTIME_SUBNORMAL AND NOT ${ARCH} STREQUAL "clspv" AND
237
256
NOT ${ARCH} STREQUAL "clspv64" )
238
- set ( rel_files convert.cl )
239
- set ( objects convert.cl )
257
+ list ( APPEND gen_files convert.cl )
258
+ list ( APPEND objects convert.cl )
240
259
list ( APPEND rel_files generic/lib/subnormal_use_default.ll )
241
260
elseif (${ARCH} STREQUAL "clspv" OR ${ARCH} STREQUAL "clspv64" )
242
- set ( rel_files clspv-convert.cl )
243
- set ( objects clspv-convert.cl )
261
+ list ( APPEND gen_files clspv-convert.cl )
262
+ list ( APPEND objects clspv-convert.cl )
244
263
endif ()
245
- else ()
246
- set ( rel_files )
247
- set ( objects )
248
264
endif ()
249
265
250
266
foreach ( l ${source_list} )
251
267
file ( READ ${l} file_list )
252
268
string ( REPLACE "\n " ";" file_list ${file_list} )
253
269
get_filename_component ( dir ${l} DIRECTORY )
254
270
foreach ( f ${file_list} )
255
- list ( FIND objects ${f} found )
256
- if ( found EQUAL -1 )
271
+ # Only add each file once, so that targets can 'specialize' builtins
272
+ if ( NOT ${f} IN_LIST objects )
257
273
list ( APPEND objects ${f} )
258
274
list ( APPEND rel_files ${dir} /${f} )
259
- # FIXME: This should really go away
260
- file ( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR} /${dir}/${f} src_loc )
261
- get_filename_component ( fdir ${src_loc} DIRECTORY )
262
-
263
- set_source_files_properties ( ${dir} /${f}
264
- PROPERTIES COMPILE_FLAGS "-I ${fdir} " )
265
275
endif ()
266
276
endforeach ()
267
277
endforeach ()
268
278
269
279
foreach ( d ${${t}_devices} )
270
- # Some targets don't have a specific GPU to target
271
- if ( ${d} STREQUAL "none" OR ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
272
- set ( mcpu )
273
- set ( arch_suffix "${t} " )
274
- else ()
275
- set ( mcpu "-mcpu=${d} " )
276
- set ( arch_suffix "${d} -${t} " )
280
+ get_libclc_device_info (
281
+ TRIPLE ${t}
282
+ DEVICE ${d}
283
+ CPU cpu
284
+ ARCH_SUFFIX arch_suffix
285
+ CLANG_TRIPLE clang_triple
286
+ )
287
+
288
+ set ( mcpu )
289
+ if ( NOT "${cpu} " STREQUAL "" )
290
+ set ( mcpu "-mcpu=${cpu} " )
277
291
endif ()
292
+
278
293
message ( STATUS " device: ${d} ( ${${d} _aliases} )" )
279
294
280
- if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
281
- if ( ${ARCH} STREQUAL "spirv" )
282
- set ( t "spir--" )
283
- else ()
284
- set ( t "spir64--" )
285
- endif ()
295
+ if ( ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
286
296
set ( build_flags -O0 -finline-hint-functions )
287
297
set ( opt_flags )
288
298
set ( spvflags --spirv-max-version=1.1 )
289
- elseif ( ${ARCH} STREQUAL "clspv" )
290
- set ( t "spir--" )
291
- set ( build_flags "-Wno-unknown-assumption" )
292
- set ( opt_flags -O3 )
293
- elseif ( ${ARCH} STREQUAL "clspv64" )
294
- set ( t "spir64--" )
299
+ elseif ( ARCH STREQUAL clspv OR ARCH STREQUAL clspv64 )
295
300
set ( build_flags "-Wno-unknown-assumption" )
296
301
set ( opt_flags -O3 )
297
302
else ()
298
303
set ( build_flags )
299
304
set ( opt_flags -O3 )
300
305
endif ()
301
306
307
+ set ( LIBCLC_ARCH_OBJFILE_DIR "${LIBCLC_OBJFILE_DIR} /${arch_suffix} " )
308
+ file ( MAKE_DIRECTORY ${LIBCLC_ARCH_OBJFILE_DIR} )
309
+
310
+ string ( TOUPPER "CLC_${ARCH} " CLC_TARGET_DEFINE )
311
+
312
+ list ( APPEND build_flags
313
+ -D__CLC_INTERNAL
314
+ -D${CLC_TARGET_DEFINE}
315
+ -I${PROJECT_SOURCE_DIR}/generic/include
316
+ # FIXME: Fix libclc to not require disabling this noisy warning
317
+ -Wno-bitwise-conditional-parentheses
318
+ )
319
+
320
+ set ( bytecode_files "" )
321
+ foreach ( file IN LISTS gen_files rel_files )
322
+ # We need to take each file and produce an absolute input file, as well
323
+ # as a unique architecture-specific output file. We deal with a mix of
324
+ # different input files, which makes this trickier.
325
+ if ( ${file} IN_LIST gen_files )
326
+ # Generated files are given just as file names, which we must make
327
+ # absolute to the binary directory.
328
+ set ( input_file ${CMAKE_CURRENT_BINARY_DIR} /${file} )
329
+ set ( output_file "${LIBCLC_ARCH_OBJFILE_DIR} /${file} .o" )
330
+ else ()
331
+ # Other files are originally relative to each SOURCE file, which are
332
+ # then make relative to the libclc root directory. We must normalize
333
+ # the path (e.g., ironing out any ".."), then make it relative to the
334
+ # root directory again, and use that relative path component for the
335
+ # binary path.
336
+ get_filename_component ( abs_path ${file} ABSOLUTE BASE_DIR ${PROJECT_SOURCE_DIR} )
337
+ file ( RELATIVE_PATH root_rel_path ${PROJECT_SOURCE_DIR} ${abs_path} )
338
+ set ( input_file ${PROJECT_SOURCE_DIR} /${file} )
339
+ set ( output_file "${LIBCLC_ARCH_OBJFILE_DIR} /${root_rel_path} .o" )
340
+ endif ()
341
+
342
+ get_filename_component ( file_dir ${file} DIRECTORY )
343
+
344
+ compile_to_bc (
345
+ TRIPLE ${clang_triple}
346
+ INPUT ${input_file}
347
+ OUTPUT ${output_file}
348
+ EXTRA_OPTS "${mcpu} " -fno-builtin -nostdlib
349
+ "${build_flags} " -I${PROJECT_SOURCE_DIR}/${file_dir}
350
+ )
351
+ list ( APPEND bytecode_files ${output_file} )
352
+ endforeach ()
353
+
302
354
set ( builtins_link_lib_tgt builtins.link.${arch_suffix} )
303
- add_library ( ${builtins_link_lib_tgt} STATIC ${rel_files} )
304
- # Make sure we depend on the pseudo target to prevent
305
- # multiple invocations
306
- add_dependencies ( ${builtins_link_lib_tgt} generate_convert.cl )
307
- add_dependencies ( ${builtins_link_lib_tgt} clspv-generate_convert.cl )
308
- # CMake will turn this include into absolute path
309
- target_include_directories ( ${builtins_link_lib_tgt} PRIVATE
310
- "generic/include" )
311
- target_compile_definitions ( ${builtins_link_lib_tgt} PRIVATE
312
- "__CLC_INTERNAL" )
313
- string ( TOUPPER "-DCLC_${ARCH} " CLC_TARGET_DEFINE )
314
- target_compile_definitions ( ${builtins_link_lib_tgt} PRIVATE
315
- ${CLC_TARGET_DEFINE} )
316
- target_compile_options ( ${builtins_link_lib_tgt} PRIVATE -target
317
- ${t} ${mcpu} -fno-builtin -nostdlib ${build_flags} )
318
- set_target_properties ( ${builtins_link_lib_tgt} PROPERTIES
319
- LINKER_LANGUAGE CLC )
320
-
321
- set ( obj_suffix ${arch_suffix} .bc )
322
- set ( builtins_opt_lib_tgt builtins.opt.${obj_suffix} )
323
-
324
- # Add opt target
325
- add_custom_command ( OUTPUT ${builtins_opt_lib_tgt}
326
- COMMAND ${LLVM_OPT} ${opt_flags} -o ${builtins_opt_lib_tgt}
327
- $< TARGET_FILE:${builtins_link_lib_tgt} >
328
- DEPENDS ${builtins_link_lib_tgt} )
329
- add_custom_target ( "opt.${obj_suffix} " ALL
330
- DEPENDS ${builtins_opt_lib_tgt} )
331
-
332
- if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
355
+
356
+ link_bc (
357
+ TARGET ${builtins_link_lib_tgt}
358
+ INPUTS ${bytecode_files}
359
+ )
360
+
361
+ set ( builtins_link_lib $< TARGET_PROPERTY:${builtins_link_lib_tgt} ,TARGET_FILE> )
362
+
363
+ if ( ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
333
364
set ( spv_suffix ${arch_suffix} .spv )
334
- add_custom_command ( OUTPUT "${spv_suffix} "
335
- COMMAND ${LLVM_SPIRV} ${spvflags} -o "${spv_suffix} " $< TARGET_FILE:${builtins_link_lib_tgt} >
336
- DEPENDS ${builtins_link_lib_tgt} )
365
+ add_custom_command ( OUTPUT ${spv_suffix}
366
+ COMMAND ${LLVM_SPIRV} ${spvflags} -o ${spv_suffix} ${builtins_link_lib}
367
+ DEPENDS ${builtins_link_lib_tgt}
368
+ )
337
369
add_custom_target ( "prepare-${spv_suffix} " ALL DEPENDS "${spv_suffix} " )
338
370
install ( FILES ${CMAKE_CURRENT_BINARY_DIR} /${spv_suffix}
339
371
DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
340
372
else ()
373
+ set ( builtins_opt_lib_tgt builtins.opt.${arch_suffix} )
374
+
375
+ # Add opt target
376
+ add_custom_command ( OUTPUT ${builtins_opt_lib_tgt} .bc
377
+ COMMAND libclc::opt ${opt_flags} -o ${builtins_opt_lib_tgt} .bc
378
+ ${builtins_link_lib}
379
+ DEPENDS libclc::opt ${builtins_link_lib_tgt}
380
+ )
381
+ add_custom_target ( ${builtins_opt_lib_tgt}
382
+ ALL DEPENDS ${builtins_opt_lib_tgt} .bc
383
+ )
384
+ set_target_properties ( ${builtins_opt_lib_tgt}
385
+ PROPERTIES TARGET_FILE ${builtins_opt_lib_tgt} .bc
386
+ )
387
+
341
388
# Add prepare target
342
- add_custom_command ( OUTPUT "${obj_suffix} "
343
- COMMAND prepare_builtins -o "${obj_suffix} " ${builtins_opt_lib_tgt}
344
- DEPENDS "opt.${obj_suffix} " ${builtins_opt_lib_tgt} prepare_builtins )
345
- add_custom_target ( "prepare-${obj_suffix} " ALL DEPENDS "${obj_suffix} " )
389
+ set ( obj_suffix ${arch_suffix} .bc )
390
+ add_custom_command ( OUTPUT ${obj_suffix}
391
+ COMMAND prepare_builtins -o ${obj_suffix}
392
+ $< TARGET_PROPERTY:${builtins_opt_lib_tgt} ,TARGET_FILE>
393
+ DEPENDS ${builtins_opt_lib_tgt} prepare_builtins )
394
+ add_custom_target ( prepare-${obj_suffix} ALL DEPENDS ${obj_suffix} )
346
395
347
396
# nvptx-- targets don't include workitem builtins
348
- if ( NOT ${t} MATCHES ".*ptx.*--$" )
397
+ if ( NOT clang_triple MATCHES ".*ptx.*--$" )
349
398
add_test ( NAME external-calls-${obj_suffix}
350
399
COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR} /${obj_suffix} ${LLVM_TOOLS_BINARY_DIR}
351
400
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} )
352
401
endif ()
353
402
354
403
install ( FILES ${CMAKE_CURRENT_BINARY_DIR} /${obj_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
355
404
foreach ( a ${${d}_aliases} )
356
- set ( alias_suffix "${a} -${t } .bc" )
405
+ set ( alias_suffix "${a} -${clang_triple } .bc" )
357
406
add_custom_target ( ${alias_suffix} ALL
358
407
COMMAND ${CMAKE_COMMAND} -E create_symlink ${obj_suffix} ${alias_suffix}
359
- DEPENDS " prepare-${obj_suffix} " )
408
+ DEPENDS prepare-${obj_suffix} )
360
409
install ( FILES ${CMAKE_CURRENT_BINARY_DIR} /${alias_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
361
410
endforeach ( a )
362
411
endif ()
0 commit comments