From: Dmitry Stogov Date: Mon, 4 Sep 2017 11:07:37 +0000 (+0300) Subject: Fixed incorrect optimizaton (update of jump instructions should be also reflected... X-Git-Tag: php-7.2.0RC2~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db5b8dbcdfd2642232f7e0c753508f290c8c2da9;p=php Fixed incorrect optimizaton (update of jump instructions should be also reflected in CFG update) --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 41934f192b..c43ff29f34 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -174,7 +174,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array while (opline < end) { /* Constant Propagation: strip X = QM_ASSIGN(const) */ if ((opline->op1_type & (IS_TMP_VAR|IS_VAR)) && - opline->opcode != ZEND_FREE) { + opline->opcode != ZEND_FREE && + !zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) { src = VAR_SOURCE(opline->op1); if (src && src->opcode == ZEND_QM_ASSIGN && @@ -196,6 +197,56 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } else { + zend_op *target_opline; + + switch (opline->opcode) { + case ZEND_JMPZ: + if (zend_is_true(&c)) { + MAKE_NOP(opline); + DEL_SOURCE(block, block->successors[0]); + block->successors_count = 1; + block->successors[0] = block->successors[1]; + } else { + opline->opcode = ZEND_JMP; + COPY_NODE(opline->op1, opline->op2); + opline->op2_type = IS_UNUSED; + DEL_SOURCE(block, block->successors[1]); + block->successors_count = 1; + } + break; + case ZEND_JMPNZ: + if (zend_is_true(&c)) { + opline->opcode = ZEND_JMP; + COPY_NODE(opline->op1, opline->op2); + opline->op2_type = IS_UNUSED; + DEL_SOURCE(block, block->successors[1]); + block->successors_count = 1; + } else { + MAKE_NOP(opline); + DEL_SOURCE(block, block->successors[0]); + block->successors_count = 1; + block->successors[0] = block->successors[1]; + } + break; + case ZEND_JMPZNZ: + if (zend_is_true(&c)) { + target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); + DEL_SOURCE(block, block->successors[0]); + block->successors_count = 1; + block->successors[0] = block->successors[1]; + } else { + target_opline = ZEND_OP2_JMP_ADDR(opline); + DEL_SOURCE(block, block->successors[1]); + block->successors_count = 1; + } + ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); + opline->op1_type = IS_UNUSED; + opline->extended_value = 0; + opline->opcode = ZEND_JMP; + break; + default: + break; + } zval_ptr_dtor_nogc(&c); } } @@ -203,7 +254,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } /* Constant Propagation: strip X = QM_ASSIGN(const) */ - if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { + if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && + !zend_bitset_in(used_ext, VAR_NUM(opline->op2.var))) { src = VAR_SOURCE(opline->op2); if (src && src->opcode == ZEND_QM_ASSIGN && diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index f8f42a1277..cc197c0e52 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -258,41 +258,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, zend_op *opline, zval *val) { - zend_op *target_opline; - switch (opline->opcode) { - case ZEND_JMPZ: - if (zend_is_true(val)) { - MAKE_NOP(opline); - } else { - opline->opcode = ZEND_JMP; - COPY_NODE(opline->op1, opline->op2); - opline->op2_type = IS_UNUSED; - } - zval_ptr_dtor_nogc(val); - return 1; - case ZEND_JMPNZ: - if (zend_is_true(val)) { - opline->opcode = ZEND_JMP; - COPY_NODE(opline->op1, opline->op2); - opline->op2_type = IS_UNUSED; - } else { - MAKE_NOP(opline); - } - zval_ptr_dtor_nogc(val); - return 1; - case ZEND_JMPZNZ: - if (zend_is_true(val)) { - target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - target_opline = ZEND_OP2_JMP_ADDR(opline); - } - ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline); - opline->op1_type = IS_UNUSED; - opline->extended_value = 0; - opline->opcode = ZEND_JMP; - zval_ptr_dtor_nogc(val); - return 1; case ZEND_FREE: MAKE_NOP(opline); zval_ptr_dtor_nogc(val);