From 1ba6e66c46911a7f0b7a50f1199202c13393f654 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 17 Mar 2020 15:41:47 +0100 Subject: [PATCH] Improve type inference 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 | 16 ++++------------ ext/opcache/tests/opt/sccp_022.phpt | 7 +++---- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index fda7989424..b6bf6eb474 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -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); } diff --git a/ext/opcache/tests/opt/sccp_022.phpt b/ext/opcache/tests/opt/sccp_022.phpt index 000b1ab8b3..c69e57176e 100644 --- a/ext/opcache/tests/opt/sccp_022.phpt +++ b/ext/opcache/tests/opt/sccp_022.phpt @@ -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 -- 2.40.0