From: Dmitry Stogov Date: Wed, 9 Dec 2015 22:17:35 +0000 (+0300) Subject: Apply local optimizatons to extended bacic block (this allows some optimizarions... X-Git-Tag: php-7.1.0alpha1~688 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fd20e6cee6f443414cbe32dc422ea2de7ffcb0e6;p=php Apply local optimizatons to extended bacic block (this allows some optimizarions across few following BBs). --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 8c0bc91762..cddfb8bdfc 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -127,8 +127,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array /* remove leading NOPs */ strip_leading_nops(op_array, block); - /* we track data dependencies only insight a single basic block */ - memset(Tsource, 0, (op_array->last_var + op_array->T) * sizeof(zend_op *)); opline = op_array->opcodes + block->start; end = op_array->opcodes + block->end + 1; while (opline < end) { @@ -324,9 +322,17 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } #endif + case ZEND_FETCH_LIST: + if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + /* LIST variable will be deleted later by FREE */ + Tsource[VAR_NUM(opline->op1.var)] = NULL; + } + break; + case ZEND_CASE: if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { /* CASE variable will be deleted later by FREE, so we can't optimize it */ + Tsource[VAR_NUM(opline->op1.var)] = NULL; break; } if (opline->op1_type == IS_CONST && @@ -811,6 +817,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array) b->end = opline - new_opcodes + n - 1; opline += n; } else { + b->flags |= ZEND_BB_EMPTY; b->start = b->end = opline - new_opcodes; } } @@ -1458,7 +1465,7 @@ next_target_znz: static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx) { int n; - zend_basic_block *block; + zend_basic_block *block, *next_block; uint32_t var_num; uint32_t bitset_len; zend_bitset usage; @@ -1474,7 +1481,6 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use checkpoint = zend_arena_checkpoint(ctx->arena); bitset_len = zend_bitset_len(op_array->last_var + op_array->T); - usage = zend_arena_calloc(&ctx->arena, bitset_len, ZEND_BITSET_ELM_SIZE); defined_here = zend_arena_alloc(&ctx->arena, bitset_len * ZEND_BITSET_ELM_SIZE); for (n = 1; n < cfg->blocks_count; n++) { @@ -1486,7 +1492,11 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use opline = op_array->opcodes + block->start; end = op_array->opcodes + block->end + 1; - zend_bitset_clear(defined_here, bitset_len); + if (!(block->flags & ZEND_BB_FOLLOW) || + (block->flags & ZEND_BB_TARGET)) { + /* Skip continuation of "extended" BB */ + zend_bitset_clear(defined_here, bitset_len); + } while (oplineop1_type == IS_VAR || opline->op1_type == IS_TMP_VAR) { @@ -1551,8 +1561,10 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use } } - for (n = 0; n < cfg->blocks_count; n++) { - block = cfg->blocks + n; + usage = defined_here; + next_block = NULL; + for (n = cfg->blocks_count; n > 0;) { + block = cfg->blocks + (--n); if (!(block->flags & ZEND_BB_REACHABLE)) { continue; @@ -1560,7 +1572,15 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use opline = op_array->opcodes + block->end; end = op_array->opcodes + block->start; - zend_bitset_copy(usage, used_ext, bitset_len); + if (!next_block || + !(next_block->flags & ZEND_BB_FOLLOW) || + (next_block->flags & ZEND_BB_TARGET)) { + /* Skip continuation of "extended" BB */ + zend_bitset_copy(usage, used_ext, bitset_len); + } else if (block->successors[1] != -1) { + zend_bitset_union(usage, used_ext, bitset_len); + } + next_block = block; while (opline >= end) { /* usage checks */ @@ -1753,9 +1773,16 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* optimize each basic block separately */ for (b = blocks; b < end; b++) { - if (b->flags & ZEND_BB_REACHABLE) { - zend_optimize_block(b, op_array, usage, &cfg, Tsource); + if (!(b->flags & ZEND_BB_REACHABLE)) { + continue; + } + /* we track data dependencies only insight a single basic block */ + if (!(b->flags & ZEND_BB_FOLLOW) || + (b->flags & ZEND_BB_TARGET)) { + /* Skip continuation of "extended" BB */ + memset(Tsource, 0, (op_array->last_var + op_array->T) * sizeof(zend_op *)); } + zend_optimize_block(b, op_array, usage, &cfg, Tsource); } /* Jump optimization for each block */ diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h index 76d1bb44ab..dcfaa3fbc1 100644 --- a/ext/opcache/Optimizer/zend_cfg.h +++ b/ext/opcache/Optimizer/zend_cfg.h @@ -36,6 +36,7 @@ #define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */ #define ZEND_BB_GEN_VAR (1<<9) /* start of live range */ #define ZEND_BB_KILL_VAR (1<<10) /* end of live range */ +#define ZEND_BB_EMPTY (1<<11) #define ZEND_BB_LOOP_HEADER (1<<16) #define ZEND_BB_IRREDUCIBLE_LOOP (1<<17) diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index e411a4bc3a..e73d8567ff 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -215,11 +215,13 @@ void zend_dump_op_array(const zend_op_array *op_array, const zend_cfg *cfg, uint } fprintf(stderr, "\n"); - opline = op_array->opcodes + b->start; - end = op_array->opcodes + b->end + 1; - while (opline < end) { - zend_dump_op(op_array, b, opline); - opline++; + if (!(b->flags & ZEND_BB_EMPTY)) { + opline = op_array->opcodes + b->start; + end = op_array->opcodes + b->end + 1; + while (opline < end) { + zend_dump_op(op_array, b, opline); + opline++; + } } } }