]> granicus.if.org Git - php/commitdiff
Add ability to prevent "useless" SSA variable creation for "refcounting inference".
authorDmitry Stogov <dmitry@zend.com>
Tue, 22 Dec 2015 13:43:37 +0000 (16:43 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 22 Dec 2015 13:43:37 +0000 (16:43 +0300)
ext/opcache/Optimizer/zend_cfg.h
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c

index 0aa1096aaa021dcf478de60bedd2b2ae5dda6e8e..66ad1e5608e2be54f8626dbefc04a692db09b0e9 100644 (file)
@@ -93,6 +93,7 @@ typedef struct _zend_cfg {
 #define ZEND_CFG_STACKLESS             (1<<30)
 #define ZEND_SSA_DEBUG_LIVENESS        (1<<29)
 #define ZEND_SSA_DEBUG_PHI_PLACEMENT   (1<<28)
+#define ZEND_SSA_RC_INFERENCE          (1<<27)
 
 #define CRT_CONSTANT_EX(op_array, node, rt_constants) \
        ((rt_constants) ? \
index ebaf05807985d9f8b20debf2058d600f8d85a456..272d62b51c0d051891dcb6961dac5a31039c67e9 100644 (file)
@@ -2924,7 +2924,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
                                }
                                UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
                        }
-                       if ((opline+1)->op1_type == IS_CV) {
+                       if ((opline+1)->op1_type == IS_CV && ssa_ops[i+1].op1_def >= 0) {
                                opline++;
                                i++;
                                tmp = OP1_INFO();
@@ -2974,7 +2974,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        }
                        break;
                case ZEND_ASSIGN:
-                       if (opline->op2_type == IS_CV) {
+                       if (opline->op2_type == IS_CV && ssa_ops[i].op2_def >= 0) {
                                tmp = t2;
                                if (tmp & (MAY_BE_ANY | MAY_BE_REF)) {
                                        if (tmp & MAY_BE_RC1) {
index 0a63ecf64d85633508f3f050b8d09f07c42c981e..27f80f19f237ce928bc5a5c2fcda65409a047b14 100644 (file)
@@ -129,7 +129,7 @@ static inline zend_bool sub_will_overflow(zend_long a, zend_long b) {
                || (b < 0 && a > ZEND_LONG_MAX + b);
 }
 
-static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *var, int n) /* {{{ */
+static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
 {
        zend_basic_block *blocks = ssa->cfg.blocks;
        zend_ssa_block *ssa_blocks = ssa->blocks;
@@ -230,7 +230,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
                                                ssa_vars_count++;
                                                //NEW_SSA_VAR(opline->op1.var)
                                        }
-                                       if (opline->op2_type == IS_CV) {
+                                       if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op2_type == IS_CV) {
                                                ssa_ops[k].op2_def = ssa_vars_count;
                                                var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
                                                ssa_vars_count++;
@@ -268,7 +268,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
                                                ssa_vars_count++;
                                                //NEW_SSA_VAR(opline->op1.var)
                                        }
-                                       if (next->op1_type == IS_CV) {
+                                       if ((build_flags & ZEND_SSA_RC_INFERENCE) && next->op1_type == IS_CV) {
                                                ssa_ops[k + 1].op1_def = ssa_vars_count;
                                                var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
                                                ssa_vars_count++;
@@ -418,7 +418,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
        j = blocks[n].children;
        while (j >= 0) {
                // FIXME: Tail call optimization?
-               if (zend_ssa_rename(op_array, ssa, var, j) != SUCCESS)
+               if (zend_ssa_rename(op_array, build_flags, ssa, var, j) != SUCCESS)
                        return FAILURE;
                j = blocks[j].next_child;
        }
@@ -863,7 +863,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                var[j] = j;
        }
        ssa->vars_count = op_array->last_var;
-       if (zend_ssa_rename(op_array, ssa, var, 0) != SUCCESS) {
+       if (zend_ssa_rename(op_array, build_flags, ssa, var, 0) != SUCCESS) {
 failure:
                free_alloca(var, var_use_heap);
                free_alloca(dfg.tmp, dfg_use_heap);