@@ -276,6 +276,93 @@ static zend_bool try_replace_op1(
276276 zval zv ;
277277 ZVAL_COPY (& zv , value );
278278 if (zend_optimizer_update_op1_const (ctx -> scdf .op_array , opline , & zv )) {
279+ /* Reconstruct SSA */
280+ int num ;
281+ zend_basic_block * block ;
282+
283+ switch (opline -> opcode ) {
284+ case ZEND_JMPZ :
285+ if (zend_is_true (& zv )) {
286+ MAKE_NOP (opline );
287+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
288+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
289+ if (block -> successors_count == 2 ) {
290+ if (block -> successors [1 ] != block -> successors [0 ]) {
291+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [0 ]);
292+ }
293+ block -> successors_count = 1 ;
294+ block -> successors [0 ] = block -> successors [1 ];
295+ }
296+ } else {
297+ opline -> opcode = ZEND_JMP ;
298+ COPY_NODE (opline -> op1 , opline -> op2 );
299+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
300+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
301+ if (block -> successors_count == 2 ) {
302+ if (block -> successors [1 ] != block -> successors [0 ]) {
303+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [1 ]);
304+ }
305+ block -> successors_count = 1 ;
306+ }
307+ }
308+ break ;
309+ case ZEND_JMPNZ :
310+ if (zend_is_true (& zv )) {
311+ opline -> opcode = ZEND_JMP ;
312+ COPY_NODE (opline -> op1 , opline -> op2 );
313+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
314+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
315+ if (block -> successors_count == 2 ) {
316+ if (block -> successors [1 ] != block -> successors [0 ]) {
317+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [1 ]);
318+ }
319+ block -> successors_count = 1 ;
320+ }
321+ } else {
322+ MAKE_NOP (opline );
323+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
324+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
325+ if (block -> successors_count == 2 ) {
326+ if (block -> successors [1 ] != block -> successors [0 ]) {
327+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [0 ]);
328+ }
329+ block -> successors_count = 1 ;
330+ block -> successors [0 ] = block -> successors [1 ];
331+ }
332+ }
333+ break ;
334+ case ZEND_JMPZNZ :
335+ if (zend_is_true (& zv )) {
336+ zend_op * target_opline = ZEND_OFFSET_TO_OPLINE (opline , opline -> extended_value );
337+ ZEND_SET_OP_JMP_ADDR (opline , opline -> op1 , target_opline );
338+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
339+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
340+ if (block -> successors_count == 2 ) {
341+ if (block -> successors [1 ] != block -> successors [0 ]) {
342+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [0 ]);
343+ }
344+ block -> successors_count = 1 ;
345+ block -> successors [0 ] = block -> successors [1 ];
346+ }
347+ } else {
348+ zend_op * target_opline = ZEND_OP2_JMP_ADDR (opline );
349+ ZEND_SET_OP_JMP_ADDR (opline , opline -> op1 , target_opline );
350+ num = ctx -> scdf .ssa -> cfg .map [opline - ctx -> scdf .op_array -> opcodes ];
351+ block = & ctx -> scdf .ssa -> cfg .blocks [num ];
352+ if (block -> successors_count == 2 ) {
353+ if (block -> successors [1 ] != block -> successors [0 ]) {
354+ zend_ssa_remove_predecessor (ctx -> scdf .ssa , num , block -> successors [1 ]);
355+ }
356+ block -> successors_count = 1 ;
357+ }
358+ }
359+ opline -> op1_type = IS_UNUSED ;
360+ opline -> extended_value = 0 ;
361+ opline -> opcode = ZEND_JMP ;
362+ break ;
363+ default :
364+ break ;
365+ }
279366 return 1 ;
280367 } else {
281368 // TODO: check the following special cases ???
0 commit comments