com php-src: Fixed incorrect optimizaton (update of jump instructions should be also reflected in CFG update): ext/opcache/Optimizer/ block_pass.c
ext/opcache/Optimizer/zend_optimizer.c
| From: | Dmitry Stogov | Date: | Mon, 04 Sep 2017 11:07:37 +0000 |
| Subject: | com php-src: Fixed incorrect optimizaton (update of jump instructions should be also reflected in CFG update): ext/opcache/Optimizer/ block_pass.c ext/opcache/Optimizer/zend_optimizer.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-99239@lists.php.net to get a copy of this message | ||
Commit: db5b8dbcdfd2642232f7e0c753508f290c8c2da9
Author: Dmitry Stogov <dmitry@zend.com> Mon, 4 Sep 2017 14:07:37 +0300
Parents: ebb00c1e0feb83542f8e30f04ff5fe2b7d820043
Branches: PHP-7.2 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=db5b8dbcdfd2642232f7e0c753508f290c8c2da9
Log:
Fixed incorrect optimizaton (update of jump instructions should be also reflected in CFG update)
Changed paths:
M ext/opcache/Optimizer/block_pass.c
M ext/opcache/Optimizer/zend_optimizer.c
Diff:
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 41934f1..c43ff29 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 f8f42a1..cc197c0 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);