summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-01-21 22:18:07 +0300
committerDmitry Stogov <dmitry@zend.com>2019-01-21 22:18:07 +0300
commit6c983c6221cb3e02b253cd5379eda42fe0d6500d (patch)
treeb9131711f78b9f5ebb97ef2c977051f17428853c
parent467d8b3ff78312f6bc8d9d2795a8feddbf03ce56 (diff)
downloadphp-git-6c983c6221cb3e02b253cd5379eda42fe0d6500d.tar.gz
Use ZEND_FUNC_FREE_LOOP_VAR flag to avoid useless iterations.
-rw-r--r--ext/opcache/Optimizer/scdf.c3
-rw-r--r--ext/opcache/Optimizer/zend_cfg.c16
-rw-r--r--ext/opcache/Optimizer/zend_func_info.h1
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)