mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Remove NOP instructions, introduced bvy SCCP.
This commit discloses unrelated issue caused ext/soap/tests/bug70211.phpt failure.
This commit is contained in:
parent
9a2f50070d
commit
1ee9110b35
5 changed files with 23 additions and 8 deletions
|
@ -332,7 +332,9 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
|
||||||
zend_op *opline;
|
zend_op *opline;
|
||||||
zval tmp;
|
zval tmp;
|
||||||
|
|
||||||
sccp_optimize_op_array(op_array, ssa, call_map);
|
if (sccp_optimize_op_array(op_array, ssa, call_map)) {
|
||||||
|
remove_nops = 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (v = op_array->last_var; v < ssa->vars_count; v++) {
|
for (v = op_array->last_var; v < ssa->vars_count; v++) {
|
||||||
|
|
||||||
|
|
|
@ -1209,11 +1209,12 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
|
||||||
/* This will try to replace uses of SSA variables we have determined to be constant. Not all uses
|
/* This will try to replace uses of SSA variables we have determined to be constant. Not all uses
|
||||||
* can be replaced, because some instructions don't accept constant operands or only accept them
|
* can be replaced, because some instructions don't accept constant operands or only accept them
|
||||||
* if they have a certain type. */
|
* if they have a certain type. */
|
||||||
static void replace_constant_operands(sccp_ctx *ctx) {
|
static int replace_constant_operands(sccp_ctx *ctx) {
|
||||||
zend_ssa *ssa = ctx->ssa;
|
zend_ssa *ssa = ctx->ssa;
|
||||||
zend_op_array *op_array = ctx->op_array;
|
zend_op_array *op_array = ctx->op_array;
|
||||||
int i;
|
int i;
|
||||||
zval tmp;
|
zval tmp;
|
||||||
|
int removed_ops;
|
||||||
|
|
||||||
/* We iterate the variables backwards, so we can eliminate sequences like INIT_ROPE
|
/* We iterate the variables backwards, so we can eliminate sequences like INIT_ROPE
|
||||||
* and INIT_ARRAY. */
|
* and INIT_ARRAY. */
|
||||||
|
@ -1291,10 +1292,12 @@ static void replace_constant_operands(sccp_ctx *ctx) {
|
||||||
zend_ssa_remove_instr(ssa, call->arg_info[i].opline,
|
zend_ssa_remove_instr(ssa, call->arg_info[i].opline,
|
||||||
&ssa->ops[call->arg_info[i].opline - op_array->opcodes]);
|
&ssa->ops[call->arg_info[i].opline - op_array->opcodes]);
|
||||||
}
|
}
|
||||||
|
removed_ops = call->num_args + 2;
|
||||||
} else {
|
} else {
|
||||||
/* Ordinary computational instruction -> remove it */
|
/* Ordinary computational instruction -> remove it */
|
||||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||||
|
removed_ops++;
|
||||||
}
|
}
|
||||||
} else if (ssa_op->op1_def == i) {
|
} else if (ssa_op->op1_def == i) {
|
||||||
/* Compound assign or incdec -> convert to direct ASSIGN */
|
/* Compound assign or incdec -> convert to direct ASSIGN */
|
||||||
|
@ -1318,6 +1321,7 @@ static void replace_constant_operands(sccp_ctx *ctx) {
|
||||||
|
|
||||||
/* Remove OP_DATA opcode */
|
/* Remove OP_DATA opcode */
|
||||||
if (opline->opcode == ZEND_ASSIGN_DIM) {
|
if (opline->opcode == ZEND_ASSIGN_DIM) {
|
||||||
|
removed_ops++;
|
||||||
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
|
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1334,6 +1338,8 @@ static void replace_constant_operands(sccp_ctx *ctx) {
|
||||||
zend_ssa_remove_phi(ssa, var->definition_phi);
|
zend_ssa_remove_phi(ssa, var->definition_phi);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return removed_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sccp_context_init(sccp_ctx *ctx,
|
static void sccp_context_init(sccp_ctx *ctx,
|
||||||
|
@ -1370,10 +1376,11 @@ static void sccp_context_free(sccp_ctx *ctx) {
|
||||||
efree(ctx->values);
|
efree(ctx->values);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
|
int sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
|
||||||
{
|
{
|
||||||
scdf_ctx scdf;
|
scdf_ctx scdf;
|
||||||
sccp_ctx ctx;
|
sccp_ctx ctx;
|
||||||
|
int removed_ops = 0;
|
||||||
|
|
||||||
sccp_context_init(&ctx, ssa, op_array, call_map);
|
sccp_context_init(&ctx, ssa, op_array, call_map);
|
||||||
|
|
||||||
|
@ -1384,9 +1391,11 @@ void sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_in
|
||||||
scdf_init(&scdf, op_array, ssa, &ctx);
|
scdf_init(&scdf, op_array, ssa, &ctx);
|
||||||
scdf_solve(&scdf, "SCCP");
|
scdf_solve(&scdf, "SCCP");
|
||||||
|
|
||||||
scdf_remove_unreachable_blocks(&scdf);
|
removed_ops += scdf_remove_unreachable_blocks(&scdf);
|
||||||
replace_constant_operands(&ctx);
|
removed_ops += replace_constant_operands(&ctx);
|
||||||
|
|
||||||
scdf_free(&scdf);
|
scdf_free(&scdf);
|
||||||
sccp_context_free(&ctx);
|
sccp_context_free(&ctx);
|
||||||
|
|
||||||
|
return removed_ops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,14 +216,18 @@ static zend_bool kept_alive_by_live_range(scdf_ctx *scdf, uint32_t block) {
|
||||||
/* Removes unreachable blocks. This will remove both the instructions (and phis) in the
|
/* Removes unreachable blocks. This will remove both the instructions (and phis) in the
|
||||||
* blocks, as well as remove them from the successor / predecessor lists and mark them
|
* blocks, as well as remove them from the successor / predecessor lists and mark them
|
||||||
* unreachable. Blocks already marked unreachable are not removed. */
|
* unreachable. Blocks already marked unreachable are not removed. */
|
||||||
void scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
|
int scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
|
||||||
zend_ssa *ssa = scdf->ssa;
|
zend_ssa *ssa = scdf->ssa;
|
||||||
int i;
|
int i;
|
||||||
|
int removed_ops = 0;
|
||||||
|
|
||||||
for (i = 0; i < ssa->cfg.blocks_count; i++) {
|
for (i = 0; i < ssa->cfg.blocks_count; i++) {
|
||||||
if (!zend_bitset_in(scdf->executable_blocks, i)
|
if (!zend_bitset_in(scdf->executable_blocks, i)
|
||||||
&& (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
|
&& (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
|
||||||
&& !kept_alive_by_live_range(scdf, i)) {
|
&& !kept_alive_by_live_range(scdf, i)) {
|
||||||
|
removed_ops += ssa->cfg.blocks[i].len;
|
||||||
zend_ssa_remove_block(scdf->op_array, ssa, i);
|
zend_ssa_remove_block(scdf->op_array, ssa, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return removed_ops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ void scdf_init(scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa, void *ctx
|
||||||
void scdf_solve(scdf_ctx *scdf, const char *name);
|
void scdf_solve(scdf_ctx *scdf, const char *name);
|
||||||
void scdf_free(scdf_ctx *scdf);
|
void scdf_free(scdf_ctx *scdf);
|
||||||
|
|
||||||
void scdf_remove_unreachable_blocks(scdf_ctx *scdf);
|
int scdf_remove_unreachable_blocks(scdf_ctx *scdf);
|
||||||
|
|
||||||
/* Add uses to worklist */
|
/* Add uses to worklist */
|
||||||
static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {
|
static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {
|
||||||
|
|
|
@ -110,6 +110,6 @@ uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);
|
||||||
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
|
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
|
||||||
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
|
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
|
||||||
zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode);
|
zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode);
|
||||||
void sccp_optimize_op_array(zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
|
int sccp_optimize_op_array(zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue