]> granicus.if.org Git - php/commitdiff
Optimize $x === null into is_null($x)
authorDmitry Stogov <dmitry@zend.com>
Tue, 12 Nov 2019 10:49:55 +0000 (13:49 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 12 Nov 2019 10:49:55 +0000 (13:49 +0300)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_ssa.c
ext/opcache/jit/zend_jit_x86.dasc

index 982becce4b1abcfee6b52398b33b2e9667ab246c..fbbb5163f4e46b87bd351552c0993791519b3fe9 100644 (file)
@@ -7385,8 +7385,28 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
                                        break;
                                }
                        }
-               }
-               if (opcode == ZEND_CONCAT) {
+               } else if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) {
+                       /* convert $x === null to is_null($x) (i.e. ZEND_TYPE_CHECK opcode). Do the same thing for false/true. (covers IS_NULL, IS_FALSE, and IS_TRUE) */
+                       if (left_node.op_type == IS_CONST) {
+                               if (Z_TYPE(left_node.u.constant) <= IS_TRUE && Z_TYPE(left_node.u.constant) >= IS_NULL) {
+                                       zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &right_node, NULL);
+                                       opline->extended_value =
+                                               (opcode == ZEND_IS_IDENTICAL) ?
+                                                       (1 << Z_TYPE(left_node.u.constant)) :
+                                                       (MAY_BE_ANY - (1 << Z_TYPE(left_node.u.constant)));
+                                       return;
+                               }
+                       } else if (right_node.op_type == IS_CONST) {
+                               if (Z_TYPE(right_node.u.constant) <= IS_TRUE && Z_TYPE(right_node.u.constant) >= IS_NULL) {
+                                       zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &left_node, NULL);
+                                       opline->extended_value =
+                                               (opcode == ZEND_IS_IDENTICAL) ?
+                                                       (1 << Z_TYPE(right_node.u.constant)) :
+                                                       (MAY_BE_ANY - (1 << Z_TYPE(right_node.u.constant)));
+                                       return;
+                               }
+                       }
+               } else if (opcode == ZEND_CONCAT) {
                        /* convert constant operands to strings at compile-time */
                        if (left_node.op_type == IS_CONST) {
                                if (Z_TYPE(left_node.u.constant) == IS_ARRAY) {
index 01b3bcf9f2d72d07fe457105bac1e7f2fb2b2956..a8ab1ff375c42ff80204c1121490853a8725cedc 100644 (file)
@@ -7848,7 +7848,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MAS
        value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
        if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
 ZEND_VM_C_LABEL(type_check_resource):
-               if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+               if (opline->extended_value != MAY_BE_RESOURCE
                 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
                        result = 1;
                }
index a5b1e2e75244e67c5248d0473e301b854698791a..5da5452b69bebdb257ae93719257eba9f2035ff4 100644 (file)
@@ -4436,7 +4436,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_C
        value = RT_CONSTANT(opline, opline->op1);
        if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
 type_check_resource:
-               if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+               if (opline->extended_value != MAY_BE_RESOURCE
                 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
                        result = 1;
                }
@@ -13254,7 +13254,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TM
        value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
        if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
 type_check_resource:
-               if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+               if (opline->extended_value != MAY_BE_RESOURCE
                 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
                        result = 1;
                }
@@ -36407,7 +36407,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV
        value = EX_VAR(opline->op1.var);
        if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
 type_check_resource:
-               if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+               if (opline->extended_value != MAY_BE_RESOURCE
                 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
                        result = 1;
                }
index 68b3d4a99f452051ca528bd87438d179c6603f58..515532b3b4537b1ad7dd67bda76d3e78a80116f4 100644 (file)
@@ -516,7 +516,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
                                fprintf(stderr, " (bool)");
                                break;
                        default:
-                               fprintf(stderr, " (\?\?\?)");
+                               fprintf(stderr, " TYPE");
+                               zend_dump_type_info(opline->extended_value, NULL, 0, dump_flags);
                                break;
                }
        } else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) {
index 5fd4ccbd9d988983261a89ec839743611fd8411d..14d88bc39b04f37090f493e2e4908b1b98161449 100644 (file)
@@ -161,7 +161,7 @@ static inline void pi_not_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
 }
 static inline uint32_t mask_for_type_check(uint32_t type) {
        if (type & MAY_BE_ARRAY) {
-               return MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+               return type | (MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF);
        } else {
                return type;
        }
index dc40387c1b2f6020f41817e3e6fb244251e98a82..568dab3f017f979f27ccbcc83dc3aea0b7c91008 100644 (file)
@@ -8003,7 +8003,7 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, int b, i
        zend_bool smart_branch = 0;
        zend_jit_addr op1_addr = zend_jit_decode_op(op_array, opline->op1_type, opline->op1, opline, NULL, -1);
 
-       if (opline->extended_value & MAY_BE_RESOURCE) {
+       if (opline->extended_value == MAY_BE_RESOURCE) {
                // TODO: support for is_resource() ???
                goto fallback;
        }