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:
@@ -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 &&
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user