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
|
#[=======================================================================[.rst:
DetermineTargetCPU
---------------------------
Determine the target CPU used for the current build.
By default, the build system will generate code that is optimized for the
current architecture, by using the compile option `-march=native`. This will
let the compiler determine the target CPU. The user many also manually select
a specific target CPU by setting the variable ``TARGET_CPU``. In order to
force the compiler to generate portable code, the user can set the option
``PORTABLE`` to ``TRUE``. Note that ``PORTABLE`` and ``TARGET_CPU`` are
mutually exclusive.
This module determines which target CPU the compiler has selected, if any.
For each
enabled feature, a boolean variable ``USE_<AVX-feature>`` is written into
the cache. The user can force the generation of portable code by setting
the option ``PORTABLE`` to ``TRUE``. In that case, all cached
``USE_<AVX-feature>`` variables will be removed from the cache.
#]=======================================================================]
# List of target CPUs known by both GCC and Clang
# This list was produced as follows (note: requires llc to be installed):
# comm -12 \
# <(g++ -march=foo -E - < /dev/null |& grep '^cc1: note' | \
# sed -nE 's,^.*: *([^;]*).*$,\1,p' | tr ' ' '\n' | sort -u) \
# <(llc -mattr=help |& grep processor. | awk '{print $1}' | sort -u)
set(KNOWN_TARGET_CPUS
amdfam10
athlon64
athlon64-sse3
athlon-fx
atom
barcelona
bdver1
bdver2
bdver3
bdver4
bonnell
broadwell
btver1
btver2
core2
core-avx2
core-avx-i
corei7
corei7-avx
haswell
ivybridge
k8
k8-sse3
knl
nehalem
nocona
opteron
opteron-sse3
sandybridge
silvermont
skylake
skylake-avx512
slm
westmere
x86-64
znver1
CACHE INTERNAL "Known target CPUs")
if(NOT PORTABLE)
get_directory_property(_compile_options COMPILE_OPTIONS)
string(REPLACE ";" " " _compile_options "${_compile_options}")
execute_process(
COMMAND
bash -c
# Executed command is printed on stderr; we can discard stdout
"echo | ${CMAKE_CXX_COMPILER} ${_compile_options} -E -v - >/dev/null"
ERROR_VARIABLE _command
RESULT_VARIABLE _result)
if(NOT _result EQUAL 0)
message(WARNING "${CMAKE_CXX_COMPILER_ID} compiler failed to identify "
"target CPU '${TARGET_CPU}'")
else()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
execute_process(
COMMAND
bash -c
"echo '${_command}' | sed -nE '/cc1/s/^.*-march=([^ ]+).*$/\\1/p'"
OUTPUT_VARIABLE _target_cpu
OUTPUT_STRIP_TRAILING_WHITESPACE)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
execute_process(
COMMAND
bash -c
"echo '${_command}' | sed -nE '/cc1/s/^.*-target-cpu ([^ ]+).*$/\\1/p'"
OUTPUT_VARIABLE _target_cpu
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
message(WARNING "Don't know how to let ${CMAKE_CXX_COMPILER_ID} "
"compiler identify target CPU")
endif()
endif()
endif()
if(DEFINED _target_cpu)
set(IDENTIFIED_TARGET_CPU
${_target_cpu}
CACHE INTERNAL "")
else()
unset(IDENTIFIED_TARGET_CPU CACHE)
endif()
if(DEFINED IDENTIFIED_TARGET_CPU AND NOT IDENTIFIED_TARGET_CPU IN_LIST
KNOWN_TARGET_CPUS)
message(
AUTHOR_WARNING
"'${IDENTIFIED_TARGET_CPU}' is not in the list KNOWN_TARGET_CPUS. "
"Please check if this list is still up-to-date")
endif()
|