File: LLVMLibCCheckCpuFeatures.cmake

package info (click to toggle)
llvm-toolchain-16 1%3A16.0.6-15~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,634,792 kB
  • sloc: cpp: 6,179,261; ansic: 1,216,205; asm: 741,319; python: 196,614; objc: 75,325; f90: 49,640; lisp: 32,396; pascal: 12,286; sh: 9,394; perl: 7,442; ml: 5,494; awk: 3,523; makefile: 2,723; javascript: 1,206; xml: 886; fortran: 581; cs: 573
file content (87 lines) | stat: -rw-r--r-- 2,991 bytes parent folder | download | duplicates (2)
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
# ------------------------------------------------------------------------------
# Cpu features definition and flags
# ------------------------------------------------------------------------------

# Initialize ALL_CPU_FEATURES as empty list.
set(ALL_CPU_FEATURES "")

if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
  set(ALL_CPU_FEATURES SSE2 SSE4_2 AVX2 AVX512F AVX512BW FMA)
  set(LIBC_COMPILE_OPTIONS_NATIVE -march=native)
elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64})
  set(LIBC_COMPILE_OPTIONS_NATIVE -mcpu=native)
endif()

# Making sure ALL_CPU_FEATURES is sorted.
list(SORT ALL_CPU_FEATURES)

# Function to check whether the target CPU supports the provided set of features.
# Usage:
# cpu_supports(
#   <output variable>
#   <list of cpu features>
# )
function(cpu_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()

# Generates a cpp file to introspect the compiler defined flags.
function(_generate_check_code)
  foreach(feature IN LISTS ALL_CPU_FEATURES)
    set(DEFINITIONS
        "${DEFINITIONS}
#ifdef __${feature}__
    \"${feature}\",
#endif")
  endforeach()
  configure_file(
    "${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_cpu_features.cpp.in"
    "cpu_features/check_cpu_features.cpp" @ONLY)
endfunction()
_generate_check_code()

set(LIBC_CPU_FEATURES "" CACHE PATH "Host supported CPU features")

if(LIBC_CROSSBUILD)
  _intersection(cpu_features "${ALL_CPU_FEATURES}" "${LIBC_CPU_FEATURES}")
  if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}")
    message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}")
  endif()
  message(STATUS "Set CPU features: ${cpu_features}")
  set(LIBC_CPU_FEATURES "${cpu_features}")
else()
  # Populates the LIBC_CPU_FEATURES list from host.
  try_run(
    run_result compile_result "${CMAKE_CURRENT_BINARY_DIR}/check_${feature}"
    "${CMAKE_CURRENT_BINARY_DIR}/cpu_features/check_cpu_features.cpp"
    COMPILE_DEFINITIONS ${LIBC_COMPILE_OPTIONS_NATIVE}
    COMPILE_OUTPUT_VARIABLE compile_output
    RUN_OUTPUT_VARIABLE run_output)
  if("${run_result}" EQUAL 0)
    message(STATUS "Set CPU features: ${run_output}")
    set(LIBC_CPU_FEATURES "${run_output}")
  elseif(NOT ${compile_result})
    message(FATAL_ERROR "Failed to compile: ${compile_output}")
  else()
    message(FATAL_ERROR "Failed to run: ${run_output}")
  endif()
endif()