From 404e003cf1065fea0a9aeebe62b9392f8f9102e4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 9 Dec 2015 05:16:30 +0300 Subject: [PATCH] Delete empty live-ranges --- ext/opcache/Optimizer/block_pass.c | 35 ++++++++++++++++++++--------- ext/opcache/Optimizer/zend_cfg.c | 14 ++++++++++++ sapi/phpdbg/tests/stepping_001.phpt | 4 ++-- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index d2695c6c4b..91a86f05f1 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -778,6 +778,9 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array) MAKE_NOP(opline); b->end--; } + } else if (b->start == b->end && opline->opcode == ZEND_NOP) { + /* skip empty block */ + b->end--; } len += b->end - b->start + 1; } else if (b->start <= b->end) { @@ -801,14 +804,15 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array) /* Copy code of reachable blocks into a single buffer */ for (b = blocks; b < end; b++) { if (b->flags & ZEND_BB_REACHABLE) { - uint32_t n; - - ZEND_ASSERT(b->start <= b->end); - n = b->end - b->start + 1; - memcpy(opline, op_array->opcodes + b->start, n * sizeof(zend_op)); - b->start = opline - new_opcodes; - b->end = opline - new_opcodes + n - 1; - opline += n; + if (b->start <= b->end) { + uint32_t n = b->end - b->start + 1; + memcpy(opline, op_array->opcodes + b->start, n * sizeof(zend_op)); + b->start = opline - new_opcodes; + b->end = opline - new_opcodes + n - 1; + opline += n; + } else { + b->start = b->end = opline - new_opcodes; + } } } @@ -913,11 +917,22 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array) map = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last_live_range, use_heap); for (i = 0, j = 0; i < op_array->last_live_range; i++) { + if (op_array->live_range[i].var == (uint32_t)-1) { + /* this live range already removed */ + continue; + } if (!(blocks[cfg->map[op_array->live_range[i].start]].flags & ZEND_BB_REACHABLE)) { ZEND_ASSERT(!(blocks[cfg->map[op_array->live_range[i].end]].flags & ZEND_BB_REACHABLE)); } else { - op_array->live_range[i].start = blocks[cfg->map[op_array->live_range[i].start]].start; - op_array->live_range[i].end = blocks[cfg->map[op_array->live_range[i].end]].start; + uint32_t start_op = blocks[cfg->map[op_array->live_range[i].start]].start; + uint32_t end_op = blocks[cfg->map[op_array->live_range[i].end]].start; + + if (start_op == end_op) { + /* skip empty live range */ + continue; + } + op_array->live_range[i].start = start_op; + op_array->live_range[i].end = end_op; map[i] = j; if (i != j) { op_array->live_range[j] = op_array->live_range[i]; diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index 374bf25e48..77e5dc1942 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -90,8 +90,22 @@ static void zend_mark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg, i /* Add brk/cont paths */ for (j = 0; j < op_array->last_live_range; j++) { + if (op_array->live_range[j].var == (uint32_t)-1) { + /* this live range already removed */ + continue; + } b = blocks + block_map[op_array->live_range[j].start]; if (b->flags & ZEND_BB_REACHABLE) { + while (op_array->opcodes[b->start].opcode == ZEND_NOP && b->start != b->end) { + b->start++; + } + if (op_array->opcodes[b->start].opcode == ZEND_NOP && + b->start == b->end && + b->successors[0] == block_map[op_array->live_range[j].end]) { + /* mark as removed (empty live range) */ + op_array->live_range[j].var = (uint32_t)-1; + continue; + } b->flags |= ZEND_BB_GEN_VAR; b = blocks + block_map[op_array->live_range[j].end]; b->flags |= ZEND_BB_KILL_VAR; diff --git a/sapi/phpdbg/tests/stepping_001.phpt b/sapi/phpdbg/tests/stepping_001.phpt index 074eeb47fa..bec14d4487 100644 --- a/sapi/phpdbg/tests/stepping_001.phpt +++ b/sapi/phpdbg/tests/stepping_001.phpt @@ -32,14 +32,14 @@ prompt> [L10 %s ECHO "ok" 00011: } finally { 00012: echo " ... ok"; prompt> ok -[L10 %s FAST_CALL J8 ~%d %s] +[L10 %s FAST_CALL J7 ~%d %s] [L12 %s ECHO " ... ok" %s] >00012: echo " ... ok"; 00013: } 00014: prompt> ... ok [L12 %s FAST_RET ~%d %s] -[L10 %s JMP J10 %s] +[L10 %s JMP J9 %s] >00010: echo "ok"; 00011: } finally { 00012: echo " ... ok"; -- 2.40.0