Skip to content

Commit a22f145

Browse files
committed
[AArch64][compiler-rt] Option to build compiler-rt without FMV support.
This commit adds compiler-rt cmake option COMPILER_RT_DISABLE_AARCH64_FMV which, when enabled, doesn't include function multiversioning features initilization code in 'builtins' build. Differential Revision: https://reviews.llvm.org/D141199
1 parent ddab12d commit a22f145

File tree

3 files changed

+68
-59
lines changed

3 files changed

+68
-59
lines changed

compiler-rt/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ include(CMakeDependentOption)
4242

4343
option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON)
4444
mark_as_advanced(COMPILER_RT_BUILD_BUILTINS)
45+
option(COMPILER_RT_DISABLE_AARCH64_FMV "Disable AArch64 Function Multi Versioning support" OFF)
46+
mark_as_advanced(COMPILER_RT_DISABLE_AARCH64_FMV)
4547
option(COMPILER_RT_BUILD_CRT "Build crtbegin.o/crtend.o" ON)
4648
mark_as_advanced(COMPILER_RT_BUILD_CRT)
4749
option(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY "Use eh_frame in crtbegin.o/crtend.o" ON)

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,10 @@ else ()
770770
append_list_if(COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG VISIBILITY_HIDDEN BUILTIN_DEFS)
771771
endif()
772772

773+
if(COMPILER_RT_DISABLE_AARCH64_FMV)
774+
list(APPEND BUILTIN_DEFS DISABLE_AARCH64_FMV)
775+
endif()
776+
773777
append_list_if(COMPILER_RT_HAS_ASM_LSE HAS_ASM_LSE BUILTIN_DEFS)
774778

775779
foreach (arch ${BUILTIN_SUPPORTED_ARCH})

compiler-rt/lib/builtins/cpu_model.c

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,66 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) {
838838
return 0;
839839
}
840840
#elif defined(__aarch64__)
841+
// LSE support detection for out-of-line atomics
842+
// using HWCAP and Auxiliary vector
843+
_Bool __aarch64_have_lse_atomics
844+
__attribute__((visibility("hidden"), nocommon));
845+
846+
#if defined(__has_include)
847+
#if __has_include(<sys/auxv.h>)
848+
#include <sys/auxv.h>
849+
#if __has_include(<asm/hwcap.h>)
850+
#include <asm/hwcap.h>
851+
852+
#if defined(__ANDROID__)
853+
#include <string.h>
854+
#include <sys/system_properties.h>
855+
#elif defined(__Fuchsia__)
856+
#include <zircon/features.h>
857+
#include <zircon/syscalls.h>
858+
#endif
859+
860+
// Detect Exynos 9810 CPU
861+
#define IF_EXYNOS9810 \
862+
char arch[PROP_VALUE_MAX]; \
863+
if (__system_property_get("ro.arch", arch) > 0 && \
864+
strncmp(arch, "exynos9810", sizeof("exynos9810") - 1) == 0)
865+
866+
static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) {
867+
#if defined(__FreeBSD__)
868+
unsigned long hwcap;
869+
int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
870+
__aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0;
871+
#elif defined(__Fuchsia__)
872+
// This ensures the vDSO is a direct link-time dependency of anything that
873+
// needs this initializer code.
874+
#pragma comment(lib, "zircon")
875+
uint32_t features;
876+
zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features);
877+
__aarch64_have_lse_atomics =
878+
status == ZX_OK && (features & ZX_ARM64_FEATURE_ISA_ATOMICS) != 0;
879+
#else
880+
unsigned long hwcap = getauxval(AT_HWCAP);
881+
_Bool result = (hwcap & HWCAP_ATOMICS) != 0;
882+
#if defined(__ANDROID__)
883+
if (result) {
884+
// Some cores in the Exynos 9810 CPU are ARMv8.2 and others are ARMv8.0;
885+
// only the former support LSE atomics. However, the kernel in the
886+
// initial Android 8.0 release of Galaxy S9/S9+ devices incorrectly
887+
// reported the feature as being supported.
888+
//
889+
// The kernel appears to have been corrected to mark it unsupported as of
890+
// the Android 9.0 release on those devices, and this issue has not been
891+
// observed anywhere else. Thus, this workaround may be removed if
892+
// compiler-rt ever drops support for Android 8.0.
893+
IF_EXYNOS9810 result = false;
894+
}
895+
#endif // defined(__ANDROID__)
896+
__aarch64_have_lse_atomics = result;
897+
#endif // defined(__FreeBSD__)
898+
}
899+
900+
#if !defined(DISABLE_AARCH64_FMV)
841901
// CPUFeatures must correspond to the same AArch64 features in
842902
// AArch64TargetParser.h
843903
enum CPUFeatures {
@@ -901,27 +961,17 @@ enum CPUFeatures {
901961
FEAT_SME2,
902962
FEAT_MAX
903963
};
964+
904965
// Architecture features used
905966
// in Function Multi Versioning
906967
struct {
907968
unsigned long long features;
908969
// As features grows new fields could be added
909970
} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
910971

911-
// LSE support detection for out-of-line atomics
912-
// using HWCAP and Auxiliary vector
913-
_Bool __aarch64_have_lse_atomics
914-
__attribute__((visibility("hidden"), nocommon));
915-
#if defined(__has_include)
916-
#if __has_include(<sys/auxv.h>)
917-
#include <sys/auxv.h>
918-
#if __has_include(<asm/hwcap.h>)
919-
#include <asm/hwcap.h>
920-
921972
#ifndef AT_HWCAP
922973
#define AT_HWCAP 16
923974
#endif
924-
925975
#ifndef HWCAP_CPUID
926976
#define HWCAP_CPUID (1 << 11)
927977
#endif
@@ -1086,54 +1136,6 @@ _Bool __aarch64_have_lse_atomics
10861136
#define HWCAP2_SVE_EBF16 (1UL << 33)
10871137
#endif
10881138

1089-
#if defined(__ANDROID__)
1090-
#include <string.h>
1091-
#include <sys/system_properties.h>
1092-
#elif defined(__Fuchsia__)
1093-
#include <zircon/features.h>
1094-
#include <zircon/syscalls.h>
1095-
#endif
1096-
1097-
// Detect Exynos 9810 CPU
1098-
#define IF_EXYNOS9810 \
1099-
char arch[PROP_VALUE_MAX]; \
1100-
if (__system_property_get("ro.arch", arch) > 0 && \
1101-
strncmp(arch, "exynos9810", sizeof("exynos9810") - 1) == 0)
1102-
1103-
static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) {
1104-
#if defined(__FreeBSD__)
1105-
unsigned long hwcap;
1106-
int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
1107-
__aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0;
1108-
#elif defined(__Fuchsia__)
1109-
// This ensures the vDSO is a direct link-time dependency of anything that
1110-
// needs this initializer code.
1111-
#pragma comment(lib, "zircon")
1112-
uint32_t features;
1113-
zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features);
1114-
__aarch64_have_lse_atomics =
1115-
status == ZX_OK && (features & ZX_ARM64_FEATURE_ISA_ATOMICS) != 0;
1116-
#else
1117-
unsigned long hwcap = getauxval(AT_HWCAP);
1118-
_Bool result = (hwcap & HWCAP_ATOMICS) != 0;
1119-
#if defined(__ANDROID__)
1120-
if (result) {
1121-
// Some cores in the Exynos 9810 CPU are ARMv8.2 and others are ARMv8.0;
1122-
// only the former support LSE atomics. However, the kernel in the
1123-
// initial Android 8.0 release of Galaxy S9/S9+ devices incorrectly
1124-
// reported the feature as being supported.
1125-
//
1126-
// The kernel appears to have been corrected to mark it unsupported as of
1127-
// the Android 9.0 release on those devices, and this issue has not been
1128-
// observed anywhere else. Thus, this workaround may be removed if
1129-
// compiler-rt ever drops support for Android 8.0.
1130-
IF_EXYNOS9810 result = false;
1131-
}
1132-
#endif // defined(__ANDROID__)
1133-
__aarch64_have_lse_atomics = result;
1134-
#endif // defined(__FreeBSD__)
1135-
}
1136-
11371139
void init_cpu_features_resolver(unsigned long hwcap, unsigned long hwcap2) {
11381140
#define setCPUFeature(F) __aarch64_cpu_features.features |= 1ULL << F
11391141
#define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr))
@@ -1344,6 +1346,7 @@ void CONSTRUCTOR_ATTRIBUTE init_cpu_features(void) {
13441346
#undef setCPUFeature
13451347
#undef IF_EXYNOS9810
13461348
}
1349+
#endif // !defined(DISABLE_AARCH64_FMV)
13471350
#endif // defined(__has_include)
13481351
#endif // __has_include(<sys/auxv.h>)
13491352
#endif // __has_include(<asm/hwcap.h>)

0 commit comments

Comments
 (0)