@@ -122,7 +122,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex
122
122
/* Vars */
123
123
for (i = 0 ; i < ssa -> vars_count ; i ++ ) {
124
124
zend_ssa_var * var = & ssa -> vars [i ];
125
- int use , c ;
125
+ int use ;
126
126
uint32_t type = ssa -> var_info [i ].type ;
127
127
128
128
if (var -> definition < 0 && !var -> definition_phi && i > op_array -> last_var ) {
@@ -148,23 +148,45 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex
148
148
}
149
149
}
150
150
151
- c = 0 ;
152
- FOREACH_USE (var , use ) {
153
- if (++ c > 10000 ) {
151
+ /* Floyd's cycle detection algorithm, applied for use chain. */
152
+ use = var -> use_chain ;
153
+ int second_use = use ;
154
+ while (use >= 0 && second_use >= 0 ) {
155
+ use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , use );
156
+ second_use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , second_use );
157
+ if (second_use < 0 ) {
158
+ break ;
159
+ }
160
+ second_use = zend_ssa_next_use (ssa -> ops , var - ssa -> vars , second_use );
161
+ if (use == second_use ) {
154
162
FAIL ("cycle in uses of " VARFMT "\n" , VAR (i ));
155
163
goto finish ;
156
164
}
165
+ }
166
+
167
+ FOREACH_USE (var , use ) {
157
168
if (!is_used_by_op (ssa , use , i )) {
158
169
fprintf (stderr , "var " VARFMT " not in uses of op %d\n" , VAR (i ), use );
159
170
}
160
171
} FOREACH_USE_END ();
161
172
162
- c = 0 ;
163
- FOREACH_PHI_USE (var , phi ) {
164
- if (++ c > 10000 ) {
173
+ /* Floyd's cycle detection algorithm, applied for phi nodes. */
174
+ phi = var -> phi_use_chain ;
175
+ zend_ssa_phi * second_phi = phi ;
176
+ while (phi && second_phi ) {
177
+ phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , phi );
178
+ second_phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , second_phi );
179
+ if (!second_phi ) {
180
+ break ;
181
+ }
182
+ second_phi = zend_ssa_next_use_phi (ssa , var - ssa -> vars , second_phi );
183
+ if (phi == second_phi ) {
165
184
FAIL ("cycle in phi uses of " VARFMT "\n" , VAR (i ));
166
185
goto finish ;
167
186
}
187
+ }
188
+
189
+ FOREACH_PHI_USE (var , phi ) {
168
190
if (!is_in_phi_sources (ssa , phi , i )) {
169
191
FAIL ("var " VARFMT " not in phi sources of %d\n" , VAR (i ), phi -> ssa_var );
170
192
}
0 commit comments