]> granicus.if.org Git - php/commitdiff
Merge def and gen sets
authorNikita Popov <nikic@php.net>
Thu, 21 Apr 2016 21:12:28 +0000 (23:12 +0200)
committerNikita Popov <nikic@php.net>
Thu, 21 Apr 2016 21:32:01 +0000 (23:32 +0200)
For live-variable analysis it does not matter if def includes
variables that are previously use in the same block, the data flow
equations still have the same result. As such there is no need to
compute separate gen & def sets.

I'm keeping the name "def", because use of "gen" in this context is
pretty confusing (gen is usually the use set, not the def set).

ext/opcache/Optimizer/zend_dfg.c
ext/opcache/Optimizer/zend_dfg.h
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_ssa.c

index b45aac41fbdf63b462e4876f008cb67cb786784d..c1972128d5485304451d256b2cfdad071b931c3c 100644 (file)
@@ -25,21 +25,19 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
        int set_size;
        zend_basic_block *blocks = cfg->blocks;
        int blocks_count = cfg->blocks_count;
-       zend_bitset tmp, gen, def, use, in, out;
+       zend_bitset tmp, def, use, in, out;
        zend_op *opline;
        uint32_t k, var_num;
        int j;
 
-       /* FIXME: can we use "gen" instead of "def" for flow analyzing? */
        set_size = dfg->size;
        tmp = dfg->tmp;
-       gen = dfg->gen;
        def = dfg->def;
        use = dfg->use;
        in  = dfg->in;
        out = dfg->out;
 
-       /* Collect "gen", "def" and "use" sets */
+       /* Collect "def" and "use" sets */
        for (j = 0; j < blocks_count; j++) {
                if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
                        continue;
@@ -84,6 +82,9 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
                                                        goto op1_def;
                                                }
                                                goto op1_use;
+                                       case ZEND_UNSET_VAR:
+                                               ZEND_ASSERT(opline->extended_value & ZEND_QUICK_SET);
+                                               /* break missing intentionally */
                                        case ZEND_ASSIGN:
                                        case ZEND_ASSIGN_REF:
                                        case ZEND_BIND_GLOBAL:
@@ -92,17 +93,6 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
                                        case ZEND_SEND_REF:
                                        case ZEND_SEND_VAR_NO_REF:
                                        case ZEND_FE_RESET_RW:
-op1_def:
-                                               if (!DFG_ISSET(use, set_size, j, var_num)) {
-                                                       // FIXME: include into "use" to ...?
-                                                       DFG_SET(use, set_size, j, var_num);
-                                                       DFG_SET(def, set_size, j, var_num);
-                                               }
-                                               DFG_SET(gen, set_size, j, var_num);
-                                               break;
-                                       case ZEND_UNSET_VAR:
-                                               ZEND_ASSERT(opline->extended_value & ZEND_QUICK_SET);
-                                               /* break missing intentionally */
                                        case ZEND_ASSIGN_ADD:
                                        case ZEND_ASSIGN_SUB:
                                        case ZEND_ASSIGN_MUL:
@@ -132,7 +122,11 @@ op1_def:
                                        case ZEND_FETCH_OBJ_FUNC_ARG:
                                        case ZEND_FETCH_OBJ_UNSET:
                                        case ZEND_VERIFY_RETURN_TYPE:
-                                               DFG_SET(gen, set_size, j, var_num);
+op1_def:
+                                               // FIXME: include into "use" too ...?
+                                               DFG_SET(use, set_size, j, var_num);
+                                               DFG_SET(def, set_size, j, var_num);
+                                               break;
                                        default:
 op1_use:
                                                if (!DFG_ISSET(def, set_size, j, var_num)) {
@@ -142,9 +136,9 @@ op1_use:
                                } else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
                                        var_num = EX_VAR_TO_NUM(opline->op1.var);
                                        if (opline->opcode == ZEND_VERIFY_RETURN_TYPE) {
-                                               DFG_SET(gen, set_size, j, var_num);
-                                       }
-                                       if (!DFG_ISSET(def, set_size, j, var_num)) {
+                                               DFG_SET(use, set_size, j, var_num);
+                                               DFG_SET(def, set_size, j, var_num);
+                                       } else if (!DFG_ISSET(def, set_size, j, var_num)) {
                                                DFG_SET(use, set_size, j, var_num);
                                        }
                                }
@@ -165,12 +159,9 @@ op1_use:
                                                case ZEND_FE_FETCH_R:
                                                case ZEND_FE_FETCH_RW:
 op2_def:
-                                                       if (!DFG_ISSET(use, set_size, j, var_num)) {
-                                                               // FIXME: include into "use" to ...?
-                                                               DFG_SET(use, set_size, j, var_num);
-                                                               DFG_SET(def, set_size, j, var_num);
-                                                       }
-                                                       DFG_SET(gen, set_size, j, var_num);
+                                                       // FIXME: include into "use" too ...?
+                                                       DFG_SET(use, set_size, j, var_num);
+                                                       DFG_SET(def, set_size, j, var_num);
                                                        break;
                                                default:
 op2_use:
@@ -182,10 +173,7 @@ op2_use:
                                } else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
                                        var_num = EX_VAR_TO_NUM(opline->op2.var);
                                        if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
-                                               if (!DFG_ISSET(use, set_size, j, var_num)) {
-                                                       DFG_SET(def, set_size, j, var_num);
-                                               }
-                                               DFG_SET(gen, set_size, j, var_num);
+                                               DFG_SET(def, set_size, j, var_num);
                                        } else {
                                                if (!DFG_ISSET(def, set_size, j, var_num)) {
                                                        DFG_SET(use, set_size, j, var_num);
@@ -194,10 +182,7 @@ op2_use:
                                }
                                if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
                                        var_num = EX_VAR_TO_NUM(opline->result.var);
-                                       if (!DFG_ISSET(use, set_size, j, var_num)) {
-                                               DFG_SET(def, set_size, j, var_num);
-                                       }
-                                       DFG_SET(gen, set_size, j, var_num);
+                                       DFG_SET(def, set_size, j, var_num);
                                }
                        }
                }
index 9d864992cacfaa47ccaa994f5885c60ffc2f895f..5ed8cfc5d0d40c0892d2937625eb7c6ef98e5445 100644 (file)
@@ -26,7 +26,6 @@ typedef struct _zend_dfg {
        int         vars;
        uint32_t    size;
        zend_bitset tmp;
-       zend_bitset gen;
        zend_bitset def;
        zend_bitset use;
        zend_bitset in;
index ba5fb8a0ce536903b95f9d6f3d1804f80bd84dee..986e47034576725a3ba2eca6b5f8d17ea15fdd77 100644 (file)
@@ -1143,7 +1143,6 @@ void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zen
 
        for (j = 0; j < cfg->blocks_count; j++) {
                fprintf(stderr, "  BB%d:\n", j);
-               zend_dump_var_set(op_array, "gen", DFG_BITSET(dfg->gen, dfg->size, j));
                zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j));
                zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j));
                zend_dump_var_set(op_array, "in ", DFG_BITSET(dfg->in,  dfg->size, j));
index 9d5f5a8e184fb6cb1a099a9dae6810c3e41a4bea..c70ecc52fc6e4ea705110c93df41883e7086082d 100644 (file)
@@ -765,7 +765,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        zend_ssa_block *ssa_blocks;
        int blocks_count = ssa->cfg.blocks_count;
        uint32_t set_size;
-       zend_bitset tmp, gen, in;
+       zend_bitset tmp, def, in;
        int *var = NULL;
        int i, j, k, changed;
        zend_dfg dfg;
@@ -784,8 +784,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        dfg.size = set_size = zend_bitset_len(dfg.vars);
        dfg.tmp = do_alloca((set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1), dfg_use_heap);
        memset(dfg.tmp, 0, (set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1));
-       dfg.gen = dfg.tmp + set_size;
-       dfg.def = dfg.gen + set_size * blocks_count;
+       dfg.def = dfg.tmp + set_size;
        dfg.use = dfg.def + set_size * blocks_count;
        dfg.in  = dfg.use + set_size * blocks_count;
        dfg.out = dfg.in  + set_size * blocks_count;
@@ -800,10 +799,10 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        }
 
        tmp = dfg.tmp;
-       gen = dfg.gen;
+       def = dfg.def;
        in  = dfg.in;
 
-       /* SSA construction, Step 1: Propagate "gen" sets in merge points */
+       /* SSA construction, Step 1: Propagate "def" sets in merge points */
        do {
                changed = 0;
                for (j = 0; j < blocks_count; j++) {
@@ -811,16 +810,16 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                continue;
                        }
                        if (j >= 0 && (blocks[j].predecessors_count > 1 || j == 0)) {
-                               zend_bitset_copy(tmp, gen + (j * set_size), set_size);
+                               zend_bitset_copy(tmp, def + (j * set_size), set_size);
                                for (k = 0; k < blocks[j].predecessors_count; k++) {
                                        i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k];
                                        while (i != -1 && i != blocks[j].idom) {
-                                               zend_bitset_union_with_intersection(tmp, tmp, gen + (i * set_size), in + (j * set_size), set_size);
+                                               zend_bitset_union_with_intersection(tmp, tmp, def + (i * set_size), in + (j * set_size), set_size);
                                                i = blocks[i].idom;
                                        }
                                }
-                               if (!zend_bitset_equal(gen + (j * set_size), tmp, set_size)) {
-                                       zend_bitset_copy(gen + (j * set_size), tmp, set_size);
+                               if (!zend_bitset_equal(def + (j * set_size), tmp, set_size)) {
+                                       zend_bitset_copy(def + (j * set_size), tmp, set_size);
                                        changed = 1;
                                }
                        }
@@ -850,7 +849,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                for (k = 0; k < blocks[j].predecessors_count; k++) {
                                        i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k];
                                        while (i != -1 && i != blocks[j].idom) {
-                                               zend_bitset_union_with_intersection(tmp, tmp, gen + (i * set_size), in + (j * set_size), set_size);
+                                               zend_bitset_union_with_intersection(tmp, tmp, def + (i * set_size), in + (j * set_size), set_size);
                                                i = blocks[i].idom;
                                        }
                                }
@@ -907,7 +906,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                                        if (p) {
                                                                if (p->pi >= 0) {
                                                                        if (zend_bitset_in(in + (j * set_size), p->var) &&
-                                                                           !zend_bitset_in(gen + (i * set_size), p->var)) {
+                                                                           !zend_bitset_in(def + (i * set_size), p->var)) {
                                                                                zend_bitset_incl(tmp, p->var);
                                                                        }
                                                                } else {