Optimized FETCH_CLASS before INSTANCEOF out if possible

This commit is contained in:
Xinchen Hui 2018-01-05 12:58:28 +08:00
parent c0913af570
commit 729a6688af
3 changed files with 64 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class A {
function t($obj) {
$a = "A";
$b = "self";
$c = 1;
echo ($obj instanceof $a);
echo ($obj instanceof $b);
echo ($obj instanceof $c);
}
}
?>
--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