Skip to content

Commit b0313ad

Browse files
authored
[libclc] Add an option to build SPIR-V targets with the LLVM backend (llvm#151347)
This removes the dependency on an external tool to build the SPIR-V files. It may be of interest to projects such as Mesa. Note that the option is off by default as using the SPIR-V backend, at least on my machine, uses a *lot* of memory and the process is often killed in a parallelized build. It does complete, however. Fixes llvm#135327.
1 parent 673476d commit b0313ad

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

libclc/CMakeLists.txt

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ set( LIBCLC_TARGETS_TO_BUILD "all"
4242

4343
option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support." OFF )
4444

45+
option(
46+
LIBCLC_USE_SPIRV_BACKEND "Build SPIR-V targets with the SPIR-V backend." OFF
47+
)
48+
4549
# Top level target used to build all Libclc libraries.
4650
add_custom_target( libclc ALL )
4751

@@ -115,14 +119,17 @@ foreach( tool IN ITEMS clang opt llvm-as llvm-link )
115119
endif()
116120
endforeach()
117121

118-
# llvm-spirv is an optional dependency, used to build spirv-* targets.
119-
# It may be provided in-tree or externally.
120-
if( TARGET llvm-spirv )
121-
get_host_tool_path( llvm-spirv LLVM_SPIRV llvm-spirv_exe llvm-spirv_target )
122-
else()
123-
find_program( LLVM_SPIRV llvm-spirv HINTS ${LLVM_TOOLS_BINARY_DIR} )
124-
set( llvm-spirv_exe "${LLVM_SPIRV}" )
125-
set( llvm-spirv_target )
122+
if( NOT LIBCLC_USE_SPIRV_BACKEND )
123+
# llvm-spirv is an optional dependency, used to build spirv-* targets when
124+
# the SPIR-V backend hasn't been requested. It may be provided in-tree or
125+
# externally.
126+
if( TARGET llvm-spirv )
127+
get_host_tool_path( llvm-spirv LLVM_SPIRV llvm-spirv_exe llvm-spirv_target )
128+
else()
129+
find_program( LLVM_SPIRV llvm-spirv HINTS ${LLVM_TOOLS_BINARY_DIR} )
130+
set( llvm-spirv_exe "${LLVM_SPIRV}" )
131+
set( llvm-spirv_target )
132+
endif()
126133
endif()
127134

128135
# List of all targets. Note that some are added dynamically below.
@@ -138,22 +145,24 @@ set( LIBCLC_TARGETS_ALL
138145
nvptx64--nvidiacl
139146
)
140147

141-
# mesa3d environment is only available since LLVM 4.0
148+
# The mesa3d environment is only available since LLVM 4.0
142149
if( LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL 4.0.0 )
143150
list( APPEND LIBCLC_TARGETS_ALL amdgcn-mesa-mesa3d )
144151
endif()
145152

146-
# spirv-mesa3d and spirv64-mesa3d targets can only be built with the (optional)
147-
# llvm-spirv external tool.
148-
if( llvm-spirv_exe )
149-
list( APPEND LIBCLC_TARGETS_ALL spirv-mesa3d- spirv64-mesa3d- )
153+
# The spirv-mesa3d and spirv64-mesa3d targets are optional and can be built
154+
# with either the LLVM SPIR-V backend or the external llvm-spirv tool.
155+
if( LIBCLC_USE_SPIRV_BACKEND OR llvm-spirv_exe )
156+
list( APPEND LIBCLC_TARGETS_ALL spirv-mesa3d- spirv64-mesa3d- )
150157
endif()
151158

152159
# Verify that the user hasn't requested mesa3d targets without an available
153160
# llvm-spirv tool.
154-
if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD )
155-
if( NOT llvm-spirv_exe )
156-
message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
161+
if( spirv-mesa3d- IN_LIST LIBCLC_TARGETS_TO_BUILD
162+
OR spirv64-mesa3d- IN_LIST LIBCLC_TARGETS_TO_BUILD )
163+
if( NOT LIBCLC_USE_SPIRV_BACKEND AND NOT llvm-spirv_exe )
164+
message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not "
165+
"installed and the SPIR-V backend has not been requested." )
157166
endif()
158167
endif()
159168

libclc/cmake/modules/AddLibclc.cmake

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,9 @@ function(get_libclc_device_info)
164164
list( GET TRIPLE 0 ARCH )
165165

166166
# Some targets don't have a specific device architecture to target
167-
if( ARG_DEVICE STREQUAL none OR ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
167+
if( ARG_DEVICE STREQUAL none
168+
OR ((ARCH STREQUAL spirv OR ARCH STREQUAL spirv64)
169+
AND NOT LIBCLC_USE_SPIRV_BACKEND) )
168170
set( cpu )
169171
set( arch_suffix "${ARG_TRIPLE}" )
170172
else()
@@ -182,7 +184,11 @@ function(get_libclc_device_info)
182184

183185
# Some libclc targets are not real clang triples: return their canonical
184186
# triples.
185-
if( ARCH STREQUAL spirv OR ARCH STREQUAL clspv )
187+
if( ARCH STREQUAL spirv AND LIBCLC_USE_SPIRV_BACKEND )
188+
set( ARG_TRIPLE "spirv32--" )
189+
elseif( ARCH STREQUAL spirv64 AND LIBCLC_USE_SPIRV_BACKEND )
190+
set( ARG_TRIPLE "spirv64--" )
191+
elseif( ARCH STREQUAL spirv OR ARCH STREQUAL clspv )
186192
set( ARG_TRIPLE "spir--" )
187193
elseif( ARCH STREQUAL spirv64 OR ARCH STREQUAL clspv64 )
188194
set( ARG_TRIPLE "spir64--" )
@@ -363,10 +369,17 @@ function(add_libclc_builtin_set)
363369
if( ARG_ARCH STREQUAL spirv OR ARG_ARCH STREQUAL spirv64 )
364370
set( obj_suffix ${ARG_ARCH_SUFFIX}.spv )
365371
set( libclc_builtins_lib ${LIBCLC_OUTPUT_LIBRARY_DIR}/${obj_suffix} )
366-
add_custom_command( OUTPUT ${libclc_builtins_lib}
367-
COMMAND ${llvm-spirv_exe} ${spvflags} -o ${libclc_builtins_lib} ${builtins_link_lib}
368-
DEPENDS ${llvm-spirv_target} ${builtins_link_lib} ${builtins_link_lib_tgt}
369-
)
372+
if ( LIBCLC_USE_SPIRV_BACKEND )
373+
add_custom_command( OUTPUT ${libclc_builtins_lib}
374+
COMMAND ${clang_exe} --target=${ARG_TRIPLE} -x ir -o ${libclc_builtins_lib} ${builtins_link_lib}
375+
DEPENDS ${clang_target} ${builtins_link_lib} ${builtins_link_lib_tgt}
376+
)
377+
else()
378+
add_custom_command( OUTPUT ${libclc_builtins_lib}
379+
COMMAND ${llvm-spirv_exe} ${spvflags} -o ${libclc_builtins_lib} ${builtins_link_lib}
380+
DEPENDS ${llvm-spirv_target} ${builtins_link_lib} ${builtins_link_lib_tgt}
381+
)
382+
endif()
370383
else()
371384
# Non-SPIR-V targets add an extra step to optimize the bytecode
372385
set( builtins_opt_lib_tgt builtins.opt.${ARG_ARCH_SUFFIX} )

0 commit comments

Comments
 (0)