Fixed cpu feature check in reslover functions

This commit is contained in:
Xinchen Hui 2018-02-10 16:58:27 +08:00
parent ab44dddfe4
commit 87b7180480
6 changed files with 88 additions and 9 deletions

View file

@ -742,9 +742,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
extern zend_php_scanner_globals language_scanner_globals; extern zend_php_scanner_globals language_scanner_globals;
#endif #endif
#ifndef HAVE_FUNC_ATTRIBUTE_IFUNC
zend_cpu_startup(); zend_cpu_startup();
#endif
#ifdef ZEND_WIN32 #ifdef ZEND_WIN32
php_win32_cp_set_by_id(65001); php_win32_cp_set_by_id(65001);

View file

@ -16,7 +16,6 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
#include "zend.h"
#include "zend_cpuinfo.h" #include "zend_cpuinfo.h"
typedef struct _zend_cpu_info { typedef struct _zend_cpu_info {
@ -68,10 +67,6 @@ void zend_cpu_startup(void)
} }
ZEND_API int zend_cpu_supports(zend_cpu_feature feature) { 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) { if (feature & ZEND_CPU_EDX_MASK) {
return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK)); return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK));
} else { } else {

View file

@ -19,6 +19,8 @@
#ifndef ZEND_CPU_INFO_H #ifndef ZEND_CPU_INFO_H
#define ZEND_CPU_INFO_H #define ZEND_CPU_INFO_H
#include "zend.h"
#define ZEND_CPU_EDX_MASK (1<<31) #define ZEND_CPU_EDX_MASK (1<<31)
typedef enum _zend_cpu_feature { typedef enum _zend_cpu_feature {
@ -91,9 +93,72 @@ typedef enum _zend_cpu_feature {
/*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/ /*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/
} zend_cpu_feature; } zend_cpu_feature;
void zend_cpu_startup();
ZEND_API int zend_cpu_supports(zend_cpu_feature feature); 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 #endif

View file

@ -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. dnl Load the AX_CHECK_COMPILE_FLAG macro from the autoconf archive.
m4_include([build/ax_check_compile_flag.m4]) m4_include([build/ax_check_compile_flag.m4])

View file

@ -566,6 +566,8 @@ dnl Check __builtin_ssubl_overflow
PHP_CHECK_BUILTIN_SSUBL_OVERFLOW PHP_CHECK_BUILTIN_SSUBL_OVERFLOW
dnl Check __builtin_ssubll_overflow dnl Check __builtin_ssubll_overflow
PHP_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 dnl Check for members of the stat structure
AC_STRUCT_ST_BLKSIZE AC_STRUCT_ST_BLKSIZE

View file

@ -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"))); PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) __attribute__((ifunc("resolve_addslashes")));
static void *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_sse42;
} }
return php_addslashes_default; return php_addslashes_default;