]> granicus.if.org Git - php/commitdiff
Fixed copy semantics in escape analysis
authorDmitry Stogov <dmitry@zend.com>
Mon, 11 Sep 2017 17:59:40 +0000 (20:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 11 Sep 2017 17:59:40 +0000 (20:59 +0300)
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/Optimizer/escape_analysis.c
ext/opcache/tests/opt/sccp_017.phpt
ext/opcache/tests/opt/sccp_019.phpt [new file with mode: 0644]

index e014afe6701dc09707b652ed702e2fe58c0c12b8..d4b9a6a38b09c4a7fd7f10f1b75febf644167b2b 100644 (file)
@@ -107,15 +107,15 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
                return FAILURE;
        }
 
-       if (zend_ssa_escape_analysis(ctx->script, op_array, ssa) != SUCCESS) {
+       if (zend_ssa_find_sccs(op_array, ssa) != SUCCESS){
                return FAILURE;
        }
 
-       if (zend_ssa_find_sccs(op_array, ssa) != SUCCESS){
+       if (zend_ssa_inference(&ctx->arena, op_array, ctx->script, ssa) != SUCCESS) {
                return FAILURE;
        }
 
-       if (zend_ssa_inference(&ctx->arena, op_array, ctx->script, ssa) != SUCCESS) {
+       if (zend_ssa_escape_analysis(ctx->script, op_array, ssa) != SUCCESS) {
                return FAILURE;
        }
 
index 99e3d2605fb5c97586e6965387c86d35183399e0..db70bbc013ab33b27e6c6d16c6a3dcd2c1dee5f4 100644 (file)
@@ -182,13 +182,21 @@ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, in
                                            !(ce->ce_flags & ZEND_ACC_INHERITED)) {
                                                return 1;
                                        }
-                           }
+                               }
                                break;
                        case ZEND_QM_ASSIGN:
                                if (opline->op1_type == IS_CONST
                                 && Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline->op1, ssa->rt_constants)) == IS_ARRAY) {
                                        return 1;
                                }
+                               if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) {
+                                       return 1;
+                               }
+                               break;
+                       case ZEND_ASSIGN:
+                               if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) {
+                                       return 1;
+                               }
                                break;
                }
     } else if (op->op1_def == var) {
@@ -198,6 +206,9 @@ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, in
                                 && Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline->op2, ssa->rt_constants)) == IS_ARRAY) {
                                        return 1;
                                }
+                               if (opline->op2_type == IS_CV && (OP2_INFO() & MAY_BE_ARRAY)) {
+                                       return 1;
+                               }
                                break;
                        case ZEND_ASSIGN_DIM:
                        case ZEND_ASSIGN_OBJ:
index 4aa7f965091dbb765ace3a411e709e8624f8818c..a8cbcae7230e84503de20bea0883aa1eeb390a4a 100644 (file)
@@ -9,10 +9,10 @@ opcache.opt_debug_level=0x20000
 <?php require_once('skipif.inc'); ?>
 --FILE--
 <?php
-function foo() {
-       $a = [];
-       $b = $a;
+function foo(int $x) {
        $a[0] = 5;
+       $a[1] = $x;
+       $b = $a;
        $b[0] = 42;
        return $a[0];
 }
@@ -23,7 +23,8 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
     ; %ssccp_017.php:1-10
 L0:     RETURN int(1)
 
-foo: ; (lines=1, args=0, vars=0, tmps=0)
+foo: ; (lines=2, args=1, vars=1, tmps=0)
     ; (after optimizer)
     ; %ssccp_017.php:2-8
-L0:     RETURN int(5)
+L0:     CV0($x) = RECV 1
+L1:     RETURN int(5)
diff --git a/ext/opcache/tests/opt/sccp_019.phpt b/ext/opcache/tests/opt/sccp_019.phpt
new file mode 100644 (file)
index 0000000..80d4123
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+SCCP 019: Array assignemnt
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.opt_debug_level=0x20000
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function foo(int $x) {
+       $a[0] = 5;
+       $a[1] = $x;
+       $b = $a;
+       return $b[0];
+}
+?>
+--EXPECTF--
+$_main: ; (lines=1, args=0, vars=0, tmps=0)
+    ; (after optimizer)
+    ; %ssccp_019.php:1-9
+L0:     RETURN int(1)
+
+foo: ; (lines=2, args=1, vars=1, tmps=0)
+    ; (after optimizer)
+    ; %ssccp_019.php:2-7
+L0:     CV0($x) = RECV 1
+L1:     RETURN int(5)