1
0
mirror of https://github.com/php/php-src.git synced 2026-04-16 20:41:18 +02:00

Fixed incorrect optimizaton (update of jump instructions should be also reflected in CFG update)

This commit is contained in:
Dmitry Stogov
2017-09-04 14:07:37 +03:00
parent ebb00c1e0f
commit db5b8dbcdf
2 changed files with 54 additions and 36 deletions

View File

@@ -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 &&

View File

@@ -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);