com php-src: Remove dead JMP/JMPZ/JMPNZ/JMPZNZ (DCE pass can't remove them): ext/opcache/Optimizer/dfa_pass.c

From: Date: Tue, 18 Jul 2017 17:43:06 +0000
Subject: com php-src: Remove dead JMP/JMPZ/JMPNZ/JMPZNZ (DCE pass can't remove them): ext/opcache/Optimizer/dfa_pass.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-98615@lists.php.net to get a copy of this message
Commit: 0903f6bffb32f796711d8dd5b02c5c98e16ec7b5 Author: Dmitry Stogov <dmitry@zend.com> Tue, 18 Jul 2017 20:43:06 +0300 Parents: 582882ae18d0e2ce04992aa9e5979574562fb5bf Branches: PHP-7.2 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=0903f6bffb32f796711d8dd5b02c5c98e16ec7b5 Log: Remove dead JMP/JMPZ/JMPNZ/JMPZNZ (DCE pass can't remove them) Changed paths: M ext/opcache/Optimizer/dfa_pass.c Diff: diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 642e0d3..5325977 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass..c @@ -450,6 +450,84 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) return removed_ops; } +static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) +{ + int removed_ops = 0; + int block_num = 0; + + while (block_num < ssa->cfg.blocks_count + && !(ssa->cfg.blocks[block_num].flags & ZEND_BB_REACHABLE)) { + block_num++; + } + while (block_num < ssa->cfg.blocks_count) { + int next_block_num = block_num + 1; + zend_basic_block *block = &ssa->cfg.blocks[block_num]; + uint32_t op_num; + zend_op *opline; + zend_ssa_op *op; + + while (next_block_num < ssa->cfg.blocks_count + && !(ssa->cfg.blocks[next_block_num].flags & ZEND_BB_REACHABLE)) { + next_block_num++; + } + + if (block->len) { + if (block->successors_count == 2) { + if (block->successors[0] == block->successors[1]) { + op_num = block->start + block->len - 1; + opline = op_array->opcodes + op_num; + switch (opline->opcode) { + case ZEND_JMPZ: + case ZEND_JMPNZ: + case ZEND_JMPZNZ: + op = ssa->ops + op_num; + if (block->successors[0] == next_block_num) { + if (opline->op1_type & (IS_CV|IS_CONST)) { + zend_ssa_remove_instr(ssa, opline, op); + if (op->op1_use >= 0) { + zend_ssa_unlink_use_chain(ssa, op_num, op->op1_use); + op->op1_use = -1; + op->op1_use_chain = -1; + } + MAKE_NOP(opline); + removed_ops++; + } else { + opline->opcode = ZEND_FREE; + opline->op2.num = 0; + } + } else { + if (opline->op1_type & (IS_CV|IS_CONST)) { + if (op->op1_use >= 0) { + zend_ssa_unlink_use_chain(ssa, op_num, op->op1_use); + op->op1_use = -1; + op->op1_use_chain = -1; + } + opline->opcode = ZEND_JMP; + opline->op1_type = IS_UNUSED; + opline->op1.num = opline->op2.num; + } + } + break; + default: + break; + } + } + } else if (block->successors_count == 1 && block->successors[0] == next_block_num) { + op_num = block->start + block->len - 1; + opline = op_array->opcodes + op_num; + if (opline->opcode == ZEND_JMP) { + MAKE_NOP(opline); + removed_ops++; + } + } + } + + block_num = next_block_num; + } + + return removed_ops; +} + void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, zend_call_info **call_map) { if (ctx->debug_level & ZEND_DUMP_BEFORE_DFA_PASS) { @@ -467,6 +545,11 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if (sccp_optimize_op_array(ctx, op_array, ssa, call_map)) { remove_nops = 1; } + + if (zend_dfa_optimize_jmps(op_array, ssa)) { + remove_nops = 1; + } + #if ZEND_DEBUG_DFA ssa_verify_integrity(op_array, ssa, "after sccp"); #endif

« previous php.cvs (#98615) next »