Skip to content

Instantly share code, notes, and snippets.

@laruence
Last active February 5, 2018 06:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laruence/a94a8a3e4122f32962e0e4067360732d to your computer and use it in GitHub Desktop.
Save laruence/a94a8a3e4122f32962e0e4067360732d to your computer and use it in GitHub Desktop.
diff --git a/Zend/zend.c b/Zend/zend.c
index aae1d13..dc0cab8 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 2b087af..988ceb2 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 97e33a5..06f46d7 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 {
@@ -93,7 +95,64 @@ typedef enum _zend_cpu_feature {
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
-void zend_cpu_startup(void);
+#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS
+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 347404b..d74b7b0 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 7c0d007..d9f1e3f 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 ad75a77..df299a2 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;
[huixinchen@jx-lj-hxc.lianjia.com:/home/huixinchen/opensource/trunk/] (master)
$ git diff > cpuinfo.diff
[huixinchen@jx-lj-hxc.lianjia.com:/home/huixinchen/opensource/trunk/] (master)
$ cat cpuinfo.diff
diff --git a/Zend/zend.c b/Zend/zend.c
index aae1d13..dc0cab8 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 2b087af..988ceb2 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 97e33a5..06f46d7 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 {
@@ -93,7 +95,64 @@ typedef enum _zend_cpu_feature {
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
-void zend_cpu_startup(void);
+#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS
+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 347404b..d74b7b0 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 7c0d007..d9f1e3f 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 ad75a77..df299a2 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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment