Skip to content

Commit 052aa46

Browse files
committed
Further optimize worklist management
Instead of always popping the first elements, do multiple complete iterations of the worklist until it is empty.
1 parent e60515f commit 052aa46

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

ext/opcache/Optimizer/zend_inference.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,20 @@
5858
#define LOG_NEG_RANGE(...)
5959
#endif
6060

61+
/* Pop elements in unspecified order from worklist until it is empty */
62+
#define WHILE_WORKLIST(worklist, len, i) do { \
63+
zend_bool _done = 0; \
64+
while (!_done) { \
65+
_done = 1; \
66+
ZEND_BITSET_FOREACH(worklist, len, i) { \
67+
zend_bitset_excl(worklist, i); \
68+
_done = 0;
69+
70+
#define WHILE_WORKLIST_END() \
71+
} ZEND_BITSET_FOREACH_END(); \
72+
} \
73+
} while (0)
74+
6175
#define CHECK_SCC_VAR(var2) \
6276
do { \
6377
if (!ssa->vars[var2].no_val) { \
@@ -269,8 +283,7 @@ int zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ss
269283
}
270284
}
271285

272-
while ((i = zend_bitset_first(worklist, zend_bitset_len(ssa_vars_count))) >= 0) {
273-
zend_bitset_excl(worklist, i);
286+
WHILE_WORKLIST(worklist, zend_bitset_len(ssa_vars_count), i) {
274287
if (ssa_vars[i].definition_phi) {
275288
/* mark all possible sources as used */
276289
p = ssa_vars[i].definition_phi;
@@ -288,7 +301,7 @@ int zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ss
288301
}
289302
}
290303
}
291-
}
304+
} WHILE_WORKLIST_END();
292305

293306
free_alloca(worklist, use_heap);
294307

@@ -1567,8 +1580,7 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss
15671580

15681581
memset(visited, 0, sizeof(zend_ulong) * worklist_len);
15691582

1570-
while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
1571-
zend_bitset_excl(worklist, j);
1583+
WHILE_WORKLIST(worklist, worklist_len, j) {
15721584
if (zend_inference_calc_range(op_array, ssa, j, 0, 0, &tmp)) {
15731585
#ifdef NEG_RANGE
15741586
if (!has_inner_cycles &&
@@ -1623,7 +1635,7 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss
16231635
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR_1);
16241636
}
16251637
}
1626-
}
1638+
} WHILE_WORKLIST_END();
16271639
}
16281640
free_alloca(worklist, use_heap);
16291641
}
@@ -1686,12 +1698,11 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
16861698
#endif
16871699

16881700
/* widening */
1689-
while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
1690-
zend_bitset_excl(worklist, j);
1701+
WHILE_WORKLIST(worklist, worklist_len, j) {
16911702
if (zend_ssa_range_widening(op_array, ssa, j, scc)) {
16921703
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR);
16931704
}
1694-
}
1705+
} WHILE_WORKLIST_END();
16951706

16961707
/* Add all SCC entry variables into worklist for narrowing */
16971708
for (j = scc_var[scc]; j >= 0; j = next_scc_var[j]) {
@@ -1702,8 +1713,7 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
17021713
}
17031714

17041715
/* narrowing */
1705-
while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
1706-
zend_bitset_excl(worklist, j);
1716+
WHILE_WORKLIST(worklist, worklist_len, j) {
17071717
if (zend_ssa_range_narrowing(op_array, ssa, j, scc)) {
17081718
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR);
17091719
#ifdef SYM_RANGE
@@ -1715,7 +1725,7 @@ static int zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* {{
17151725
}
17161726
#endif
17171727
}
1718-
}
1728+
} WHILE_WORKLIST_END();
17191729
}
17201730
}
17211731

@@ -3264,8 +3274,7 @@ int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script
32643274
int i, j;
32653275
uint32_t tmp;
32663276

3267-
while ((j = zend_bitset_first(worklist, zend_bitset_len(ssa_vars_count))) >= 0) {
3268-
zend_bitset_excl(worklist, j);
3277+
WHILE_WORKLIST(worklist, zend_bitset_len(ssa_vars_count), j) {
32693278
if (ssa_vars[j].definition_phi) {
32703279
zend_ssa_phi *p = ssa_vars[j].definition_phi;
32713280
if (p->pi >= 0) {
@@ -3322,7 +3331,7 @@ int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script
33223331
i = ssa_vars[j].definition;
33233332
zend_update_type_info(op_array, ssa, script, worklist, i);
33243333
}
3325-
}
3334+
} WHILE_WORKLIST_END();
33263335
return SUCCESS;
33273336
}
33283337

@@ -3894,13 +3903,12 @@ void zend_inference_check_recursive_dependencies(zend_op_array *op_array)
38943903
}
38953904
call_info = call_info->next_callee;
38963905
}
3897-
while ((i = zend_bitset_first(worklist, worklist_len)) >= 0) {
3898-
zend_bitset_excl(worklist, i);
3906+
WHILE_WORKLIST(worklist, worklist_len, i) {
38993907
if (!info->ssa.var_info[i].recursive) {
39003908
info->ssa.var_info[i].recursive = 1;
39013909
add_usages(op_array, &info->ssa, worklist, i);
39023910
}
3903-
}
3911+
} WHILE_WORKLIST_END();
39043912
free_alloca(worklist, use_heap);
39053913
}
39063914

0 commit comments

Comments
 (0)