mirror of
https://github.com/php/php-src.git
synced 2026-04-28 18:53:33 +02:00
Improved reference dependencies analysis
This commit is contained in:
@@ -298,6 +298,17 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va
|
||||
return 1; /* incorrect type */
|
||||
}
|
||||
break;
|
||||
case ZEND_INIT_ARRAY:
|
||||
case ZEND_ADD_ARRAY_ELEMENT:
|
||||
if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) {
|
||||
return 1;
|
||||
}
|
||||
if (OP1_INFO() & MAY_BE_OBJECT) {
|
||||
/* object aliasing */
|
||||
return 1;
|
||||
}
|
||||
/* reference dependencies processed separately */
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@@ -307,9 +318,19 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va
|
||||
switch (opline->opcode) {
|
||||
case ZEND_ASSIGN_DIM:
|
||||
case ZEND_ASSIGN_OBJ:
|
||||
if (OP1_INFO() & MAY_BE_OBJECT) {
|
||||
/* object aliasing */
|
||||
return 1;
|
||||
}
|
||||
/* reference dependencies processed separately */
|
||||
break;
|
||||
case ZEND_ASSIGN:
|
||||
if (OP1_INFO() & MAY_BE_REF) {
|
||||
return 1;
|
||||
}
|
||||
if (op->op1_def >= 0 && ssa->vars[op->op1_def].alias) {
|
||||
return 1;
|
||||
}
|
||||
if (opline->op2_type == IS_CV || opline->result_type != IS_UNUSED) {
|
||||
if (OP2_INFO() & MAY_BE_OBJECT) {
|
||||
/* object aliasing */
|
||||
@@ -428,30 +449,40 @@ int zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array,
|
||||
FOREACH_USE(ssa->vars + i, use) {
|
||||
zend_ssa_op *op = ssa->ops + use;
|
||||
zend_op *opline = op_array->opcodes + use;
|
||||
int enclosing_root;
|
||||
|
||||
if ((opline->opcode == ZEND_ASSIGN_DIM ||
|
||||
opline->opcode == ZEND_ASSIGN_OBJ) &&
|
||||
op->op2_use == i &&
|
||||
op->op1_use >= 0) {
|
||||
int root2 = ees[op->op1_use];
|
||||
enclosing_root = ees[op->op1_use];
|
||||
} else if ((opline->opcode == ZEND_INIT_ARRAY ||
|
||||
opline->opcode == ZEND_ADD_ARRAY_ELEMENT) &&
|
||||
op->op1_use == i &&
|
||||
op->result_def >= 0) {
|
||||
enclosing_root = ees[op->result_def];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ssa_vars[root2].escape_state == ESCAPE_STATE_UNKNOWN ||
|
||||
ssa_vars[root2].escape_state > ssa_vars[root].escape_state) {
|
||||
if (ssa_vars[root2].escape_state == ESCAPE_STATE_UNKNOWN) {
|
||||
ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
|
||||
} else {
|
||||
ssa_vars[root].escape_state = ssa_vars[root2].escape_state;
|
||||
}
|
||||
if (ssa_vars[root].escape_state == ESCAPE_STATE_GLOBAL_ESCAPE) {
|
||||
num_non_escaped--;
|
||||
if (num_non_escaped == 0) {
|
||||
i = ssa_vars_count;
|
||||
changed = 0;
|
||||
}
|
||||
break;
|
||||
if (ssa_vars[enclosing_root].escape_state == ESCAPE_STATE_UNKNOWN ||
|
||||
ssa_vars[enclosing_root].escape_state > ssa_vars[root].escape_state) {
|
||||
if (ssa_vars[enclosing_root].escape_state == ESCAPE_STATE_UNKNOWN) {
|
||||
ssa_vars[root].escape_state = ESCAPE_STATE_GLOBAL_ESCAPE;
|
||||
} else {
|
||||
ssa_vars[root].escape_state = ssa_vars[enclosing_root].escape_state;
|
||||
}
|
||||
if (ssa_vars[root].escape_state == ESCAPE_STATE_GLOBAL_ESCAPE) {
|
||||
num_non_escaped--;
|
||||
if (num_non_escaped == 0) {
|
||||
i = ssa_vars_count;
|
||||
changed = 0;
|
||||
} else {
|
||||
changed = 1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
} FOREACH_USE_END();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
DCE 007: Escaiping of enclosed arrays doesn't prevent removing of enclosing array
|
||||
--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
|
||||
function esc($x) {
|
||||
$a = [$x];
|
||||
$b = [$a];
|
||||
return $a;
|
||||
}
|
||||
--EXPECTF--
|
||||
$_main: ; (lines=1, args=0, vars=0, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_007.php:1-7
|
||||
L0: RETURN int(1)
|
||||
|
||||
esc: ; (lines=3, args=1, vars=2, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_007.php:2-6
|
||||
L0: CV0($x) = RECV 1
|
||||
L1: CV1($a) = INIT_ARRAY 1 (packed) CV0($x) NEXT
|
||||
L2: RETURN CV1($a)
|
||||
Reference in New Issue
Block a user