mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-26 05:18:46 +00:00
[reland][libc][NFC] Detect host CPU features using try_compile instead of try_run.
This implements the same behavior as D141997 but makes sure that the same detection mechanism is used between CMake and source code. Differential Revision: https://reviews.llvm.org/D142108
This commit is contained in:
parent
1d1a331351
commit
c84d74f5bf
@ -44,44 +44,32 @@ function(_intersection output_var list1 list2)
|
||||
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")
|
||||
|
||||
set(AVAILABLE_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}")
|
||||
# If we are doing a cross build, we will just assume that all CPU features
|
||||
# are available.
|
||||
set(AVAILABLE_CPU_FEATURES ${ALL_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()
|
||||
# Try compile a C file to check if flag is supported.
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
foreach(feature IN LISTS ALL_CPU_FEATURES)
|
||||
try_compile(
|
||||
has_feature
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cpu_features
|
||||
SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_${feature}.cpp
|
||||
COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${LIBC_COMPILE_OPTIONS_NATIVE}
|
||||
)
|
||||
if(has_feature)
|
||||
list(APPEND AVAILABLE_CPU_FEATURES ${feature})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(LIBC_CPU_FEATURES ${AVAILABLE_CPU_FEATURES} CACHE STRING "Host supported CPU features")
|
||||
|
||||
_intersection(cpu_features "${AVAILABLE_CPU_FEATURES}" "${LIBC_CPU_FEATURES}")
|
||||
if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}")
|
||||
message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}")
|
||||
else()
|
||||
message(STATUS "Set CPU features: ${cpu_features}")
|
||||
endif()
|
||||
|
5
libc/cmake/modules/cpu_features/check_AVX2.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_AVX2.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_AVX2
|
||||
#error unsupported
|
||||
#endif
|
5
libc/cmake/modules/cpu_features/check_AVX512BW.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_AVX512BW.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_AVX512BW
|
||||
#error unsupported
|
||||
#endif
|
5
libc/cmake/modules/cpu_features/check_AVX512F.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_AVX512F.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_AVX512F
|
||||
#error unsupported
|
||||
#endif
|
5
libc/cmake/modules/cpu_features/check_FMA.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_FMA.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_FMA
|
||||
#error unsupported
|
||||
#endif
|
5
libc/cmake/modules/cpu_features/check_SSE2.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_SSE2.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_SSE2
|
||||
#error unsupported
|
||||
#endif
|
5
libc/cmake/modules/cpu_features/check_SSE4_2.cpp
Normal file
5
libc/cmake/modules/cpu_features/check_SSE4_2.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#ifndef LIBC_TARGET_HAS_SSE4_2
|
||||
#error unsupported
|
||||
#endif
|
@ -1,32 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// This file is instantiated by CMake.
|
||||
// DEFINITIONS below is replaced with a set of lines like so:
|
||||
// #ifdef __SSE2__
|
||||
// "SSE2",
|
||||
// #endif
|
||||
//
|
||||
// This allows for introspection of compiler definitions.
|
||||
// The output of the program is a single line of semi colon separated feature
|
||||
// names.
|
||||
|
||||
// MSVC is using a different set of preprocessor definitions for
|
||||
// SSE and SSE2, see _M_IX86_FP in
|
||||
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
|
||||
|
||||
int main(int, char **) {
|
||||
const char *strings[] = {
|
||||
@DEFINITIONS@
|
||||
// If DEFINITIONS turns out to be empty, we don't want to list
|
||||
// an empty array. So, we add an end of list marker.
|
||||
"<end_of_feature_list>"
|
||||
};
|
||||
const size_t size = sizeof(strings) / sizeof(strings[0]);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (i)
|
||||
putchar(';');
|
||||
fputs(strings[i], stdout);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -33,6 +33,7 @@ add_header_library(
|
||||
HDRS
|
||||
architectures.h
|
||||
common.h
|
||||
cpu_features.h
|
||||
endian.h
|
||||
)
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "src/__support/architectures.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#if defined(LIBC_TARGET_HAS_FMA)
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H
|
||||
|
||||
#include "src/__support/architectures.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#if !defined(LLVM_LIBC_ARCH_AARCH64)
|
||||
#error "Invalid include"
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "src/__support/architectures.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "src/__support/architectures.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#if !defined(LLVM_LIBC_ARCH_X86_64)
|
||||
#error "Invalid include"
|
||||
|
@ -49,12 +49,4 @@
|
||||
#define LLVM_LIBC_ARCH_ANY_ARM
|
||||
#endif
|
||||
|
||||
#if defined(LLVM_LIBC_ARCH_AARCH64)
|
||||
#define LIBC_TARGET_HAS_FMA
|
||||
#elif defined(LLVM_LIBC_ARCH_X86_64)
|
||||
#if (defined(__AVX2__) || defined(__FMA__))
|
||||
#define LIBC_TARGET_HAS_FMA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SUPPORT_ARCHITECTURES_H
|
||||
|
43
libc/src/__support/cpu_features.h
Normal file
43
libc/src/__support/cpu_features.h
Normal file
@ -0,0 +1,43 @@
|
||||
//===-- Compile time cpu feature detection ----------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This file lists target cpu features by introspecting compiler enabled
|
||||
// preprocessor definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H
|
||||
#define LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#define LIBC_TARGET_HAS_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_2__)
|
||||
#define LIBC_TARGET_HAS_SSE4_2
|
||||
#endif
|
||||
|
||||
#if defined(__AVX__)
|
||||
#define LIBC_TARGET_HAS_AVX
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
#define LIBC_TARGET_HAS_AVX2
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
#define LIBC_TARGET_HAS_AVX512F
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512BW__)
|
||||
#define LIBC_TARGET_HAS_AVX512BW
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_FMA) || defined(__AVX2__) || defined(__FMA__)
|
||||
#define LIBC_TARGET_HAS_FMA
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H
|
@ -13,6 +13,7 @@
|
||||
#include "src/__support/FPUtil/except_value_utils.h"
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/FPUtil/sqrt.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "src/__support/FPUtil/except_value_utils.h"
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/FPUtil/nearest_integer.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/PolyEval.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#if defined(LIBC_TARGET_HAS_FMA)
|
||||
#include "range_reduction_fma.h"
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "src/__support/FPUtil/PolyEval.h"
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/__support/FPUtil/multiply_add.h"
|
||||
#include "src/__support/FPUtil/nearest_integer.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "src/math/tanhf.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/cpu_features.h"
|
||||
#include "src/math/generic/explogxf.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
@ -79,6 +79,7 @@ libc_support_library(
|
||||
hdrs = [
|
||||
"src/__support/architectures.h",
|
||||
"src/__support/common.h",
|
||||
"src/__support/cpu_features.h",
|
||||
"src/__support/endian.h",
|
||||
],
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user