From b8e30a492ab1cd1dd0ed3ff55cd6ea6468f18972 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 26 Feb 2016 21:02:41 +0300 Subject: [PATCH] Use more general optimisation patterns --- ext/opcache/Optimizer/dfa_pass.c | 77 +++++++++++++++----------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 98db4ea23e..2598d99ea1 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -125,9 +125,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx // 1: #1.T = OP_Y | #3.CV = OP_Y // 2: ASSIGN #2.CV [undef,scalar] -> #3.CV, #1.T | NOP // -- - // 2: ASSIGN #2.CV [undef,scalar] -> #3.CV, C | 3.CV = QM_ASSIGN C - // -- - // 2: ASSIGN #2.CV [undef,scalar] -> #3.CV, #1.CV | 3.CV = QM_ASSIGN #1.CV + // 2: ASSIGN #2.CV [undef,scalar] -> #3.CV, X | 3.CV = QM_ASSIGN X for (i = 0; i < ssa->vars_count; i++) { int op2 = ssa->vars[i].definition; @@ -143,49 +141,46 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && !(ssa->var_info[var2].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) ) { - if (op_array->opcodes[op2].op2_type & (IS_TMP_VAR|IS_VAR)) { + if ((op_array->opcodes[op2].op2_type & (IS_TMP_VAR|IS_VAR)) + && ssa->ops[op2].op2_use >= 0 + && !(ssa->var_info[ssa->ops[op2].op2_use].type & MAY_BE_REF) + && ssa->vars[ssa->ops[op2].op2_use].definition >= 0 + && ssa->ops[ssa->vars[ssa->ops[op2].op2_use].definition].result_def == ssa->ops[op2].op2_use + && ssa->ops[ssa->vars[ssa->ops[op2].op2_use].definition].result_use < 0 + && ssa->vars[ssa->ops[op2].op2_use].use_chain == op2 + && ssa->ops[op2].op2_use_chain < 0 + && !ssa->vars[ssa->ops[op2].op2_use].phi_use_chain + && !ssa->vars[ssa->ops[op2].op2_use].sym_use_chain + /* see Zend/tests/generators/aborted_yield_during_new.phpt */ + && op_array->opcodes[ssa->vars[ssa->ops[op2].op2_use].definition].opcode != ZEND_NEW + ) { int var1 = ssa->ops[op2].op2_use; + int op1 = ssa->vars[var1].definition; + int var3 = i; + + if (zend_ssa_unlink_use_chain(ssa, op2, var2)) { + /* Reconstruct SSA */ + ssa->vars[var3].definition = op1; + ssa->ops[op1].result_def = var3; + + ssa->vars[var1].definition = -1; + ssa->vars[var1].use_chain = -1; + + ssa->ops[op2].op1_use = -1; + ssa->ops[op2].op2_use = -1; + ssa->ops[op2].op1_def = -1; + ssa->ops[op2].op1_use_chain = -1; - if (var1 >= 0 - && !(ssa->var_info[var1].type & MAY_BE_REF) - && ssa->vars[var1].definition >= 0 - && ssa->ops[ssa->vars[var1].definition].result_def == var1 - && ssa->ops[ssa->vars[var1].definition].result_use < 0 - && ssa->vars[var1].use_chain == op2 - && ssa->ops[op2].op2_use_chain < 0 - && !ssa->vars[var1].phi_use_chain - && !ssa->vars[var1].sym_use_chain - /* see Zend/tests/generators/aborted_yield_during_new.phpt */ - && op_array->opcodes[ssa->vars[var1].definition].opcode != ZEND_NEW - ) { - int op1 = ssa->vars[var1].definition; - int var3 = i; - - if (zend_ssa_unlink_use_chain(ssa, op2, var2)) { - /* Reconstruct SSA */ - ssa->vars[var3].definition = op1; - ssa->ops[op1].result_def = var3; - - ssa->vars[var1].definition = -1; - ssa->vars[var1].use_chain = -1; - - ssa->ops[op2].op1_use = -1; - ssa->ops[op2].op2_use = -1; - ssa->ops[op2].op1_def = -1; - ssa->ops[op2].op1_use_chain = -1; - - /* Update opcodes */ - op_array->opcodes[op1].result_type = op_array->opcodes[op2].op1_type; - op_array->opcodes[op1].result.var = op_array->opcodes[op2].op1.var; - MAKE_NOP(&op_array->opcodes[op2]); - remove_nops = 1; - } + /* Update opcodes */ + op_array->opcodes[op1].result_type = op_array->opcodes[op2].op1_type; + op_array->opcodes[op1].result.var = op_array->opcodes[op2].op1.var; + MAKE_NOP(&op_array->opcodes[op2]); + remove_nops = 1; } } else if (op_array->opcodes[op2].op2_type == IS_CONST - || (op_array->opcodes[op2].op2_type == IS_CV + || ((op_array->opcodes[op2].op2_type & (IS_TMP_VAR|IS_VAR|IS_CV)) && ssa->ops[op2].op2_use >= 0 - && ssa->ops[op2].op2_def < 0 - && !(ssa->var_info[ssa->ops[op2].op2_use].type & MAY_BE_REF)) + && ssa->ops[op2].op2_def < 0) ) { int var3 = i; -- 2.50.1