From: Dmitry Stogov Date: Mon, 14 Aug 2017 10:54:52 +0000 (+0300) Subject: Fixed removing dead live ranges X-Git-Tag: php-7.2.0beta3~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df5104bfc9419813c3262180dc7f191a615c8e84;p=php Fixed removing dead live ranges --- diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index cd74ea41e3..24af78ee5d 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1459,7 +1459,7 @@ static int replace_constant_operands(sccp_ctx *ctx) { ZEND_ASSERT(call); ZEND_ASSERT(call->caller_call_opline == opline); if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { - zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition + 1); + zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition); } zend_ssa_remove_result_def(ssa, ssa_op); zend_ssa_remove_instr(ssa, opline, ssa_op); @@ -1477,7 +1477,7 @@ static int replace_constant_operands(sccp_ctx *ctx) { } else { /* Ordinary computational instruction -> remove it */ if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { - zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition + 1); + zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition); } zend_ssa_remove_result_def(ssa, ssa_op); zend_ssa_remove_instr(ssa, opline, ssa_op); @@ -1502,7 +1502,7 @@ static int replace_constant_operands(sccp_ctx *ctx) { && ssa->vars[ssa_op->result_def].use_chain < 0 && ssa->vars[ssa_op->result_def].phi_use_chain == NULL) { if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { - zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition + 1); + zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition); } zend_ssa_remove_result_def(ssa, ssa_op); opline->result_type = IS_UNUSED; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 4b56809fda..89917224d9 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -557,6 +557,24 @@ void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var, { uint32_t i = 0; + switch (op_array->opcodes[start].opcode) { + case ZEND_ROPE_ADD: + case ZEND_ADD_ARRAY_ELEMENT: + return; + case ZEND_ROPE_INIT: + var |= ZEND_LIVE_ROPE; + break; + case ZEND_BEGIN_SILENCE: + var |= ZEND_LIVE_SILENCE; + break; + case ZEND_FE_RESET_R: + case ZEND_FE_RESET_RW: + var |= ZEND_LIVE_LOOP; + /* break missing intentionally */ + default: + start++; + } + while (i < op_array->last_live_range) { if (op_array->live_range[i].var == var && op_array->live_range[i].start == start) { diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index a82d7ff225..e100be426c 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -1362,7 +1362,7 @@ void zend_ssa_remove_block(zend_op_array *op_array, zend_ssa *ssa, int i) /* {{{ } if (op_array->opcodes[j].result_type & (IS_TMP_VAR|IS_VAR)) { - zend_optimizer_remove_live_range_ex(op_array, op_array->opcodes[j].result.var, j + 1); + zend_optimizer_remove_live_range_ex(op_array, op_array->opcodes[j].result.var, j); } zend_ssa_remove_defs_of_instr(ssa, &ssa->ops[j]); zend_ssa_remove_instr(ssa, &op_array->opcodes[j], &ssa->ops[j]);