@@ -4,6 +4,11 @@ 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
+ include ( AddLibclc )
11
+
7
12
include ( GNUInstallDirs )
8
13
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
9
14
amdgcn-amdhsa/lib/SOURCES;
@@ -27,31 +32,47 @@ set( LIBCLC_TARGETS_TO_BUILD "all"
27
32
28
33
option ( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support." OFF )
29
34
30
- find_package (LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR} " )
31
- include (AddLLVM )
35
+ if ("${CMAKE_SOURCE_DIR} " STREQUAL "${CMAKE_CURRENT_SOURCE_DIR} " )
36
+ # Out-of-tree configuration
37
+ find_package (LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR} " )
38
+ include (AddLLVM )
32
39
33
- message ( STATUS "libclc LLVM version: ${LLVM_PACKAGE_VERSION} " )
40
+ message ( STATUS "libclc LLVM version: ${LLVM_PACKAGE_VERSION} " )
34
41
35
- if ( ${LLVM_PACKAGE_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} )
36
- message ( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM} " )
37
- endif ()
42
+ if ( ${LLVM_PACKAGE_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} )
43
+ message ( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM} " )
44
+ endif ()
38
45
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 )
46
+ # Import required tools as targets
47
+ foreach ( tool clang llvm-as llvm-link opt )
48
+ find_program ( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
49
+ add_executable ( libclc::${tool} IMPORTED GLOBAL )
50
+ set_target_properties ( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} )
51
+ endforeach ()
52
+ else ()
53
+ # In-tree configuration
54
+ set ( LLVM_PACKAGE_VERSION ${LLVM_VERSION} )
55
+
56
+ # Note that we check this later (for both build types) but we can provide a
57
+ # more useful error message when built in-tree. We assume that LLVM tools are
58
+ # always available so don't warn here.
59
+ if ( NOT clang IN_LIST LLVM_ENABLE_PROJECTS )
60
+ message (FATAL_ERROR "Clang is not enabled, but is required to build libclc in-tree" )
61
+ endif ()
44
62
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 )
63
+ foreach ( tool clang llvm-as llvm-link opt )
64
+ add_executable ( libclc::${tool} ALIAS ${tool} )
65
+ endforeach ( )
66
+ endif ( )
67
+
68
+ if ( NOT TARGET libclc::clang OR NOT TARGET libclc::opt
69
+ OR NOT TARGET libclc::llvm-as OR NOT TARGET libclc::llvm-link )
52
70
message ( FATAL_ERROR "libclc toolchain incomplete!" )
53
71
endif ()
54
72
73
+ # llvm-spirv is an optional dependency, used to build spirv-* targets.
74
+ find_program ( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
75
+
55
76
# List of all targets. Note that some are added dynamically below.
56
77
set ( LIBCLC_TARGETS_ALL
57
78
amdgcn--
@@ -66,7 +87,7 @@ set( LIBCLC_TARGETS_ALL
66
87
)
67
88
68
89
# mesa3d environment is only available since LLVM 4.0
69
- if ( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.9.0" )
90
+ if ( ${LLVM_PACKAGE_VERSION} VERSION_GREATER_EQUAL 4.0.0 )
70
91
list ( APPEND LIBCLC_TARGETS_ALL amdgcn-mesa-mesa3d )
71
92
endif ()
72
93
@@ -90,24 +111,9 @@ if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST
90
111
endif ()
91
112
endif ()
92
113
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
114
# Construct LLVM version define
101
115
set ( LLVM_VERSION_DEFINE "-DHAVE_LLVM=0x${LLVM_VERSION_MAJOR} 0${LLVM_VERSION_MINOR} " )
102
116
103
-
104
- # LLVM 13 enables standard includes by default
105
- if ( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "12.99.99" )
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
117
# This needs to be set before any target that needs it
112
118
# We need to use LLVM_INCLUDE_DIRS here, because if we are linking to an
113
119
# llvm build directory, this includes $src/llvm/include which is where all the
@@ -162,13 +168,18 @@ configure_file( libclc.pc.in libclc.pc @ONLY )
162
168
install ( FILES ${CMAKE_CURRENT_BINARY_DIR} /libclc.pc DESTINATION "${CMAKE_INSTALL_DATADIR} /pkgconfig" )
163
169
install ( DIRECTORY generic/include/clc DESTINATION "${CMAKE_INSTALL_INCLUDEDIR} " )
164
170
171
+ set ( LIBCLC_OBJFILE_DIR "${CMAKE_CURRENT_BINARY_DIR} /obj.libclc.dir" )
172
+
165
173
if ( ENABLE_RUNTIME_SUBNORMAL )
166
- add_library ( subnormal_use_default STATIC
167
- generic/lib/subnormal_use_default.ll )
168
- add_library ( subnormal_disable STATIC
169
- generic/lib/subnormal_disable.ll )
170
- install ( TARGETS subnormal_use_default subnormal_disable ARCHIVE
171
- DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
174
+ foreach ( file subnormal_use_default subnormal_disable )
175
+ link_bc (
176
+ OUTPUT ${LIBCLC_OBJFILE_DIR} /${file}.bc
177
+ INPUTS ${PROJECT_SOURCE_DIR} /generic/lib/${file}.ll
178
+ )
179
+ add_custom_target ( ${file} .bc ALL DEPENDS ${LIBCLC_OBJFILE_DIR} /${file}.bc )
180
+ install ( FILES ${LIBCLC_OBJFILE_DIR} /${file}.bc ARCHIVE
181
+ DESTINATION "${CMAKE_INSTALL_DATADIR} /clc" )
182
+ endforeach ()
172
183
endif ()
173
184
174
185
find_package ( Python3 REQUIRED COMPONENTS Interpreter )
@@ -205,7 +216,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
205
216
list ( APPEND dirs amdgpu )
206
217
endif ()
207
218
208
- #nvptx is special
219
+ # nvptx is special
209
220
if ( ${ARCH} STREQUAL nvptx OR ${ARCH} STREQUAL nvptx64 )
210
221
set ( DARCH ptx )
211
222
else ()
@@ -226,38 +237,32 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
226
237
endforeach ()
227
238
endforeach ()
228
239
229
- # Add the generated convert.cl here to prevent adding
230
- # the one listed in SOURCES
240
+ # Add the generated convert.cl here to prevent adding the one listed in
241
+ # SOURCES
242
+ set ( objects ) # A "set" of already-added input files
243
+ set ( rel_files ) # Source directory input files, relative to the root dir
244
+ set ( gen_files ) # Generated binary input files, relative to the binary dir
231
245
if ( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" )
232
246
if ( NOT ENABLE_RUNTIME_SUBNORMAL AND NOT ${ARCH} STREQUAL "clspv" AND
233
247
NOT ${ARCH} STREQUAL "clspv64" )
234
- set ( rel_files convert.cl )
235
- set ( objects convert.cl )
248
+ list ( APPEND gen_files convert.cl )
249
+ list ( APPEND objects convert.cl )
236
250
list ( APPEND rel_files generic/lib/subnormal_use_default.ll )
237
251
elseif (${ARCH} STREQUAL "clspv" OR ${ARCH} STREQUAL "clspv64" )
238
- set ( rel_files clspv-convert.cl )
239
- set ( objects clspv-convert.cl )
252
+ list ( APPEND gen_files clspv-convert.cl )
253
+ list ( APPEND objects clspv-convert.cl )
240
254
endif ()
241
- else ()
242
- set ( rel_files )
243
- set ( objects )
244
255
endif ()
245
256
246
257
foreach ( l ${source_list} )
247
258
file ( READ ${l} file_list )
248
259
string ( REPLACE "\n " ";" file_list ${file_list} )
249
260
get_filename_component ( dir ${l} DIRECTORY )
250
261
foreach ( f ${file_list} )
251
- list ( FIND objects ${f} found )
252
- if ( found EQUAL -1 )
262
+ # Only add each file once, so that targets can 'specialize' builtins
263
+ if ( NOT ${f} IN_LIST objects )
253
264
list ( APPEND objects ${f} )
254
265
list ( APPEND rel_files ${dir} /${f} )
255
- # FIXME: This should really go away
256
- file ( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR} /${dir}/${f} src_loc )
257
- get_filename_component ( fdir ${src_loc} DIRECTORY )
258
-
259
- set_source_files_properties ( ${dir} /${f}
260
- PROPERTIES COMPILE_FLAGS "-I ${fdir} " )
261
266
endif ()
262
267
endforeach ()
263
268
endforeach ()
@@ -295,32 +300,67 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
295
300
set ( opt_flags -O3 )
296
301
endif ()
297
302
298
- set ( builtins_link_lib_tgt builtins.link.${arch_suffix} )
299
- add_library ( ${builtins_link_lib_tgt} STATIC ${rel_files} )
300
- # Make sure we depend on the pseudo target to prevent
301
- # multiple invocations
302
- add_dependencies ( ${builtins_link_lib_tgt} generate_convert.cl )
303
- add_dependencies ( ${builtins_link_lib_tgt} clspv-generate_convert.cl )
304
- # CMake will turn this include into absolute path
305
- target_include_directories ( ${builtins_link_lib_tgt} PRIVATE
306
- "generic/include" )
307
- target_compile_definitions ( ${builtins_link_lib_tgt} PRIVATE
308
- "__CLC_INTERNAL" )
309
- string ( TOUPPER "-DCLC_${ARCH} " CLC_TARGET_DEFINE )
310
- target_compile_definitions ( ${builtins_link_lib_tgt} PRIVATE
311
- ${CLC_TARGET_DEFINE} )
312
- target_compile_options ( ${builtins_link_lib_tgt} PRIVATE -target
313
- ${t} ${mcpu} -fno-builtin -nostdlib ${build_flags} )
314
- set_target_properties ( ${builtins_link_lib_tgt} PROPERTIES
315
- LINKER_LANGUAGE CLC )
303
+ set ( LIBCLC_ARCH_OBJFILE_DIR "${LIBCLC_OBJFILE_DIR} /${arch_suffix} " )
304
+ file ( MAKE_DIRECTORY ${LIBCLC_ARCH_OBJFILE_DIR} )
305
+
306
+ string ( TOUPPER "CLC_${ARCH} " CLC_TARGET_DEFINE )
307
+
308
+ list ( APPEND build_flags
309
+ -D__CLC_INTERNAL
310
+ -D${CLC_TARGET_DEFINE}
311
+ -I${PROJECT_SOURCE_DIR}/generic/include
312
+ # FIXME: Fix libclc to not require disabling this noisy warnings
313
+ -Wno-bitwise-conditional-parentheses
314
+ )
315
+
316
+ set ( bytecode_files "" )
317
+ foreach ( file IN LISTS gen_files rel_files )
318
+ # We need to take each file and produce an absolute input file, as well
319
+ # as a unique architecture-specific output file. We deal with a mix of
320
+ # different input files, which makes this trickier.
321
+ if ( ${file} IN_LIST gen_files )
322
+ # Generated files are given just as file names, which we must make
323
+ # absolute to the binary directory.
324
+ set ( input_file ${CMAKE_CURRENT_BINARY_DIR} /${file} )
325
+ set ( output_file "${LIBCLC_ARCH_OBJFILE_DIR} /${file} .o" )
326
+ else ()
327
+ # Other files are originally relative to each SOURCE file, which are
328
+ # then make relative to the libclc root directory. We must normalize
329
+ # the path (e.g., ironing out any ".."), then make it relative to the
330
+ # root directory again, and use that relative path component for the
331
+ # binary path.
332
+ get_filename_component ( abs_path ${file} ABSOLUTE BASE_DIR ${PROJECT_SOURCE_DIR} )
333
+ file ( RELATIVE_PATH root_rel_path ${PROJECT_SOURCE_DIR} ${abs_path} )
334
+ set ( input_file ${PROJECT_SOURCE_DIR} /${file} )
335
+ set ( output_file "${LIBCLC_ARCH_OBJFILE_DIR} /${root_rel_path} .o" )
336
+ endif ()
337
+
338
+ get_filename_component ( file_dir ${file} DIRECTORY )
339
+
340
+ compile_to_bc (
341
+ TRIPLE ${t}
342
+ INPUT ${input_file}
343
+ OUTPUT ${output_file}
344
+ EXTRA_OPTS "${mcpu} " -fno-builtin -nostdlib
345
+ "${build_flags} " -I${PROJECT_SOURCE_DIR}/${file_dir}
346
+ )
347
+ list (APPEND bytecode_files ${output_file} )
348
+ endforeach ()
349
+
350
+ set ( builtins_link_lib_tgt builtins.link.${arch_suffix}.bc )
351
+
352
+ link_bc (
353
+ OUTPUT ${builtins_link_lib_tgt}
354
+ INPUTS ${bytecode_files}
355
+ )
316
356
317
357
set ( obj_suffix ${arch_suffix} .bc )
318
358
set ( builtins_opt_lib_tgt builtins.opt.${obj_suffix} )
319
359
320
360
# Add opt target
321
361
add_custom_command ( OUTPUT ${builtins_opt_lib_tgt}
322
- COMMAND ${LLVM_OPT} ${opt_flags} -o ${builtins_opt_lib_tgt}
323
- $< TARGET_FILE: $ {builtins_link_lib_tgt}>
362
+ COMMAND libclc::opt ${opt_flags} -o ${builtins_opt_lib_tgt}
363
+ ${builtins_link_lib_tgt}
324
364
DEPENDS ${builtins_link_lib_tgt} )
325
365
add_custom_target ( "opt.${obj_suffix} " ALL
326
366
DEPENDS ${builtins_opt_lib_tgt} )
0 commit comments