]> granicus.if.org Git - php/commitdiff
Introduce ZEND_ASSUME() macro to help optimizing code.
authorDmitry Stogov <dmitry@zend.com>
Tue, 24 Mar 2015 09:21:06 +0000 (12:21 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 24 Mar 2015 09:21:06 +0000 (12:21 +0300)
Reuse ZEND_ASSERT() conditions for optimization.

Zend/zend_portability.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 0743141437435cd610fefffa3da8715531c742d4..05ef0df53ef64afaeef7a295a5f299bdd00f2176 100644 (file)
 #include <intrin.h>
 #endif
 
+/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
+#ifdef __GNUC__
+# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#else
+# define ZEND_GCC_VERSION 0
+#endif
+
+#if defined(ZEND_WIN32)
+# define ZEND_ASSUME(c)        __assume(c)
+#elif defined(__GNUC__) && PHP_HAVE_BUILTIN_EXPECT && ZEND_GCC_VERSION >= 4005
+# define ZEND_ASSUME(c)        do { \
+               if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \
+       } while (0)
+#else
+# define ZEND_ASSUME(c)
+#endif
+
+#if ZEND_DEBUG
+# define ZEND_ASSERT(c)        assert(c)
+#else
+# define ZEND_ASSERT(c) ZEND_ASSUME(c)
+#endif
+
 /* Only use this macro if you know for sure that all of the switches values
    are covered by its case statements */
 #if ZEND_DEBUG
 # define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
-#elif defined(ZEND_WIN32)
-# define EMPTY_SWITCH_DEFAULT_CASE() default: __assume(0); break;
 #else
-# define EMPTY_SWITCH_DEFAULT_CASE()
+# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSUME(0); break;
 #endif
 
 /* all HAVE_XXX test have to be after the include of zend_config above */
@@ -145,13 +166,6 @@ char *alloca();
 # define __has_attribute(x) 0
 #endif
 
-/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
-#ifdef __GNUC__
-# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
-#else
-# define ZEND_GCC_VERSION 0
-#endif
-
 #if ZEND_GCC_VERSION >= 2096
 # define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
 #else
@@ -337,7 +351,6 @@ char *alloca();
 # define ZEND_FILE_LINE_EMPTY_CC               , ZEND_FILE_LINE_EMPTY_C
 # define ZEND_FILE_LINE_ORIG_RELAY_C   __zend_orig_filename, __zend_orig_lineno
 # define ZEND_FILE_LINE_ORIG_RELAY_CC  , ZEND_FILE_LINE_ORIG_RELAY_C
-# define ZEND_ASSERT(c)                                        assert(c)
 #else
 # define ZEND_FILE_LINE_D
 # define ZEND_FILE_LINE_DC
@@ -351,7 +364,6 @@ char *alloca();
 # define ZEND_FILE_LINE_EMPTY_CC
 # define ZEND_FILE_LINE_ORIG_RELAY_C
 # define ZEND_FILE_LINE_ORIG_RELAY_CC
-# define ZEND_ASSERT(c)
 #endif /* ZEND_DEBUG */
 
 #if ZEND_DEBUG
index 95408ebdd40bc4f4bc95307919db6df68268a127..ed4c7191a7ae1f67d8209f6c08132d9d2f89a0d4 100644 (file)
@@ -3229,10 +3229,12 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY)
 
        fbc->internal_function.handler(call, ret);
 
+#if ZEND_DEBUG
        ZEND_ASSERT(
                !call->func ||
                !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
        EG(current_execute_data) = call->prev_execute_data;
        zend_vm_stack_free_args(call);
@@ -3357,10 +3359,12 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
 
                fbc->internal_function.handler(call, ret);
 
+#if ZEND_DEBUG
                ZEND_ASSERT(
                        !call->func ||
                        !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                        zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
                EG(current_execute_data) = call->prev_execute_data;
                zend_vm_stack_free_args(call);
@@ -3494,10 +3498,12 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
                        zend_execute_internal(call, ret);
                }
                
+#if ZEND_DEBUG
                ZEND_ASSERT(
                        !call->func ||
                        !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                        zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
                EG(current_execute_data) = call->prev_execute_data;
                zend_vm_stack_free_args(call);
index eb551ee15fc5feeb53cea25969aeba7d3de07678..ebec22ed84a8126e8770ee33d1eda773d4b65bd9 100644 (file)
@@ -560,10 +560,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPC
 
        fbc->internal_function.handler(call, ret);
 
+#if ZEND_DEBUG
        ZEND_ASSERT(
                !call->func ||
                !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
        EG(current_execute_data) = call->prev_execute_data;
        zend_vm_stack_free_args(call);
@@ -688,10 +690,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(
 
                fbc->internal_function.handler(call, ret);
 
+#if ZEND_DEBUG
                ZEND_ASSERT(
                        !call->func ||
                        !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                        zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
                EG(current_execute_data) = call->prev_execute_data;
                zend_vm_stack_free_args(call);
@@ -825,10 +829,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC
                        zend_execute_internal(call, ret);
                }
 
+#if ZEND_DEBUG
                ZEND_ASSERT(
                        !call->func ||
                        !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
                        zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+#endif
 
                EG(current_execute_data) = call->prev_execute_data;
                zend_vm_stack_free_args(call);