From f3c70f118c54dceea02e50de526c3138c2719384 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 31 Mar 2016 17:26:27 +0300 Subject: [PATCH] Manual CSE --- ext/opcache/Optimizer/zend_dfg.c | 70 +++++++++++++------------- ext/opcache/Optimizer/zend_inference.c | 28 ++++++----- 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c index 78c534af29..91c447799e 100644 --- a/ext/opcache/Optimizer/zend_dfg.c +++ b/ext/opcache/Optimizer/zend_dfg.c @@ -27,7 +27,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg int blocks_count = cfg->blocks_count; zend_bitset tmp, gen, def, use, in, out; zend_op *opline; - uint32_t k; + uint32_t k, var_num; int j; /* FIXME: can we use "gen" instead of "def" for flow analyzing? */ @@ -51,17 +51,20 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg if (k < blocks[j].end && next->opcode == ZEND_OP_DATA) { if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { - if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(next->op1.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(next->op1.var)); + var_num = EX_VAR_TO_NUM(next->op1.var); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } } if (next->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { - if (!DFG_ISSET(def, set_size, j,EX_VAR_TO_NUM(next->op2.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(next->op2.var)); + var_num = EX_VAR_TO_NUM(next->op2.var); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } } } if (opline->op1_type == IS_CV) { + var_num = EX_VAR_TO_NUM(opline->op1.var); switch (opline->opcode) { case ZEND_ADD_ARRAY_ELEMENT: case ZEND_INIT_ARRAY: @@ -90,12 +93,12 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg case ZEND_SEND_VAR_NO_REF: case ZEND_FE_RESET_RW: op1_def: - if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) { + if (!DFG_ISSET(use, set_size, j, var_num)) { // FIXME: include into "use" to ...? - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); - DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); + DFG_SET(use, set_size, j, var_num); + DFG_SET(def, set_size, j, var_num); } - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); + DFG_SET(gen, set_size, j, var_num); break; case ZEND_UNSET_VAR: ZEND_ASSERT(opline->extended_value & ZEND_QUICK_SET); @@ -128,19 +131,21 @@ op1_def: case ZEND_FETCH_OBJ_RW: case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_FETCH_OBJ_UNSET: - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); + DFG_SET(gen, set_size, j, var_num); default: op1_use: - if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } } } else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var)); + var_num = EX_VAR_TO_NUM(opline->op1.var); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } } if (opline->op2_type == IS_CV) { + var_num = EX_VAR_TO_NUM(opline->op2.var); switch (opline->opcode) { case ZEND_ASSIGN: if (build_flags & ZEND_SSA_RC_INFERENCE) { @@ -156,42 +161,39 @@ op1_use: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: op2_def: - if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) { + if (!DFG_ISSET(use, set_size, j, var_num)) { // FIXME: include into "use" to ...? - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); - DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + DFG_SET(use, set_size, j, var_num); + DFG_SET(def, set_size, j, var_num); } - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + DFG_SET(gen, set_size, j, var_num); break; default: op2_use: - if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } break; } } else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { + var_num = EX_VAR_TO_NUM(opline->op2.var); if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) { - if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) { - DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + if (!DFG_ISSET(use, set_size, j, var_num)) { + DFG_SET(def, set_size, j, var_num); } - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + DFG_SET(gen, set_size, j, var_num); } else { - if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) { - DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); + if (!DFG_ISSET(def, set_size, j, var_num)) { + DFG_SET(use, set_size, j, var_num); } } } - if (opline->result_type == IS_CV) { - if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->result.var))) { - DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->result.var)); + if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { + var_num = EX_VAR_TO_NUM(opline->result.var); + if (!DFG_ISSET(use, set_size, j, var_num)) { + DFG_SET(def, set_size, j, var_num); } - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->result.var)); - } else if (opline->result_type & (IS_VAR|IS_TMP_VAR)) { - if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->result.var))) { - DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->result.var)); - } - DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->result.var)); + DFG_SET(gen, set_size, j, var_num); } } } diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index c07a0d0907..5f345699c6 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2037,25 +2037,29 @@ static void add_usages(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset } if (ssa->vars[var].use_chain >= 0) { int use = ssa->vars[var].use_chain; + zend_ssa_op *op; + do { - if (ssa->ops[use].result_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use].result_def); + op = ssa->ops + use; + if (op->result_def >= 0) { + zend_bitset_incl(worklist, op->result_def); } - if (ssa->ops[use].op1_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use].op1_def); + if (op->op1_def >= 0) { + zend_bitset_incl(worklist, op->op1_def); } - if (ssa->ops[use].op2_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use].op2_def); + if (op->op2_def >= 0) { + zend_bitset_incl(worklist, op->op2_def); } if (op_array->opcodes[use].opcode == ZEND_OP_DATA) { - if (ssa->ops[use-1].result_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use-1].result_def); + op--; + if (op->result_def >= 0) { + zend_bitset_incl(worklist, op->result_def); } - if (ssa->ops[use-1].op1_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use-1].op1_def); + if (op->op1_def >= 0) { + zend_bitset_incl(worklist, op->op1_def); } - if (ssa->ops[use-1].op2_def >= 0) { - zend_bitset_incl(worklist, ssa->ops[use-1].op2_def); + if (op->op2_def >= 0) { + zend_bitset_incl(worklist, op->op2_def); } } use = zend_ssa_next_use(ssa->ops, var, use); -- 2.50.1