diff --git a/Zend/Optimizer/ssa_integrity.c b/Zend/Optimizer/ssa_integrity.c index d92fc2e18d1fc..a2de466669ab6 100644 --- a/Zend/Optimizer/ssa_integrity.c +++ b/Zend/Optimizer/ssa_integrity.c @@ -122,7 +122,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex /* Vars */ for (i = 0; i < ssa->vars_count; i++) { zend_ssa_var *var = &ssa->vars[i]; - int use, c; + int use; uint32_t type = ssa->var_info[i].type; if (var->definition < 0 && !var->definition_phi && i > op_array->last_var) { @@ -148,23 +148,43 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex } } - c = 0; - FOREACH_USE(var, use) { - if (++c > 10000) { + use = var->use_chain; + int second_use = use; + while (use >= 0 && second_use >= 0) { + use = zend_ssa_next_use(ssa->ops, var - ssa->vars, use); + second_use = zend_ssa_next_use(ssa->ops, var - ssa->vars, second_use); + if (second_use < 0) { + break; + } + second_use = zend_ssa_next_use(ssa->ops, var - ssa->vars, second_use); + if (use == second_use) { FAIL("cycle in uses of " VARFMT "\n", VAR(i)); goto finish; } + } + + FOREACH_USE(var, use) { if (!is_used_by_op(ssa, use, i)) { fprintf(stderr, "var " VARFMT " not in uses of op %d\n", VAR(i), use); } } FOREACH_USE_END(); - c = 0; - FOREACH_PHI_USE(var, phi) { - if (++c > 10000) { + phi = var->phi_use_chain; + zend_ssa_phi *second_phi = phi; + while (phi && second_phi) { + phi = zend_ssa_next_use_phi(ssa, var - ssa->vars, phi); + second_phi = zend_ssa_next_use_phi(ssa, var - ssa->vars, second_phi); + if (!second_phi) { + break; + } + second_phi = zend_ssa_next_use_phi(ssa, var - ssa->vars, second_phi); + if (phi == second_phi) { FAIL("cycle in phi uses of " VARFMT "\n", VAR(i)); goto finish; } + } + + FOREACH_PHI_USE(var, phi) { if (!is_in_phi_sources(ssa, phi, i)) { FAIL("var " VARFMT " not in phi sources of %d\n", VAR(i), phi->ssa_var); }