summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/opcache/Optimizer/dfa_pass.c9
-rw-r--r--ext/opcache/Optimizer/zend_cfg.c10
-rw-r--r--ext/opcache/Optimizer/zend_cfg.h1
-rw-r--r--ext/opcache/Optimizer/zend_dump.c3
4 files changed, 18 insertions, 5 deletions
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index 3f4112a7db..40a3dc996b 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass.c
@@ -128,7 +128,14 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
shiftlist = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last, use_heap);
memset(shiftlist, 0, sizeof(uint32_t) * op_array->last);
for (b = blocks; b < end; b++) {
- if (b->flags & ZEND_BB_REACHABLE) {
+ if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) {
+ if (b->flags & ZEND_BB_UNREACHABLE_FREE) {
+ /* Only keep the FREE for the loop var */
+ ZEND_ASSERT(op_array->opcodes[b->start].opcode == ZEND_FREE
+ || op_array->opcodes[b->start].opcode == ZEND_FE_FREE);
+ b->end = b->start;
+ }
+
i = b->start;
b->start = target;
while (i <= b->end) {
diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c
index c675da1116..33c34b85c4 100644
--- a/ext/opcache/Optimizer/zend_cfg.c
+++ b/ext/opcache/Optimizer/zend_cfg.c
@@ -114,8 +114,14 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
b = blocks + block_map[op_array->live_range[j].end];
b->flags |= ZEND_BB_KILL_VAR;
if (!(b->flags & ZEND_BB_REACHABLE)) {
- changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, b);
+ if (cfg->split_at_live_ranges) {
+ changed = 1;
+ zend_mark_reachable(op_array->opcodes, blocks, b);
+ } else {
+ ZEND_ASSERT(!(b->flags & ZEND_BB_UNREACHABLE_FREE));
+ ZEND_ASSERT(b->start == op_array->live_range[j].end);
+ b->flags |= ZEND_BB_UNREACHABLE_FREE;
+ }
}
} else {
ZEND_ASSERT(!(blocks[block_map[op_array->live_range[j].end]].flags & ZEND_BB_REACHABLE));
diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h
index de94997dd5..cbf4225a31 100644
--- a/ext/opcache/Optimizer/zend_cfg.h
+++ b/ext/opcache/Optimizer/zend_cfg.h
@@ -32,6 +32,7 @@
#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_UNREACHABLE_FREE (1<<12) /* unreachable loop free */
#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 986e470345..70abe4d317 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -399,9 +399,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) {
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
- if (ssa && ssa->ops) {
+ if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_def >= 0) {
int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def;
- ZEND_ASSERT(ssa_var_num >= 0);
zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
} else {
zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));