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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user