From 729a6688af366f995bd07ce94d825ed895a77d10 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 5 Jan 2018 12:58:28 +0800 Subject: [PATCH] Optimized FETCH_CLASS before INSTANCEOF out if possible --- ext/opcache/Optimizer/sccp.c | 19 ++++++++++++ ext/opcache/Optimizer/zend_optimizer.c | 4 +++ ext/opcache/tests/opt/sccp_024.phpt | 41 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 ext/opcache/tests/opt/sccp_024.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 3c6c54be771..996eb10ac72 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -329,6 +329,25 @@ static zend_bool try_replace_op2( if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline, &zv)) { return 1; } else { + switch (opline->opcode) { + case ZEND_FETCH_CLASS: + if (Z_TYPE(zv) == IS_STRING) { + ZEND_ASSERT((opline + 1)->opcode == ZEND_INSTANCEOF); + ZEND_ASSERT((opline + 1)->op2.var == opline->result.var); + if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline + 1, &zv)) { + zend_ssa_op *next_op = ssa_op + 1; + zend_optimizer_remove_live_range_ex(ctx->scdf.op_array, opline->result.var, ssa_op - ctx->scdf.ssa->ops); + zend_ssa_unlink_use_chain(ctx->scdf.ssa, next_op - ctx->scdf.ssa->ops, next_op->op2_use); + next_op->op2_use = -1; + next_op->op2_use_chain = -1; + zend_ssa_remove_result_def(ctx->scdf.ssa, ssa_op); + MAKE_NOP(opline); + return 1; + } + } + default: + break; + } zval_ptr_dtor_nogc(&zv); } } diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 97be113f47a..d5975f14141 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -347,6 +347,10 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_FAST_CALL: return 0; case ZEND_FETCH_CLASS: + if ((opline + 1)->opcode == ZEND_INSTANCEOF && + (opline + 1)->op2.var == opline->result.var) { + return 0; + } case ZEND_INIT_FCALL_BY_NAME: /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ case ZEND_ADD_INTERFACE: diff --git a/ext/opcache/tests/opt/sccp_024.phpt b/ext/opcache/tests/opt/sccp_024.phpt new file mode 100644 index 00000000000..f0b34f077b1 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_024.phpt @@ -0,0 +1,41 @@ +--TEST-- +SCCP 024: Const replacing to op2 of INSTANCEOF +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0x20000 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +$_main: ; (lines=1, args=0, vars=0, tmps=0) + ; (after optimizer) + ; %ssccp_024.php:1-13 +L0 (13): RETURN int(1) + +A::t: ; (lines=10, args=1, vars=2, tmps=2) + ; (after optimizer) + ; %ssccp_024.php:3-10 +L0 (3): CV0($obj) = RECV 1 +L1 (6): CV1($c) = QM_ASSIGN int(1) +L2 (7): T2 = INSTANCEOF CV0($obj) string("A") +L3 (7): ECHO T2 +L4 (8): T2 = INSTANCEOF CV0($obj) string("self") +L5 (8): ECHO T2 +L6 (9): V3 = FETCH_CLASS (no-autolod) (exception) CV1($c) +L7 (9): T2 = INSTANCEOF CV0($obj) V3 +L8 (9): ECHO T2 +L9 (10): RETURN null