diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-01-21 22:18:07 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-01-21 22:18:07 +0300 |
commit | 6c983c6221cb3e02b253cd5379eda42fe0d6500d (patch) | |
tree | b9131711f78b9f5ebb97ef2c977051f17428853c | |
parent | 467d8b3ff78312f6bc8d9d2795a8feddbf03ce56 (diff) | |
download | php-git-6c983c6221cb3e02b253cd5379eda42fe0d6500d.tar.gz |
Use ZEND_FUNC_FREE_LOOP_VAR flag to avoid useless iterations.
-rw-r--r-- | ext/opcache/Optimizer/scdf.c | 3 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_cfg.c | 16 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_func_info.h | 1 |
3 files changed, 19 insertions, 1 deletions
diff --git a/ext/opcache/Optimizer/scdf.c b/ext/opcache/Optimizer/scdf.c index 77cfc9715e..f3a79338bd 100644 --- a/ext/opcache/Optimizer/scdf.c +++ b/ext/opcache/Optimizer/scdf.c @@ -213,6 +213,9 @@ int scdf_remove_unreachable_blocks(scdf_ctx *scdf) { int i; int removed_ops = 0; + if (!(ssa->cfg.flags & ZEND_FUNC_FREE_LOOP_VAR)) { + return 0; + } for (i = 0; i < ssa->cfg.blocks_count; i++) { if (!zend_bitset_in(scdf->executable_blocks, i) && (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE) diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index 267c39c8ef..1bd0a4b5e0 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -110,7 +110,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * blocks[start].flags = ZEND_BB_START; zend_mark_reachable(op_array->opcodes, cfg, blocks + start); - if (op_array->last_live_range || op_array->last_try_catch) { + if (op_array->last_try_catch) { zend_basic_block *b; int j, changed; uint32_t *block_map = cfg->map; @@ -193,6 +193,12 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * } } } while (changed); + } + + if (cfg->flags & ZEND_FUNC_FREE_LOOP_VAR) { + zend_basic_block *b; + int j; + uint32_t *block_map = cfg->map; /* Mark blocks that are unreachable, but free a loop var created in a reachable block. */ for (b = blocks; b < blocks + cfg->blocks_count; b++) { @@ -417,6 +423,14 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b case ZEND_EXT_FCALL_END: flags |= ZEND_FUNC_HAS_EXTENDED_INFO; break; + case ZEND_FREE: + if (opline->extended_value == ZEND_FREE_SWITCH) { + flags |= ZEND_FUNC_FREE_LOOP_VAR; + } + break; + case ZEND_FE_FREE: + flags |= ZEND_FUNC_FREE_LOOP_VAR; + break; } } diff --git a/ext/opcache/Optimizer/zend_func_info.h b/ext/opcache/Optimizer/zend_func_info.h index 45d38ddc2c..656cc59fad 100644 --- a/ext/opcache/Optimizer/zend_func_info.h +++ b/ext/opcache/Optimizer/zend_func_info.h @@ -27,6 +27,7 @@ #define ZEND_FUNC_VARARG (1<<2) /* uses func_get_args() */ #define ZEND_FUNC_NO_LOOPS (1<<3) #define ZEND_FUNC_IRREDUCIBLE (1<<4) +#define ZEND_FUNC_FREE_LOOP_VAR (1<<5) #define ZEND_FUNC_RECURSIVE (1<<7) #define ZEND_FUNC_RECURSIVE_DIRECTLY (1<<8) #define ZEND_FUNC_RECURSIVE_INDIRECTLY (1<<9) |