Skip to content

Commit 1ee9110

Browse files
committed
Remove NOP instructions, introduced bvy SCCP.
This commit discloses unrelated issue caused ext/soap/tests/bug70211.phpt failure.
1 parent 9a2f500 commit 1ee9110

File tree

5 files changed

+23
-8
lines changed

5 files changed

+23
-8
lines changed

ext/opcache/Optimizer/dfa_pass.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,9 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
332332
zend_op *opline;
333333
zval tmp;
334334

335-
sccp_optimize_op_array(op_array, ssa, call_map);
335+
if (sccp_optimize_op_array(op_array, ssa, call_map)) {
336+
remove_nops = 1;
337+
}
336338

337339
for (v = op_array->last_var; v < ssa->vars_count; v++) {
338340

ext/opcache/Optimizer/sccp.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,11 +1209,12 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
12091209
/* This will try to replace uses of SSA variables we have determined to be constant. Not all uses
12101210
* can be replaced, because some instructions don't accept constant operands or only accept them
12111211
* if they have a certain type. */
1212-
static void replace_constant_operands(sccp_ctx *ctx) {
1212+
static int replace_constant_operands(sccp_ctx *ctx) {
12131213
zend_ssa *ssa = ctx->ssa;
12141214
zend_op_array *op_array = ctx->op_array;
12151215
int i;
12161216
zval tmp;
1217+
int removed_ops;
12171218

12181219
/* We iterate the variables backwards, so we can eliminate sequences like INIT_ROPE
12191220
* and INIT_ARRAY. */
@@ -1291,10 +1292,12 @@ static void replace_constant_operands(sccp_ctx *ctx) {
12911292
zend_ssa_remove_instr(ssa, call->arg_info[i].opline,
12921293
&ssa->ops[call->arg_info[i].opline - op_array->opcodes]);
12931294
}
1295+
removed_ops = call->num_args + 2;
12941296
} else {
12951297
/* Ordinary computational instruction -> remove it */
12961298
zend_ssa_remove_result_def(ssa, ssa_op);
12971299
zend_ssa_remove_instr(ssa, opline, ssa_op);
1300+
removed_ops++;
12981301
}
12991302
} else if (ssa_op->op1_def == i) {
13001303
/* Compound assign or incdec -> convert to direct ASSIGN */
@@ -1318,6 +1321,7 @@ static void replace_constant_operands(sccp_ctx *ctx) {
13181321

13191322
/* Remove OP_DATA opcode */
13201323
if (opline->opcode == ZEND_ASSIGN_DIM) {
1324+
removed_ops++;
13211325
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
13221326
}
13231327

@@ -1334,6 +1338,8 @@ static void replace_constant_operands(sccp_ctx *ctx) {
13341338
zend_ssa_remove_phi(ssa, var->definition_phi);
13351339
}*/
13361340
}
1341+
1342+
return removed_ops;
13371343
}
13381344

13391345
static void sccp_context_init(sccp_ctx *ctx,
@@ -1370,10 +1376,11 @@ static void sccp_context_free(sccp_ctx *ctx) {
13701376
efree(ctx->values);
13711377
}
13721378

1373-
void sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
1379+
int sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
13741380
{
13751381
scdf_ctx scdf;
13761382
sccp_ctx ctx;
1383+
int removed_ops = 0;
13771384

13781385
sccp_context_init(&ctx, ssa, op_array, call_map);
13791386

@@ -1384,9 +1391,11 @@ void sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_in
13841391
scdf_init(&scdf, op_array, ssa, &ctx);
13851392
scdf_solve(&scdf, "SCCP");
13861393

1387-
scdf_remove_unreachable_blocks(&scdf);
1388-
replace_constant_operands(&ctx);
1394+
removed_ops += scdf_remove_unreachable_blocks(&scdf);
1395+
removed_ops += replace_constant_operands(&ctx);
13891396

13901397
scdf_free(&scdf);
13911398
sccp_context_free(&ctx);
1399+
1400+
return removed_ops;
13921401
}

ext/opcache/Optimizer/scdf.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,18 @@ static zend_bool kept_alive_by_live_range(scdf_ctx *scdf, uint32_t block) {
216216
/* Removes unreachable blocks. This will remove both the instructions (and phis) in the
217217
* blocks, as well as remove them from the successor / predecessor lists and mark them
218218
* unreachable. Blocks already marked unreachable are not removed. */
219-
void scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
219+
int scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
220220
zend_ssa *ssa = scdf->ssa;
221221
int i;
222+
int removed_ops = 0;
223+
222224
for (i = 0; i < ssa->cfg.blocks_count; i++) {
223225
if (!zend_bitset_in(scdf->executable_blocks, i)
224226
&& (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
225227
&& !kept_alive_by_live_range(scdf, i)) {
228+
removed_ops += ssa->cfg.blocks[i].len;
226229
zend_ssa_remove_block(scdf->op_array, ssa, i);
227230
}
228231
}
232+
return removed_ops;
229233
}

ext/opcache/Optimizer/scdf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void scdf_init(scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa, void *ctx
5151
void scdf_solve(scdf_ctx *scdf, const char *name);
5252
void scdf_free(scdf_ctx *scdf);
5353

54-
void scdf_remove_unreachable_blocks(scdf_ctx *scdf);
54+
int scdf_remove_unreachable_blocks(scdf_ctx *scdf);
5555

5656
/* Add uses to worklist */
5757
static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {

ext/opcache/Optimizer/zend_optimizer_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,6 @@ uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);
110110
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
111111
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
112112
zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode);
113-
void sccp_optimize_op_array(zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
113+
int sccp_optimize_op_array(zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
114114

115115
#endif

0 commit comments

Comments
 (0)