From: Xinchen Hui Date: Sat, 10 Feb 2018 08:58:27 +0000 (+0800) Subject: Fixed cpu feature check in reslover functions X-Git-Tag: php-7.3.0alpha1~469 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87b71804804a0a76115267a34acd27b7d01d6e85;p=php Fixed cpu feature check in reslover functions --- diff --git a/Zend/zend.c b/Zend/zend.c index aae1d13b11..dc0cab8cc0 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -742,9 +742,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / extern zend_php_scanner_globals language_scanner_globals; #endif -#ifndef HAVE_FUNC_ATTRIBUTE_IFUNC zend_cpu_startup(); -#endif #ifdef ZEND_WIN32 php_win32_cp_set_by_id(65001); diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 2b087afaef..988ceb2521 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -16,7 +16,6 @@ +----------------------------------------------------------------------+ */ -#include "zend.h" #include "zend_cpuinfo.h" typedef struct _zend_cpu_info { @@ -68,10 +67,6 @@ void zend_cpu_startup(void) } ZEND_API int zend_cpu_supports(zend_cpu_feature feature) { -#ifdef HAVE_FUNC_ATTRIBUTE_IFUNC - /* The resolver is invoked before zend_startup(). */ - zend_cpu_startup(); -#endif if (feature & ZEND_CPU_EDX_MASK) { return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK)); } else { diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index 97e33a55cc..c077366bd8 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -19,6 +19,8 @@ #ifndef ZEND_CPU_INFO_H #define ZEND_CPU_INFO_H +#include "zend.h" + #define ZEND_CPU_EDX_MASK (1<<31) typedef enum _zend_cpu_feature { @@ -91,9 +93,72 @@ typedef enum _zend_cpu_feature { /*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/ } zend_cpu_feature; +void zend_cpu_startup(); ZEND_API int zend_cpu_supports(zend_cpu_feature feature); -void zend_cpu_startup(void); +#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS +/* NOTE: you should use following inline function in + * resolver functions (ifunc), as it could be called + * before all PLT symbols are resloved. in other words, + * resolver functions should not depends any external + * functions */ +static zend_always_inline int zend_cpu_support_sse2() { + __builtin_cpu_init(); + return __builtin_cpu_supports("sse2"); +} + +static zend_always_inline int zend_cpu_support_sse3() { + __builtin_cpu_init(); + return __builtin_cpu_supports("sse3"); +} + +static zend_always_inline int zend_cpu_support_sse41() { + __builtin_cpu_init(); + return __builtin_cpu_supports("sse4.1"); +} + +static zend_always_inline int zend_cpu_support_sse42() { + __builtin_cpu_init(); + return __builtin_cpu_supports("sse4.2"); +} + +static zend_always_inline int zend_cpu_support_avx() { + __builtin_cpu_init(); + return __builtin_cpu_supports("avx"); +} + +static zend_always_inline int zend_cpu_support_avx2() { + __builtin_cpu_init(); + return __builtin_cpu_supports("avx2"); +} +#else + +static zend_always_inline int zend_cpu_support_sse2() { + return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2); +} + +static zend_always_inline int zend_cpu_support_sse3() { + return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3); +} + +static zend_always_inline int zend_cpu_support_sse41() { + return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41); +} + +static zend_always_inline int zend_cpu_support_sse42() { + return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42); +} + +static zend_always_inline int zend_cpu_support_avx() { + return zend_cpu_supports(ZEND_CPU_FEATURE_AVX); +} + +static zend_always_inline int zend_cpu_support_avx2() { + /* TODO */ + return 0; +} + +#endif #endif diff --git a/acinclude.m4 b/acinclude.m4 index 347404bfae..d74b7b02a1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -3241,6 +3241,25 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CPU_INIT], [ ]) +dnl PHP_CHECK_BUILTIN_CPU_SUPPORTS +AC_DEFUN([PHP_CHECK_BUILTIN_CPU_SUPPORTS], [ + AC_MSG_CHECKING([for __builtin_cpu_supports]) + + AC_TRY_LINK(, [ + return __builtin_cpu_supports("sse2")? 1 : 0; + ], [ + have_builtin_cpu_supports=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_cpu_supports=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_CPU_SUPPORTS], + [$have_builtin_cpu_supports], [Whether the compiler supports __builtin_cpu_supports]) + +]) + dnl Load the AX_CHECK_COMPILE_FLAG macro from the autoconf archive. m4_include([build/ax_check_compile_flag.m4]) diff --git a/configure.ac b/configure.ac index 7c0d007254..d9f1e3fe1b 100644 --- a/configure.ac +++ b/configure.ac @@ -566,6 +566,8 @@ dnl Check __builtin_ssubl_overflow PHP_CHECK_BUILTIN_SSUBL_OVERFLOW dnl Check __builtin_ssubll_overflow PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW +dnl Check __builtin_cpu_supports +PHP_CHECK_BUILTIN_CPU_SUPPORTS dnl Check for members of the stat structure AC_STRUCT_ST_BLKSIZE diff --git a/ext/standard/string.c b/ext/standard/string.c index caaee8c1da..b90ce49861 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3873,7 +3873,7 @@ zend_string *php_addslashes_default(zend_string *str, int should_free); PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) __attribute__((ifunc("resolve_addslashes"))); static void *resolve_addslashes() { - if (zend_cpu_supports(ZEND_CPU_FEATURE_SSE42)) { + if (zend_cpu_support_sse42()) { return php_addslashes_sse42; } return php_addslashes_default;