]> granicus.if.org Git - php/commitdiff
Improve type inference
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Mar 2020 14:41:47 +0000 (15:41 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Mar 2020 14:41:47 +0000 (15:41 +0100)
After thinking about this a bit more, the code here was too
conservative. We know that everything but an object is going to
throw, so it's sufficient to restrict the type to MAY_BE_OBJECT.

The change in the test is weird but not incorrect, because it
operates on empty inferred types, in which case the code must be
dead (which it is). We should probably add a more explicit removal
of code working on empty types.

ext/opcache/Optimizer/zend_inference.c
ext/opcache/tests/opt/sccp_022.phpt

index fda79894249110d849d75a80ed37d089880a91cf..b6bf6eb4742cea76a98650533df6a327da0f581d 100644 (file)
@@ -2525,10 +2525,8 @@ static zend_always_inline int _zend_update_type_info(
                                }
                        } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
                                if (opline->op1_type == IS_CV) {
-                                       if (orig & MAY_BE_OBJECT) {
-                                               orig |= (MAY_BE_RC1|MAY_BE_RCN);
-                                       }
-                                       UPDATE_SSA_TYPE(orig, ssa_op->op1_def);
+                                       tmp = (orig & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
+                                       UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
                                        COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
                                }
                        } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP) {
@@ -2728,10 +2726,7 @@ static zend_always_inline int _zend_update_type_info(
                        break;
                case ZEND_ASSIGN_OBJ:
                        if (opline->op1_type == IS_CV) {
-                               tmp = t1;
-                               if (tmp & MAY_BE_OBJECT) {
-                                       tmp |= MAY_BE_RC1 | MAY_BE_RCN;
-                               }
+                               tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
                                UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
                                COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
                        }
@@ -2774,10 +2769,7 @@ static zend_always_inline int _zend_update_type_info(
                case ZEND_POST_INC_OBJ:
                case ZEND_POST_DEC_OBJ:
                        if (opline->op1_type == IS_CV) {
-                               tmp = t1;
-                               if (tmp & MAY_BE_OBJECT) {
-                                       tmp |= MAY_BE_RC1 | MAY_BE_RCN;
-                               }
+                               tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
                                UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
                                COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
                        }
index 000b1ab8b3a6b3d3ad1251ddd74d70355c1aaeba..c69e57176e53371bf3c4ff7ab28dd697b952431a 100644 (file)
@@ -24,7 +24,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
     ; %ssccp_022.php:1-10
 L0 (10):    RETURN int(1)
 
-foo: ; (lines=11, args=1, vars=2, tmps=1)
+foo: ; (lines=10, args=1, vars=2, tmps=1)
     ; (after optimizer)
     ; %ssccp_022.php:2-8
 L0 (2):     CV0($x) = RECV 1
@@ -35,6 +35,5 @@ L4 (4):     OP_DATA int(5)
 L5 (5):     ECHO string("5")
 L6 (6):     ASSIGN_OBJ CV1($a) string("foo")
 L7 (6):     OP_DATA int(5)
-L8 (7):     T2 = FETCH_DIM_R CV1($a) int(1)
-L9 (7):     ECHO T2
-L10 (8):    RETURN null
+L8 (7):     T2 = FETCH_DIM_R null int(1)
+L9 (8):     RETURN null