if (NOT BUILD_AVX512)
set (DISPATCHER_DEFINE "-DDISABLE_AVX512_DISPATCH")
endif (NOT BUILD_AVX512)
+ if (NOT BUILD_AVX512VBMI)
+ set (DISPATCHER_DEFINE "${DISPATCHER_DEFINE} -DDISABLE_AVX512VBMI_DISPATCH")
+ endif (NOT BUILD_AVX512VBMI)
set_source_files_properties(src/dispatcher.c PROPERTIES
COMPILE_FLAGS "-Wno-unused-parameter -Wno-unused-function ${DISPATCHER_DEFINE}")
if (BUILD_AVX512)
add_library(hs_exec_avx512 OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
list(APPEND RUNTIME_LIBS $<TARGET_OBJECTS:hs_exec_avx512>)
- if (BUILD_AVX512VBMI)
- set_target_properties(hs_exec_avx512 PROPERTIES
- COMPILE_FLAGS "${ICELAKE_FLAG}"
- RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
- )
- else ()
- set_target_properties(hs_exec_avx512 PROPERTIES
- COMPILE_FLAGS "${SKYLAKE_FLAG}"
- RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
- )
- endif (BUILD_AVX512VBMI)
+ set_target_properties(hs_exec_avx512 PROPERTIES
+ COMPILE_FLAGS "${SKYLAKE_FLAG}"
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
endif (BUILD_AVX512)
+ if (BUILD_AVX512VBMI)
+ add_library(hs_exec_avx512vbmi OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
+ list(APPEND RUNTIME_LIBS $<TARGET_OBJECTS:hs_exec_avx512vbmi>)
+ set_target_properties(hs_exec_avx512vbmi PROPERTIES
+ COMPILE_FLAGS "${ICELAKE_FLAG}"
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512vbmi ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+ endif (BUILD_AVX512VBMI)
add_library(hs_exec_common OBJECT
${hs_exec_common_SRCS}
if (BUILD_AVX512)
add_library(hs_exec_shared_avx512 OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
list(APPEND RUNTIME_SHLIBS $<TARGET_OBJECTS:hs_exec_shared_avx512>)
- if (BUILD_AVX512VBMI)
- set_target_properties(hs_exec_shared_avx512 PROPERTIES
- COMPILE_FLAGS "${ICELAKE_FLAG}"
- POSITION_INDEPENDENT_CODE TRUE
- RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
- )
- else ()
- set_target_properties(hs_exec_shared_avx512 PROPERTIES
- COMPILE_FLAGS "${SKYLAKE_FLAG}"
- POSITION_INDEPENDENT_CODE TRUE
- RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
- )
- endif (BUILD_AVX512VBMI)
+ set_target_properties(hs_exec_shared_avx512 PROPERTIES
+ COMPILE_FLAGS "${SKYLAKE_FLAG}"
+ POSITION_INDEPENDENT_CODE TRUE
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512 ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
endif (BUILD_AVX512)
+ if (BUILD_AVX512VBMI)
+ add_library(hs_exec_shared_avx512vbmi OBJECT ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
+ list(APPEND RUNTIME_SHLIBS $<TARGET_OBJECTS:hs_exec_shared_avx512vbmi>)
+ set_target_properties(hs_exec_shared_avx512vbmi PROPERTIES
+ COMPILE_FLAGS "${ICELAKE_FLAG}"
+ POSITION_INDEPENDENT_CODE TRUE
+ RULE_LAUNCH_COMPILE "${BUILD_WRAPPER} avx512vbmi ${CMAKE_MODULE_PATH}/keep.syms.in"
+ )
+ endif (BUILD_AVX512VBMI)
add_library(hs_exec_common_shared OBJECT
${hs_exec_common_SRCS}
src/dispatcher.c
endif ()
endif ()
+if (BUILD_AVX512VBMI)
+ CHECK_C_COMPILER_FLAG(${ICELAKE_FLAG} HAS_ARCH_ICELAKE)
+ if (NOT HAS_ARCH_ICELAKE)
+ message (FATAL_ERROR "AVX512VBMI not supported by compiler")
+ endif ()
+endif ()
+
if (FAT_RUNTIME)
# test the highest level microarch to make sure everything works
if (BUILD_AVX512)
/* Define if building AVX-512 in the fat runtime. */
#cmakedefine BUILD_AVX512
+/* Define if building AVX512VBMI in the fat runtime. */
+#cmakedefine BUILD_AVX512VBMI
+
/* Define to 1 if `backtrace' works. */
#cmakedefine HAVE_BACKTRACE
As of this release, the variants of the runtime that are built, and the CPU
capability that is required, are the following:
-+----------+-------------------------------+---------------------------+
-| Variant | CPU Feature Flag(s) Required | gcc arch flag |
-+==========+===============================+===========================+
-| Core 2 | ``SSSE3`` | ``-march=core2`` |
-+----------+-------------------------------+---------------------------+
-| Core i7 | ``SSE4_2`` and ``POPCNT`` | ``-march=corei7`` |
-+----------+-------------------------------+---------------------------+
-| AVX 2 | ``AVX2`` | ``-march=core-avx2`` |
-+----------+-------------------------------+---------------------------+
-| AVX 512 | ``AVX512BW`` (see note below) | ``-march=skylake-avx512`` |
-+----------+-------------------------------+---------------------------+
++--------------+---------------------------------+---------------------------+
+| Variant | CPU Feature Flag(s) Required | gcc arch flag |
++==============+=================================+===========================+
+| Core 2 | ``SSSE3`` | ``-march=core2`` |
++--------------+---------------------------------+---------------------------+
+| Core i7 | ``SSE4_2`` and ``POPCNT`` | ``-march=corei7`` |
++--------------+---------------------------------+---------------------------+
+| AVX 2 | ``AVX2`` | ``-march=core-avx2`` |
++--------------+---------------------------------+---------------------------+
+| AVX 512 | ``AVX512BW`` (see note below) | ``-march=skylake-avx512`` |
++--------------+---------------------------------+---------------------------+
+| AVX 512 VBMI | ``AVX512VBMI`` (see note below) | ``-march=icelake-server`` |
++--------------+---------------------------------+---------------------------+
.. note::
cmake -DBUILD_AVX512=on <...>
+ Hyperscan v5.3 adds support for AVX512VBMI instructions - in particular the
+ ``AVX512VBMI`` instruction set that was introduced on Intel "Icelake" Xeon
+ processors - however the AVX512VBMI runtime variant is **not** enabled by
+ default in fat runtime builds as not all toolchains support AVX512VBMI
+ instruction sets. To build an AVX512VBMI runtime, the CMake variable
+ ``BUILD_AVX512VBMI`` must be enabled manually during configuration. For
+ example: ::
+
+ cmake -DBUILD_AVX512VBMI=on <...>
+
As the fat runtime requires compiler, libc, and binutils support, at this time
it will only be enabled for Linux builds where the compiler supports the
`indirect function "ifunc" function attribute
if (!target_info.has_avx512()) {
p |= HS_PLATFORM_NOAVX512;
}
+ if (!target_info.has_avx512vbmi()) {
+ p |= HS_PLATFORM_NOAVX512VBMI;
+ }
return p;
}
/*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
hs_error_t db_check_platform(const u64a p) {
if (p != hs_current_platform
&& p != (hs_current_platform | hs_current_platform_no_avx2)
- && p != (hs_current_platform | hs_current_platform_no_avx512)) {
+ && p != (hs_current_platform | hs_current_platform_no_avx512)
+ && p != (hs_current_platform | hs_current_platform_no_avx512vbmi)) {
return HS_DB_PLATFORM_ERROR;
}
// passed all checks
u8 minor = (version >> 16) & 0xff;
u8 major = (version >> 24) & 0xff;
- const char *features = (plat & HS_PLATFORM_NOAVX512)
- ? (plat & HS_PLATFORM_NOAVX2) ? "" : "AVX2"
- : "AVX512";
+ const char *features = (plat & HS_PLATFORM_NOAVX512VBMI)
+ ? (plat & HS_PLATFORM_NOAVX512)
+ ? (plat & HS_PLATFORM_NOAVX2) ? "" : "AVX2"
+ : "AVX512"
+ : "AVX512VBMI";
const char *mode = NULL;
/*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#define HS_PLATFORM_NOAVX2 (4<<13)
#define HS_PLATFORM_NOAVX512 (8<<13)
+#define HS_PLATFORM_NOAVX512VBMI (0x10<<13)
/** \brief Platform features bitmask. */
typedef u64a platform_t;
#endif
#if !defined(HAVE_AVX512)
HS_PLATFORM_NOAVX512 |
+#endif
+#if !defined(HAVE_AVX512VBMI)
+ HS_PLATFORM_NOAVX512VBMI |
#endif
0,
};
const platform_t hs_current_platform_no_avx2 = {
HS_PLATFORM_NOAVX2 |
HS_PLATFORM_NOAVX512 |
+ HS_PLATFORM_NOAVX512VBMI |
0,
};
static UNUSED
const platform_t hs_current_platform_no_avx512 = {
HS_PLATFORM_NOAVX512 |
+ HS_PLATFORM_NOAVX512VBMI |
+ 0,
+};
+
+static UNUSED
+const platform_t hs_current_platform_no_avx512vbmi = {
+ HS_PLATFORM_NOAVX512VBMI |
0,
};
/*
- * Copyright (c) 2016-2017, Intel Corporation
+ * Copyright (c) 2016-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#define check_avx512() (0)
#endif
+#if defined(DISABLE_AVX512VBMI_DISPATCH)
+#define avx512vbmi_ disabled_
+#define check_avx512vbmi() (0)
+#endif
+
#define CREATE_DISPATCH(RTYPE, NAME, ...) \
/* create defns */ \
+ RTYPE JOIN(avx512vbmi_, NAME)(__VA_ARGS__); \
RTYPE JOIN(avx512_, NAME)(__VA_ARGS__); \
RTYPE JOIN(avx2_, NAME)(__VA_ARGS__); \
RTYPE JOIN(corei7_, NAME)(__VA_ARGS__); \
\
/* resolver */ \
static RTYPE (*JOIN(resolve_, NAME)(void))(__VA_ARGS__) { \
+ if (check_avx512vbmi()) { \
+ return JOIN(avx512vbmi_, NAME); \
+ } \
if (check_avx512()) { \
return JOIN(avx512_, NAME); \
} \
/*
- * Copyright (c) 2015-2019, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
static
bool checkPlatform(const hs_platform_info *p, hs_compile_error **comp_error) {
- static constexpr u32 HS_TUNE_LAST = HS_TUNE_FAMILY_GLM;
+ static constexpr u32 HS_TUNE_LAST = HS_TUNE_FAMILY_ICX;
static constexpr u32 HS_CPU_FEATURES_ALL =
- HS_CPU_FEATURES_AVX2 | HS_CPU_FEATURES_AVX512;
+ HS_CPU_FEATURES_AVX2 | HS_CPU_FEATURES_AVX512 |
+ HS_CPU_FEATURES_AVX512VBMI;
if (!p) {
return true;
*/
#define HS_CPU_FEATURES_AVX512 (1ULL << 3)
+/**
+ * CPU features flag - Intel(R) Advanced Vector Extensions 512
+ * Vector Byte Manipulation Instructions (Intel(R) AVX512VBMI)
+ *
+ * Setting this flag indicates that the target platform supports AVX512VBMI
+ * instructions. Using AVX512VBMI implies the use of AVX512.
+ */
+#define HS_CPU_FEATURES_AVX512VBMI (1ULL << 4)
+
/** @} */
/**
*/
#define HS_TUNE_FAMILY_GLM 8
+/**
+ * Tuning Parameter - Intel(R) microarchitecture code name Icelake
+ *
+ * This indicates that the compiled database should be tuned for the
+ * Icelake microarchitecture.
+ */
+#define HS_TUNE_FAMILY_ICL 9
+
+/**
+ * Tuning Parameter - Intel(R) microarchitecture code name Icelake Server
+ *
+ * This indicates that the compiled database should be tuned for the
+ * Icelake Server microarchitecture.
+ */
+#define HS_TUNE_FAMILY_ICX 10
+
/** @} */
/**
/*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
cap |= HS_CPU_FEATURES_AVX512;
}
+ if (check_avx512vbmi()) {
+ DEBUG_PRINTF("AVX512VBMI enabled\n");
+ cap |= HS_CPU_FEATURES_AVX512VBMI;
+ }
+
#if !defined(FAT_RUNTIME) && !defined(HAVE_AVX2)
cap &= ~HS_CPU_FEATURES_AVX2;
#endif
cap &= ~HS_CPU_FEATURES_AVX512;
#endif
+#if (!defined(FAT_RUNTIME) && !defined(HAVE_AVX512VBMI)) || \
+ (defined(FAT_RUNTIME) && !defined(BUILD_AVX512VBMI))
+ cap &= ~HS_CPU_FEATURES_AVX512VBMI;
+#endif
+
return cap;
}
{ 0x6, 0x8E, HS_TUNE_FAMILY_SKL }, /* Kabylake Mobile */
{ 0x6, 0x9E, HS_TUNE_FAMILY_SKL }, /* Kabylake desktop */
+ { 0x6, 0x7D, HS_TUNE_FAMILY_ICL }, /* Icelake */
+ { 0x6, 0x7E, HS_TUNE_FAMILY_ICL }, /* Icelake */
+ { 0x6, 0x6A, HS_TUNE_FAMILY_ICX }, /* Icelake Xeon-D */
+ { 0x6, 0x6C, HS_TUNE_FAMILY_ICX }, /* Icelake Xeon */
+
};
#ifdef DUMP_SUPPORT
T_CASE(HS_TUNE_FAMILY_BDW);
T_CASE(HS_TUNE_FAMILY_SKL);
T_CASE(HS_TUNE_FAMILY_SKX);
+ T_CASE(HS_TUNE_FAMILY_ICL);
+ T_CASE(HS_TUNE_FAMILY_ICX);
}
#undef T_CASE
return "unknown";
/*
- * Copyright (c) 2017, Intel Corporation
+ * Copyright (c) 2017-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#define CPUID_HTT (1 << 28)
// Structured Extended Feature Flags Enumeration Leaf ECX values
+#define CPUID_AVX512VBMI (1 << 1)
+
+// Structured Extended Feature Flags Enumeration Leaf EBX values
#define CPUID_BMI (1 << 3)
#define CPUID_AVX2 (1 << 5)
#define CPUID_BMI2 (1 << 8)
-
-// Structured Extended Feature Flags Enumeration Leaf EBX values
#define CPUID_AVX512F (1 << 16)
#define CPUID_AVX512BW (1 << 30)
#endif
}
+static inline
+int check_avx512vbmi(void) {
+#if defined(__INTEL_COMPILER)
+ return _may_i_use_cpu_feature(_FEATURE_AVX512VBMI);
+#else
+ unsigned int eax, ebx, ecx, edx;
+
+ cpuid(1, 0, &eax, &ebx, &ecx, &edx);
+
+ /* check XSAVE is enabled by OS */
+ if (!(ecx & CPUID_XSAVE)) {
+ DEBUG_PRINTF("AVX and XSAVE not supported\n");
+ return 0;
+ }
+
+ /* check that AVX 512 registers are enabled by OS */
+ u64a xcr0 = xgetbv(0);
+ if ((xcr0 & CPUID_XCR0_AVX512) != CPUID_XCR0_AVX512) {
+ DEBUG_PRINTF("AVX512 registers not enabled\n");
+ return 0;
+ }
+
+ /* ECX and EDX contain capability flags */
+ ecx = 0;
+ cpuid(7, 0, &eax, &ebx, &ecx, &edx);
+
+ if (!(ebx & CPUID_AVX512F)) {
+ DEBUG_PRINTF("AVX512F (AVX512 Foundation) instructions not enabled\n");
+ return 0;
+ }
+
+ if (!(ebx & CPUID_AVX512BW)) {
+ DEBUG_PRINTF("AVX512BW instructions not enabled\n");
+ return 0;
+ }
+
+ if (ecx & CPUID_AVX512VBMI) {
+ DEBUG_PRINTF("AVX512VBMI instructions enabled\n");
+ return 1;
+ }
+
+ return 0;
+#endif
+}
+
static inline
int check_ssse3(void) {
unsigned int eax, ebx, ecx, edx;
/*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
return false;
}
+ if (!has_avx512vbmi() && code_target.has_avx512vbmi()) {
+ return false;
+ }
+
return true;
}
return cpu_features & HS_CPU_FEATURES_AVX512;
}
+bool target_t::has_avx512vbmi(void) const {
+ return cpu_features & HS_CPU_FEATURES_AVX512VBMI;
+}
+
bool target_t::is_atom_class(void) const {
return tune == HS_TUNE_FAMILY_SLM || tune == HS_TUNE_FAMILY_GLM;
}
/*
- * Copyright (c) 2015-2016, Intel Corporation
+ * Copyright (c) 2015-2020, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
bool has_avx512(void) const;
+ bool has_avx512vbmi(void) const;
+
bool is_atom_class(void) const;
// This asks: can this target (the object) run on code that was built for