mirror of
https://github.com/php/php-src.git
synced 2025-08-19 17:04:47 +02:00
Remove unused temporary variables
This commit is contained in:
parent
7548789c60
commit
431ea10fb2
17 changed files with 66 additions and 53 deletions
|
@ -20,84 +20,96 @@
|
|||
#include "Optimizer/zend_optimizer_internal.h"
|
||||
#include "zend_bitset.h"
|
||||
|
||||
/* This pass removes all CVs that are completely unused. It does *not* merge any CVs.
|
||||
/* This pass removes all CVs and temporaries that are completely unused. It does *not* merge any CVs or TMPs.
|
||||
* This pass does not operate on SSA form anymore. */
|
||||
void zend_optimizer_compact_vars(zend_op_array *op_array) {
|
||||
int i;
|
||||
|
||||
ALLOCA_FLAG(use_heap1);
|
||||
ALLOCA_FLAG(use_heap2);
|
||||
uint32_t used_cvs_len = zend_bitset_len(op_array->last_var);
|
||||
zend_bitset used_cvs = ZEND_BITSET_ALLOCA(used_cvs_len, use_heap1);
|
||||
uint32_t *cv_map = do_alloca(op_array->last_var * sizeof(uint32_t), use_heap2);
|
||||
uint32_t num_cvs, tmp_offset;
|
||||
uint32_t used_vars_len = zend_bitset_len(op_array->last_var + op_array->T);
|
||||
zend_bitset used_vars = ZEND_BITSET_ALLOCA(used_vars_len, use_heap1);
|
||||
uint32_t *vars_map = do_alloca((op_array->last_var + op_array->T) * sizeof(uint32_t), use_heap2);
|
||||
uint32_t num_cvs, num_tmps;
|
||||
|
||||
/* Determine which CVs are used */
|
||||
zend_bitset_clear(used_cvs, used_cvs_len);
|
||||
zend_bitset_clear(used_vars, used_vars_len);
|
||||
for (i = 0; i < op_array->last; i++) {
|
||||
zend_op *opline = &op_array->opcodes[i];
|
||||
if (opline->op1_type == IS_CV) {
|
||||
zend_bitset_incl(used_cvs, VAR_NUM(opline->op1.var));
|
||||
if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
zend_bitset_incl(used_vars, VAR_NUM(opline->op1.var));
|
||||
}
|
||||
if (opline->op2_type == IS_CV) {
|
||||
zend_bitset_incl(used_cvs, VAR_NUM(opline->op2.var));
|
||||
if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
zend_bitset_incl(used_vars, VAR_NUM(opline->op2.var));
|
||||
}
|
||||
if (opline->result_type == IS_CV) {
|
||||
zend_bitset_incl(used_cvs, VAR_NUM(opline->result.var));
|
||||
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
zend_bitset_incl(used_vars, VAR_NUM(opline->result.var));
|
||||
if (opline->opcode == ZEND_ROPE_INIT) {
|
||||
uint32_t num = ((opline->extended_value * sizeof(zend_string*)) + (sizeof(zval) - 1)) / sizeof(zval);
|
||||
while (num > 1) {
|
||||
num--;
|
||||
zend_bitset_incl(used_vars, VAR_NUM(opline->result.var) + num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
num_cvs = 0;
|
||||
for (i = 0; i < op_array->last_var; i++) {
|
||||
if (zend_bitset_in(used_cvs, i)) {
|
||||
cv_map[i] = num_cvs++;
|
||||
if (zend_bitset_in(used_vars, i)) {
|
||||
vars_map[i] = num_cvs++;
|
||||
} else {
|
||||
cv_map[i] = (uint32_t) -1;
|
||||
vars_map[i] = (uint32_t) -1;
|
||||
}
|
||||
}
|
||||
|
||||
free_alloca(used_cvs, use_heap1);
|
||||
if (num_cvs == op_array->last_var) {
|
||||
free_alloca(cv_map, use_heap2);
|
||||
num_tmps = 0;
|
||||
for (i = op_array->last_var; i < op_array->last_var + op_array->T; i++) {
|
||||
if (zend_bitset_in(used_vars, i)) {
|
||||
vars_map[i] = num_cvs + num_tmps++;
|
||||
} else {
|
||||
vars_map[i] = (uint32_t) -1;
|
||||
}
|
||||
}
|
||||
|
||||
free_alloca(used_vars, use_heap1);
|
||||
if (num_cvs == op_array->last_var && num_tmps == op_array->T) {
|
||||
free_alloca(vars_map, use_heap2);
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_ASSERT(num_cvs < op_array->last_var);
|
||||
tmp_offset = op_array->last_var - num_cvs;
|
||||
ZEND_ASSERT(num_cvs <= op_array->last_var);
|
||||
ZEND_ASSERT(num_tmps <= op_array->T);
|
||||
|
||||
/* Update CV and TMP references in opcodes */
|
||||
for (i = 0; i < op_array->last; i++) {
|
||||
zend_op *opline = &op_array->opcodes[i];
|
||||
if (opline->op1_type == IS_CV) {
|
||||
opline->op1.var = NUM_VAR(cv_map[VAR_NUM(opline->op1.var)]);
|
||||
} else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op1.var -= sizeof(zval) * tmp_offset;
|
||||
if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op1.var = NUM_VAR(vars_map[VAR_NUM(opline->op1.var)]);
|
||||
}
|
||||
if (opline->op2_type == IS_CV) {
|
||||
opline->op2.var = NUM_VAR(cv_map[VAR_NUM(opline->op2.var)]);
|
||||
} else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op2.var -= sizeof(zval) * tmp_offset;
|
||||
if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op2.var = NUM_VAR(vars_map[VAR_NUM(opline->op2.var)]);
|
||||
}
|
||||
if (opline->result_type == IS_CV) {
|
||||
opline->result.var = NUM_VAR(cv_map[VAR_NUM(opline->result.var)]);
|
||||
} else if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
|
||||
opline->result.var -= sizeof(zval) * tmp_offset;
|
||||
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
opline->result.var = NUM_VAR(vars_map[VAR_NUM(opline->result.var)]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update TMP references in live ranges */
|
||||
if (op_array->live_range) {
|
||||
for (i = 0; i < op_array->last_live_range; i++) {
|
||||
op_array->live_range[i].var -= sizeof(zval) * tmp_offset;
|
||||
op_array->live_range[i].var =
|
||||
(op_array->live_range[i].var & ZEND_LIVE_MASK) |
|
||||
NUM_VAR(vars_map[VAR_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK)]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update CV name table */
|
||||
{
|
||||
if (num_cvs != op_array->last_var) {
|
||||
zend_string **names = safe_emalloc(sizeof(zend_string *), num_cvs, 0);
|
||||
for (i = 0; i < op_array->last_var; i++) {
|
||||
if (cv_map[i] != (uint32_t) -1) {
|
||||
names[cv_map[i]] = op_array->vars[i];
|
||||
if (vars_map[i] != (uint32_t) -1) {
|
||||
names[vars_map[i]] = op_array->vars[i];
|
||||
} else {
|
||||
zend_string_release(op_array->vars[i]);
|
||||
}
|
||||
|
@ -107,6 +119,7 @@ void zend_optimizer_compact_vars(zend_op_array *op_array) {
|
|||
}
|
||||
|
||||
op_array->last_var = num_cvs;
|
||||
op_array->T = num_tmps;
|
||||
|
||||
free_alloca(cv_map, use_heap2);
|
||||
free_alloca(vars_map, use_heap2);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %sdce_001.php:1-8
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=5, args=4, vars=4, tmps=3)
|
||||
foo: ; (lines=5, args=4, vars=4, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_001.php:2-6
|
||||
L0: CV0($s1) = RECV 1
|
||||
|
|
|
@ -24,7 +24,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %sdce_002.php:1-11
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=5, args=1, vars=2, tmps=1)
|
||||
foo: ; (lines=5, args=1, vars=2, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_002.php:2-9
|
||||
L0: CV0($a) = RECV 1
|
||||
|
|
|
@ -20,7 +20,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %sdce_003.php:1-7
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_003.php:2-5
|
||||
L0: CV0($a) = RECV 1
|
||||
|
|
|
@ -21,7 +21,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %sdce_004.php:1-8
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=4, args=2, vars=3, tmps=1)
|
||||
foo: ; (lines=4, args=2, vars=3, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_004.php:2-7
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -21,7 +21,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %sdce_005.php:1-8
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=2, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=2, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %sdce_005.php:4-7
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -22,7 +22,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_001.php:1-9
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=1, args=0, vars=0, tmps=1)
|
||||
foo: ; (lines=1, args=0, vars=0, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_001.php:2-7
|
||||
L0: RETURN int(4)
|
||||
|
|
|
@ -27,7 +27,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_002.php:1-14
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=4, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=4, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_002.php:2-12
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -27,7 +27,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_003.php:1-14
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=1)
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_003.php:2-12
|
||||
L0: ECHO int(1)
|
||||
|
|
|
@ -30,7 +30,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_004.php:1-17
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=4, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=4, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_004.php:2-15
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -20,7 +20,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_005.php:1-7
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_005.php:2-5
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -24,7 +24,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_007.php:1-11
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=5, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=5, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_007.php:2-9
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -21,7 +21,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_009.php:1-8
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=3, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_009.php:2-6
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -28,7 +28,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_010.php:1-15
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=1)
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_010.php:2-13
|
||||
L0: ECHO int(1)
|
||||
|
|
|
@ -27,7 +27,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_011.php:1-14
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=5, args=1, vars=1, tmps=1)
|
||||
foo: ; (lines=5, args=1, vars=1, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_011.php:2-12
|
||||
L0: CV0($x) = RECV 1
|
||||
|
|
|
@ -30,7 +30,7 @@ $_main: ; (lines=1, args=0, vars=0, tmps=0)
|
|||
; %ssccp_012.php:1-17
|
||||
L0: RETURN int(1)
|
||||
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=1)
|
||||
foo: ; (lines=3, args=0, vars=0, tmps=0)
|
||||
; (after optimizer)
|
||||
; %ssccp_012.php:2-15
|
||||
L0: ECHO int(1)
|
||||
|
|
|
@ -12,7 +12,7 @@ opcache.opt_debug_level=0x20000
|
|||
return isset($undef) || php_sapi_name() == php_sapi_name();
|
||||
?>
|
||||
--EXPECTF--
|
||||
$_main: ; (lines=4, args=0, vars=1, tmps=3)
|
||||
$_main: ; (lines=4, args=0, vars=1, tmps=1)
|
||||
; (after optimizer)
|
||||
; %ssccp_016.php:1-4
|
||||
L0: T1 = ISSET_ISEMPTY_CV (isset) CV0($undef)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue