Skip to content

Commit a5944f8

Browse files
committed
Merge def and gen sets
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).
1 parent 261eb5c commit a5944f8

File tree

4 files changed

+28
-46
lines changed

4 files changed

+28
-46
lines changed

ext/opcache/Optimizer/zend_dfg.c

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,19 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
2525
int set_size;
2626
zend_basic_block *blocks = cfg->blocks;
2727
int blocks_count = cfg->blocks_count;
28-
zend_bitset tmp, gen, def, use, in, out;
28+
zend_bitset tmp, def, use, in, out;
2929
zend_op *opline;
3030
uint32_t k, var_num;
3131
int j;
3232

33-
/* FIXME: can we use "gen" instead of "def" for flow analyzing? */
3433
set_size = dfg->size;
3534
tmp = dfg->tmp;
36-
gen = dfg->gen;
3735
def = dfg->def;
3836
use = dfg->use;
3937
in = dfg->in;
4038
out = dfg->out;
4139

42-
/* Collect "gen", "def" and "use" sets */
40+
/* Collect "def" and "use" sets */
4341
for (j = 0; j < blocks_count; j++) {
4442
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
4543
continue;
@@ -84,6 +82,9 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
8482
goto op1_def;
8583
}
8684
goto op1_use;
85+
case ZEND_UNSET_VAR:
86+
ZEND_ASSERT(opline->extended_value & ZEND_QUICK_SET);
87+
/* break missing intentionally */
8788
case ZEND_ASSIGN:
8889
case ZEND_ASSIGN_REF:
8990
case ZEND_BIND_GLOBAL:
@@ -92,17 +93,6 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
9293
case ZEND_SEND_REF:
9394
case ZEND_SEND_VAR_NO_REF:
9495
case ZEND_FE_RESET_RW:
95-
op1_def:
96-
if (!DFG_ISSET(use, set_size, j, var_num)) {
97-
// FIXME: include into "use" to ...?
98-
DFG_SET(use, set_size, j, var_num);
99-
DFG_SET(def, set_size, j, var_num);
100-
}
101-
DFG_SET(gen, set_size, j, var_num);
102-
break;
103-
case ZEND_UNSET_VAR:
104-
ZEND_ASSERT(opline->extended_value & ZEND_QUICK_SET);
105-
/* break missing intentionally */
10696
case ZEND_ASSIGN_ADD:
10797
case ZEND_ASSIGN_SUB:
10898
case ZEND_ASSIGN_MUL:
@@ -132,7 +122,11 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
132122
case ZEND_FETCH_OBJ_FUNC_ARG:
133123
case ZEND_FETCH_OBJ_UNSET:
134124
case ZEND_VERIFY_RETURN_TYPE:
135-
DFG_SET(gen, set_size, j, var_num);
125+
op1_def:
126+
// FIXME: include into "use" too ...?
127+
DFG_SET(use, set_size, j, var_num);
128+
DFG_SET(def, set_size, j, var_num);
129+
break;
136130
default:
137131
op1_use:
138132
if (!DFG_ISSET(def, set_size, j, var_num)) {
@@ -142,9 +136,9 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
142136
} else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
143137
var_num = EX_VAR_TO_NUM(opline->op1.var);
144138
if (opline->opcode == ZEND_VERIFY_RETURN_TYPE) {
145-
DFG_SET(gen, set_size, j, var_num);
146-
}
147-
if (!DFG_ISSET(def, set_size, j, var_num)) {
139+
DFG_SET(use, set_size, j, var_num);
140+
DFG_SET(def, set_size, j, var_num);
141+
} else if (!DFG_ISSET(def, set_size, j, var_num)) {
148142
DFG_SET(use, set_size, j, var_num);
149143
}
150144
}
@@ -165,12 +159,9 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
165159
case ZEND_FE_FETCH_R:
166160
case ZEND_FE_FETCH_RW:
167161
op2_def:
168-
if (!DFG_ISSET(use, set_size, j, var_num)) {
169-
// FIXME: include into "use" to ...?
170-
DFG_SET(use, set_size, j, var_num);
171-
DFG_SET(def, set_size, j, var_num);
172-
}
173-
DFG_SET(gen, set_size, j, var_num);
162+
// FIXME: include into "use" too ...?
163+
DFG_SET(use, set_size, j, var_num);
164+
DFG_SET(def, set_size, j, var_num);
174165
break;
175166
default:
176167
op2_use:
@@ -182,10 +173,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
182173
} else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
183174
var_num = EX_VAR_TO_NUM(opline->op2.var);
184175
if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
185-
if (!DFG_ISSET(use, set_size, j, var_num)) {
186-
DFG_SET(def, set_size, j, var_num);
187-
}
188-
DFG_SET(gen, set_size, j, var_num);
176+
DFG_SET(def, set_size, j, var_num);
189177
} else {
190178
if (!DFG_ISSET(def, set_size, j, var_num)) {
191179
DFG_SET(use, set_size, j, var_num);
@@ -194,10 +182,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
194182
}
195183
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
196184
var_num = EX_VAR_TO_NUM(opline->result.var);
197-
if (!DFG_ISSET(use, set_size, j, var_num)) {
198-
DFG_SET(def, set_size, j, var_num);
199-
}
200-
DFG_SET(gen, set_size, j, var_num);
185+
DFG_SET(def, set_size, j, var_num);
201186
}
202187
}
203188
}

ext/opcache/Optimizer/zend_dfg.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ typedef struct _zend_dfg {
2626
int vars;
2727
uint32_t size;
2828
zend_bitset tmp;
29-
zend_bitset gen;
3029
zend_bitset def;
3130
zend_bitset use;
3231
zend_bitset in;

ext/opcache/Optimizer/zend_dump.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,6 @@ void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zen
11431143

11441144
for (j = 0; j < cfg->blocks_count; j++) {
11451145
fprintf(stderr, " BB%d:\n", j);
1146-
zend_dump_var_set(op_array, "gen", DFG_BITSET(dfg->gen, dfg->size, j));
11471146
zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j));
11481147
zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j));
11491148
zend_dump_var_set(op_array, "in ", DFG_BITSET(dfg->in, dfg->size, j));

ext/opcache/Optimizer/zend_ssa.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
765765
zend_ssa_block *ssa_blocks;
766766
int blocks_count = ssa->cfg.blocks_count;
767767
uint32_t set_size;
768-
zend_bitset tmp, gen, in;
768+
zend_bitset tmp, def, in;
769769
int *var = NULL;
770770
int i, j, k, changed;
771771
zend_dfg dfg;
@@ -784,8 +784,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
784784
dfg.size = set_size = zend_bitset_len(dfg.vars);
785785
dfg.tmp = do_alloca((set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1), dfg_use_heap);
786786
memset(dfg.tmp, 0, (set_size * sizeof(zend_ulong)) * (blocks_count * 5 + 1));
787-
dfg.gen = dfg.tmp + set_size;
788-
dfg.def = dfg.gen + set_size * blocks_count;
787+
dfg.def = dfg.tmp + set_size;
789788
dfg.use = dfg.def + set_size * blocks_count;
790789
dfg.in = dfg.use + set_size * blocks_count;
791790
dfg.out = dfg.in + set_size * blocks_count;
@@ -800,27 +799,27 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
800799
}
801800

802801
tmp = dfg.tmp;
803-
gen = dfg.gen;
802+
def = dfg.def;
804803
in = dfg.in;
805804

806-
/* SSA construction, Step 1: Propagate "gen" sets in merge points */
805+
/* SSA construction, Step 1: Propagate "def" sets in merge points */
807806
do {
808807
changed = 0;
809808
for (j = 0; j < blocks_count; j++) {
810809
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
811810
continue;
812811
}
813812
if (j >= 0 && (blocks[j].predecessors_count > 1 || j == 0)) {
814-
zend_bitset_copy(tmp, gen + (j * set_size), set_size);
813+
zend_bitset_copy(tmp, def + (j * set_size), set_size);
815814
for (k = 0; k < blocks[j].predecessors_count; k++) {
816815
i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k];
817816
while (i != -1 && i != blocks[j].idom) {
818-
zend_bitset_union_with_intersection(tmp, tmp, gen + (i * set_size), in + (j * set_size), set_size);
817+
zend_bitset_union_with_intersection(tmp, tmp, def + (i * set_size), in + (j * set_size), set_size);
819818
i = blocks[i].idom;
820819
}
821820
}
822-
if (!zend_bitset_equal(gen + (j * set_size), tmp, set_size)) {
823-
zend_bitset_copy(gen + (j * set_size), tmp, set_size);
821+
if (!zend_bitset_equal(def + (j * set_size), tmp, set_size)) {
822+
zend_bitset_copy(def + (j * set_size), tmp, set_size);
824823
changed = 1;
825824
}
826825
}
@@ -850,7 +849,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
850849
for (k = 0; k < blocks[j].predecessors_count; k++) {
851850
i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k];
852851
while (i != -1 && i != blocks[j].idom) {
853-
zend_bitset_union_with_intersection(tmp, tmp, gen + (i * set_size), in + (j * set_size), set_size);
852+
zend_bitset_union_with_intersection(tmp, tmp, def + (i * set_size), in + (j * set_size), set_size);
854853
i = blocks[i].idom;
855854
}
856855
}
@@ -907,7 +906,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
907906
if (p) {
908907
if (p->pi >= 0) {
909908
if (zend_bitset_in(in + (j * set_size), p->var) &&
910-
!zend_bitset_in(gen + (i * set_size), p->var)) {
909+
!zend_bitset_in(def + (i * set_size), p->var)) {
911910
zend_bitset_incl(tmp, p->var);
912911
}
913912
} else {

0 commit comments

Comments
 (0)