]> granicus.if.org Git - php/commitdiff
Fixed SCCP on PHI(contant_array, partial_array)
authorXinchen Hui <laruence@gmail.com>
Sat, 2 Sep 2017 10:16:40 +0000 (18:16 +0800)
committerXinchen Hui <laruence@gmail.com>
Sat, 2 Sep 2017 10:16:40 +0000 (18:16 +0800)
ext/opcache/Optimizer/sccp.c
ext/opcache/tests/opt/sccp_013.phpt [new file with mode: 0644]

index a644a49756304e54a52d4e995e6392791c98b12c..8065a72cbf6988bbf305088f492d07269e57b28f 100644 (file)
@@ -133,7 +133,7 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, zval *new) {
 
        if (IS_BOT(new)) {
                SCP_DEBUG("Lowering var %d to BOT\n", var);
-       } else {
+       } else if (!IS_PARTIAL_ARRAY(new) && !IS_PARTIAL_OBJECT(new)) {
                SCP_DEBUG("Lowering var %d to %Z\n", var, new);
        }
 
@@ -144,6 +144,14 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, zval *new) {
                return;
        }
 
+       /* PARTIAL_ARRAY is lower than IS_ARRAY */
+       if (Z_TYPE_P(value) == IS_ARRAY && IS_PARTIAL_ARRAY(new)) {
+               zval_ptr_dtor_nogc(value);
+               ZVAL_COPY(value, new);
+               scdf_add_to_worklist(scdf, var);
+               return;
+       }
+
 #if ZEND_DEBUG
        ZEND_ASSERT(IS_PARTIAL_ARRAY(new) || IS_PARTIAL_OBJECT(new) || zend_is_identical(value, new));
 #endif
@@ -1035,7 +1043,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                                if (!op2 && IS_PARTIAL_ARRAY(&zv)) {
                                        /* We can't add NEXT element into partial array (skip it) */
                                        SET_RESULT(result, data);
-                                       SET_RESULT(result, &zv);
+                                       SET_RESULT(op1, &zv);
                                } else if (ct_eval_assign_dim(&zv, data, op2) == SUCCESS) {
                                        SET_RESULT(result, data);
                                        SET_RESULT(op1, &zv);
@@ -2127,7 +2135,7 @@ static int replace_constant_operands(sccp_ctx *ctx) {
                        if (!Z_DELREF(ctx->values[i])) {
                                zend_array_destroy(Z_ARR(ctx->values[i]));
                        }
-                       Z_TYPE_INFO(ctx->values[i]) = BOT;
+                       MAKE_BOT(&ctx->values[i]);
                        if ((var->use_chain < 0 && var->phi_use_chain == NULL) || var->no_val) {
                                removed_ops += try_remove_definition(ctx, i, var, NULL);
                        }
diff --git a/ext/opcache/tests/opt/sccp_013.phpt b/ext/opcache/tests/opt/sccp_013.phpt
new file mode 100644 (file)
index 0000000..052e92f
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+SCCP 013: Conditional Constant Propagation of non-escaping array elements on PHI
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function loadEntities($entity_information) {
+       $entity_types = [];
+       foreach ($entity_information as $info) {
+               $entity_types[$info] = 1;
+       }
+       var_dump((bool)($entity_types[$info]));
+}
+
+loadEntities(array("first", "second")); 
+--EXPECT--
+bool(true)