diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-10-04 12:51:01 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-10-04 12:52:46 +0300 |
commit | dc3c8c75dad511f08ac5e1dd2e854003e175894f (patch) | |
tree | d2ab2efab19ce2dbeade89fe875043455422b7be | |
parent | d44cf9b539c5dfbd3ff0295bac25165e79214e09 (diff) | |
download | php-git-dc3c8c75dad511f08ac5e1dd2e854003e175894f.tar.gz |
Prefer optimization without JMPZNZ instruction
-rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index d0671d1a5b..6ca3d02468 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1343,9 +1343,38 @@ next_target: break; } } - /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ + if (target->opcode == ZEND_JMP && !(target_block->flags & ZEND_BB_PROTECTED)) { + + if (!(target_block->flags & ZEND_BB_TARGET)) { + int next = (target_block - blocks) + 1; + + while (next < cfg->blocks_count && !(blocks[next].flags & ZEND_BB_REACHABLE)) { + /* find used one */ + next++; + } + if (next < cfg->blocks_count && + block->successors[0] == next) { + /* JMPZ(X,L1) JMP(L2) L1: -> JMPNZ(X,L2) NOP*/ + + last_op->opcode = INV_COND(last_op->opcode); + + DEL_SOURCE(block, block->successors[1]); + block->successors[0] = target_block->successors[0]; + block->successors[1] = next; + ADD_SOURCE(block, block->successors[1]); + + target_block->flags &= ~ZEND_BB_REACHABLE; + MAKE_NOP(target); + + blocks[next].flags |= ZEND_BB_FOLLOW; + + break; + } + } + + /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */ DEL_SOURCE(block, block->successors[1]); if (last_op->opcode == ZEND_JMPZ) { block->successors[1] = target_block->successors[0]; |