mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 23:16:06 +00:00
149 lines
5.2 KiB
CMake
149 lines
5.2 KiB
CMake
# ------------------------------------------------------------------------------
|
|
# Compiler features definition and flags
|
|
# ------------------------------------------------------------------------------
|
|
|
|
set(
|
|
ALL_COMPILER_FEATURES
|
|
"builtin_ceil_floor_rint_trunc"
|
|
"builtin_fmax_fmin"
|
|
"builtin_fmaxf16_fminf16"
|
|
"builtin_round"
|
|
"builtin_roundeven"
|
|
"float16"
|
|
"float16_conversion"
|
|
"float128"
|
|
"fixed_point"
|
|
"cfloat16"
|
|
"cfloat128"
|
|
)
|
|
|
|
# Making sure ALL_COMPILER_FEATURES is sorted.
|
|
list(SORT ALL_COMPILER_FEATURES)
|
|
|
|
# Compiler features that are unavailable on GPU targets with the in-tree Clang.
|
|
set(
|
|
CPU_ONLY_COMPILER_FEATURES
|
|
"float128"
|
|
)
|
|
|
|
# Function to check whether the compiler supports the provided set of features.
|
|
# Usage:
|
|
# compiler_supports(
|
|
# <output variable>
|
|
# <list of cpu features>
|
|
# )
|
|
function(compiler_supports output_var features)
|
|
_intersection(var "${LIBC_CPU_FEATURES}" "${features}")
|
|
if("${var}" STREQUAL "${features}")
|
|
set(${output_var} TRUE PARENT_SCOPE)
|
|
else()
|
|
unset(${output_var} PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Internal helpers and utilities.
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Computes the intersection between two lists.
|
|
function(_intersection output_var list1 list2)
|
|
foreach(element IN LISTS list1)
|
|
if("${list2}" MATCHES "(^|;)${element}(;|$)")
|
|
list(APPEND tmp "${element}")
|
|
endif()
|
|
endforeach()
|
|
set(${output_var} ${tmp} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
set(AVAILABLE_COMPILER_FEATURES "")
|
|
|
|
# Try compile a C file to check if flag is supported.
|
|
foreach(feature IN LISTS ALL_COMPILER_FEATURES)
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
set(compile_options ${LIBC_COMPILE_OPTIONS_NATIVE})
|
|
set(link_options "")
|
|
if(${feature} STREQUAL "fixed_point")
|
|
list(APPEND compile_options "-ffixed-point")
|
|
elseif(${feature} MATCHES "^builtin_" OR
|
|
${feature} STREQUAL "float16_conversion")
|
|
set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
|
|
set(link_options -nostdlib)
|
|
# The compiler might handle calls to math builtins by generating calls to
|
|
# the respective libc math functions, in which case we cannot use these
|
|
# builtins in our implementations of these functions. We check that this is
|
|
# not the case by trying to link an executable, since linking would fail due
|
|
# to unresolved references with -nostdlib if calls to libc functions were
|
|
# generated.
|
|
#
|
|
# We also had issues with soft-float float16 conversion functions using both
|
|
# compiler-rt and libgcc, so we also check whether we can convert from and
|
|
# to float16 without calls to compiler runtime functions by trying to link
|
|
# an executable with -nostdlib.
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
|
|
endif()
|
|
|
|
if(LIBC_TARGET_OS_IS_GPU)
|
|
# CUDA shouldn't be required to build the libc, only to test it, so we can't
|
|
# try to build CUDA binaries here. Since GPU builds are always compiled with
|
|
# the in-tree Clang, we just hardcode which compiler features are available
|
|
# when targeting GPUs.
|
|
if(feature IN_LIST CPU_ONLY_COMPILER_FEATURES)
|
|
set(has_feature FALSE)
|
|
else()
|
|
set(has_feature TRUE)
|
|
endif()
|
|
else()
|
|
try_compile(
|
|
has_feature
|
|
${CMAKE_CURRENT_BINARY_DIR}/compiler_features
|
|
SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/compiler_features/check_${feature}.cpp
|
|
COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${compile_options}
|
|
LINK_OPTIONS ${link_options}
|
|
)
|
|
endif()
|
|
|
|
if(has_feature)
|
|
list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
|
|
if(${feature} STREQUAL "float16")
|
|
set(LIBC_TYPES_HAS_FLOAT16 TRUE)
|
|
elseif(${feature} STREQUAL "float16_conversion")
|
|
add_compile_definitions(__LIBC_USE_FLOAT16_CONVERSION)
|
|
elseif(${feature} STREQUAL "float128")
|
|
set(LIBC_TYPES_HAS_FLOAT128 TRUE)
|
|
elseif(${feature} STREQUAL "fixed_point")
|
|
set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
|
|
elseif(${feature} STREQUAL "cfloat16")
|
|
set(LIBC_TYPES_HAS_CFLOAT16 TRUE)
|
|
elseif(${feature} STREQUAL "cfloat128")
|
|
set(LIBC_TYPES_HAS_CFLOAT128 TRUE)
|
|
elseif(${feature} STREQUAL "builtin_ceil_floor_rint_trunc")
|
|
set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC TRUE)
|
|
elseif(${feature} STREQUAL "builtin_fmax_fmin")
|
|
set(LIBC_COMPILER_HAS_BUILTIN_FMAX_FMIN TRUE)
|
|
elseif(${feature} STREQUAL "builtin_fmaxf16_fminf16")
|
|
set(LIBC_COMPILER_HAS_BUILTIN_FMAXF16_FMINF16 TRUE)
|
|
elseif(${feature} STREQUAL "builtin_round")
|
|
set(LIBC_COMPILER_HAS_BUILTIN_ROUND TRUE)
|
|
elseif(${feature} STREQUAL "builtin_roundeven")
|
|
set(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN TRUE)
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
|
set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
|
|
set(link_options "")
|
|
|
|
message(STATUS "Compiler features available: ${AVAILABLE_COMPILER_FEATURES}")
|
|
|
|
### Compiler Feature Detection ###
|
|
|
|
# clang-8+, gcc-12+
|
|
check_cxx_compiler_flag("-ftrivial-auto-var-init=pattern" LIBC_CC_SUPPORTS_PATTERN_INIT)
|
|
|
|
# clang-6+, gcc-13+
|
|
check_cxx_compiler_flag("-nostdlib++" LIBC_CC_SUPPORTS_NOSTDLIBPP)
|
|
|
|
# clang-3.0+
|
|
check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)
|