1
0
mirror of https://github.com/php/php-src.git synced 2026-04-18 13:31:27 +02:00

Eliminate more VERIFY_RETURN_TYPE instructions

This commit is contained in:
Dmitry Stogov
2021-12-27 23:40:21 +03:00
parent 1d4482908b
commit eb43f8a4f8
3 changed files with 81 additions and 18 deletions

View File

@@ -1293,30 +1293,52 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
} else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE
&& opline->op1_type != IS_CONST
&& ssa->ops[op_1].op1_def == v
&& ssa->ops[op_1].op1_use >= 0
&& ssa->ops[op_1].op1_use_chain == -1
&& can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) {
&& ssa->ops[op_1].op1_use >= 0) {
int orig_var = ssa->ops[op_1].op1_use;
int ret = ssa->vars[v].use_chain;
if (ssa->ops[op_1].op1_use_chain == -1
&& can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) {
// op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP
int orig_var = ssa->ops[op_1].op1_use;
zend_ssa_unlink_use_chain(ssa, op_1, orig_var);
zend_ssa_unlink_use_chain(ssa, op_1, orig_var);
if (ret >= 0) {
ssa->ops[ret].op1_use = orig_var;
ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain;
ssa->vars[orig_var].use_chain = ret;
}
ssa->vars[v].definition = -1;
ssa->vars[v].use_chain = -1;
ssa->ops[op_1].op1_def = -1;
ssa->ops[op_1].op1_use = -1;
MAKE_NOP(opline);
remove_nops = 1;
} else if (ret >= 0
&& ssa->ops[ret].op1_use == v
&& ssa->ops[ret].op1_use_chain == -1
&& can_elide_return_type_check(ctx->script, op_array, ssa, &ssa->ops[op_1])) {
// op_1: VERIFY_RETURN_TYPE #orig_var.? [T] -> #v.? [T] => NOP
zend_ssa_replace_use_chain(ssa, op_1, ret, orig_var);
int ret = ssa->vars[v].use_chain;
if (ret >= 0) {
ssa->ops[ret].op1_use = orig_var;
ssa->ops[ret].op1_use_chain = ssa->vars[orig_var].use_chain;
ssa->vars[orig_var].use_chain = ret;
ssa->ops[ret].op1_use_chain = ssa->ops[op_1].op1_use_chain;
ssa->vars[v].definition = -1;
ssa->vars[v].use_chain = -1;
ssa->ops[op_1].op1_def = -1;
ssa->ops[op_1].op1_use = -1;
MAKE_NOP(opline);
remove_nops = 1;
}
ssa->vars[v].definition = -1;
ssa->vars[v].use_chain = -1;
ssa->ops[op_1].op1_def = -1;
ssa->ops[op_1].op1_use = -1;
MAKE_NOP(opline);
remove_nops = 1;
}
}

View File

@@ -1209,6 +1209,46 @@ void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var) /* {{{ */
}
/* }}} */
void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var) /* {{{ */
{
if (ssa->vars[var].use_chain == op) {
ssa->vars[var].use_chain = new_op;
return;
} else {
int use = ssa->vars[var].use_chain;
while (use >= 0) {
if (ssa->ops[use].result_use == var) {
if (ssa->ops[use].res_use_chain == op) {
ssa->ops[use].res_use_chain = new_op;
return;
} else {
use = ssa->ops[use].res_use_chain;
}
} else if (ssa->ops[use].op1_use == var) {
if (ssa->ops[use].op1_use_chain == op) {
ssa->ops[use].op1_use_chain = new_op;
return;
} else {
use = ssa->ops[use].op1_use_chain;
}
} else if (ssa->ops[use].op2_use == var) {
if (ssa->ops[use].op2_use_chain == op) {
ssa->ops[use].op2_use_chain = new_op;
return;
} else {
use = ssa->ops[use].op2_use_chain;
}
} else {
break;
}
}
}
/* something wrong */
ZEND_UNREACHABLE();
}
/* }}} */
void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) /* {{{ */
{
if (ssa_op->result_use >= 0) {

View File

@@ -149,6 +149,7 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip
ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa);
ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *opline, uint32_t k, uint32_t build_flags, int ssa_vars_count, zend_ssa_op *ssa_ops, int *var);
void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var);
void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var);
void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to);
void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op);