#define LOG_NEG_RANGE(...)
#endif
+/* Pop elements in unspecified order from worklist until it is empty */
+#define WHILE_WORKLIST(worklist, len, i) do { \
+ zend_bool _done = 0; \
+ while (!_done) { \
+ _done = 1; \
+ ZEND_BITSET_FOREACH(worklist, len, i) { \
+ zend_bitset_excl(worklist, i); \
+ _done = 0;
+
+#define WHILE_WORKLIST_END() \
+ } ZEND_BITSET_FOREACH_END(); \
+ } \
+} while (0)
+
#define CHECK_SCC_VAR(var2) \
do { \
if (!ssa->vars[var2].no_val) { \
}
}
- while ((i = zend_bitset_first(worklist, zend_bitset_len(ssa_vars_count))) >= 0) {
- zend_bitset_excl(worklist, i);
+ WHILE_WORKLIST(worklist, zend_bitset_len(ssa_vars_count), i) {
if (ssa_vars[i].definition_phi) {
/* mark all possible sources as used */
p = ssa_vars[i].definition_phi;
}
}
}
- }
+ } WHILE_WORKLIST_END();
free_alloca(worklist, use_heap);
memset(visited, 0, sizeof(zend_ulong) * worklist_len);
- while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
- zend_bitset_excl(worklist, j);
+ WHILE_WORKLIST(worklist, worklist_len, j) {
if (zend_inference_calc_range(op_array, ssa, j, 0, 0, &tmp)) {
#ifdef NEG_RANGE
if (!has_inner_cycles &&
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR_1);
}
}
- }
+ } WHILE_WORKLIST_END();
}
free_alloca(worklist, use_heap);
}
#endif
/* widening */
- while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
- zend_bitset_excl(worklist, j);
+ WHILE_WORKLIST(worklist, worklist_len, j) {
if (zend_ssa_range_widening(op_array, ssa, j, scc)) {
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR);
}
- }
+ } WHILE_WORKLIST_END();
/* Add all SCC entry variables into worklist for narrowing */
for (j = scc_var[scc]; j >= 0; j = next_scc_var[j]) {
}
/* narrowing */
- while ((j = zend_bitset_first(worklist, worklist_len)) >= 0) {
- zend_bitset_excl(worklist, j);
+ WHILE_WORKLIST(worklist, worklist_len, j) {
if (zend_ssa_range_narrowing(op_array, ssa, j, scc)) {
FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR);
#ifdef SYM_RANGE
}
#endif
}
- }
+ } WHILE_WORKLIST_END();
}
}
int i, j;
uint32_t tmp;
- while ((j = zend_bitset_first(worklist, zend_bitset_len(ssa_vars_count))) >= 0) {
- zend_bitset_excl(worklist, j);
+ WHILE_WORKLIST(worklist, zend_bitset_len(ssa_vars_count), j) {
if (ssa_vars[j].definition_phi) {
zend_ssa_phi *p = ssa_vars[j].definition_phi;
if (p->pi >= 0) {
i = ssa_vars[j].definition;
zend_update_type_info(op_array, ssa, script, worklist, i);
}
- }
+ } WHILE_WORKLIST_END();
return SUCCESS;
}
}
call_info = call_info->next_callee;
}
- while ((i = zend_bitset_first(worklist, worklist_len)) >= 0) {
- zend_bitset_excl(worklist, i);
+ WHILE_WORKLIST(worklist, worklist_len, i) {
if (!info->ssa.var_info[i].recursive) {
info->ssa.var_info[i].recursive = 1;
add_usages(op_array, &info->ssa, worklist, i);
}
- }
+ } WHILE_WORKLIST_END();
free_alloca(worklist, use_heap);
}