blob: 4d50d81e0ce45726a3a10c32888a90f5d63d4cf6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# ------------------------------------------------------------------------------
# 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"
"ext_vector_type"
)
# 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)
elseif(${feature} STREQUAL "ext_vector_type")
set(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE 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)
|