Skip to content

Commit 93d3e7d

Browse files
committed
Made sccp_ctx to be an "extension" of scdf_ctx and remove duplicate data.
1 parent f810c6f commit 93d3e7d

File tree

3 files changed

+34
-40
lines changed

3 files changed

+34
-40
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@
7373
#endif
7474

7575
typedef struct _sccp_ctx {
76-
zend_op_array *op_array;
77-
zend_ssa *ssa;
76+
scdf_ctx scdf;
7877
zend_call_info **call_map;
7978
zval *values;
8079
zval top;
@@ -121,7 +120,7 @@ static void set_value(scdf_ctx *scdf, sccp_ctx *ctx, int var, zval *new) {
121120

122121
static zval *get_op1_value(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
123122
if (opline->op1_type == IS_CONST) {
124-
return CT_CONSTANT_EX(ctx->op_array, opline->op1.constant);
123+
return CT_CONSTANT_EX(ctx->scdf.op_array, opline->op1.constant);
125124
} else if (ssa_op->op1_use != -1) {
126125
return &ctx->values[ssa_op->op1_use];
127126
} else {
@@ -131,7 +130,7 @@ static zval *get_op1_value(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op)
131130

132131
static zval *get_op2_value(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
133132
if (opline->op2_type == IS_CONST) {
134-
return CT_CONSTANT_EX(ctx->op_array, opline->op2.constant);
133+
return CT_CONSTANT_EX(ctx->scdf.op_array, opline->op2.constant);
135134
} else if (ssa_op->op2_use != -1) {
136135
return &ctx->values[ssa_op->op2_use];
137136
} else {
@@ -233,10 +232,10 @@ static zend_bool can_replace_op2(
233232

234233
static zend_bool try_replace_op1(
235234
sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op, int var, zval *value) {
236-
if (ssa_op->op1_use == var && can_replace_op1(ctx->op_array, opline, ssa_op)) {
235+
if (ssa_op->op1_use == var && can_replace_op1(ctx->scdf.op_array, opline, ssa_op)) {
237236
zval zv;
238237
ZVAL_COPY(&zv, value);
239-
if (zend_optimizer_update_op1_const(ctx->op_array, opline, &zv)) {
238+
if (zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, &zv)) {
240239
return 1;
241240
} else {
242241
// TODO: check the following special cases ???
@@ -248,7 +247,7 @@ static zend_bool try_replace_op1(
248247
if (Z_TYPE(zv) == IS_STRING) {
249248
zend_string_hash_val(Z_STR(zv));
250249
}
251-
opline->op1.constant = zend_optimizer_add_literal(ctx->op_array, &zv);
250+
opline->op1.constant = zend_optimizer_add_literal(ctx->scdf.op_array, &zv);
252251
opline->op1_type = IS_CONST;
253252
return 1;
254253
}
@@ -260,10 +259,10 @@ static zend_bool try_replace_op1(
260259

261260
static zend_bool try_replace_op2(
262261
sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op, int var, zval *value) {
263-
if (ssa_op->op2_use == var && can_replace_op2(ctx->op_array, opline, ssa_op)) {
262+
if (ssa_op->op2_use == var && can_replace_op2(ctx->scdf.op_array, opline, ssa_op)) {
264263
zval zv;
265264
ZVAL_COPY(&zv, value);
266-
if (zend_optimizer_update_op2_const(ctx->op_array, opline, &zv)) {
265+
if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline, &zv)) {
267266
return 1;
268267
} else {
269268
zval_ptr_dtor_nogc(&zv);
@@ -614,7 +613,7 @@ static inline int ct_eval_func_call(
614613
#define SKIP_IF_TOP(op) if (IS_TOP(op)) break;
615614

616615
static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_op) {
617-
sccp_ctx *ctx = (sccp_ctx *) scdf->ctx;
616+
sccp_ctx *ctx = (sccp_ctx *) scdf;
618617
zval *op1, *op2, zv; /* zv is a temporary to hold result values */
619618

620619
op1 = get_op1_value(ctx, opline, ssa_op);
@@ -624,7 +623,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
624623
case ZEND_ASSIGN:
625624
/* The value of op1 is irrelevant here, because we are overwriting it
626625
* -- unless it can be a reference, in which case we propagate a BOT. */
627-
if (IS_BOT(op1) && (ctx->ssa->var_info[ssa_op->op1_use].type & MAY_BE_REF)) {
626+
if (IS_BOT(op1) && (ctx->scdf.ssa->var_info[ssa_op->op1_use].type & MAY_BE_REF)) {
628627
SET_RESULT_BOT(op1);
629628
} else {
630629
SET_RESULT(op1, op2);
@@ -636,7 +635,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
636635
/* We may be able to evaluate TYPE_CHECK based on type inference info,
637636
* even if we don't know the precise value. */
638637
if (!value_known(op1)) {
639-
uint32_t type = ctx->ssa->var_info[ssa_op->op1_use].type;
638+
uint32_t type = ctx->scdf.ssa->var_info[ssa_op->op1_use].type;
640639
uint32_t expected_type = opline->extended_value == _IS_BOOL
641640
? (MAY_BE_TRUE|MAY_BE_FALSE) : (1 << opline->extended_value);
642641
if (!(type & expected_type) && !(type & MAY_BE_UNDEF)) {
@@ -654,7 +653,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
654653
break;
655654
case ZEND_ASSIGN_DIM:
656655
/* If $a in $a[$b]=$c is UNDEF, treat it like NULL. There is no warning. */
657-
if ((ctx->ssa->var_info[ssa_op->op1_use].type & MAY_BE_ANY) == 0) {
656+
if ((ctx->scdf.ssa->var_info[ssa_op->op1_use].type & MAY_BE_ANY) == 0) {
658657
op1 = &EG(uninitialized_zval);
659658
}
660659
break;
@@ -668,13 +667,13 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
668667
return;
669668
}
670669

671-
call = ctx->call_map[opline - ctx->op_array->opcodes];
670+
call = ctx->call_map[opline - ctx->scdf.op_array->opcodes];
672671
if (IS_TOP(op1) || !call || call->caller_call_opline->opcode != ZEND_DO_ICALL) {
673672
return;
674673
}
675674

676675
opline = call->caller_call_opline;
677-
ssa_op = &ctx->ssa->ops[opline - ctx->op_array->opcodes];
676+
ssa_op = &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes];
678677
break;
679678
}
680679
}
@@ -983,8 +982,8 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
983982
break;
984983
}
985984

986-
call = ctx->call_map[opline - ctx->op_array->opcodes];
987-
name = CT_CONSTANT_EX(ctx->op_array, call->caller_init_opline->op2.constant);
985+
call = ctx->call_map[opline - ctx->scdf.op_array->opcodes];
986+
name = CT_CONSTANT_EX(ctx->scdf.op_array, call->caller_init_opline->op2.constant);
988987

989988
/* We already know it can't be evaluated, don't bother checking again */
990989
if (ssa_op->result_def < 0 || IS_BOT(&ctx->values[ssa_op->result_def])) {
@@ -1005,7 +1004,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
10051004
}
10061005

10071006
args[i] = get_op1_value(ctx, opline,
1008-
&ctx->ssa->ops[opline - ctx->op_array->opcodes]);
1007+
&ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
10091008
if (args[i]) {
10101009
if (IS_BOT(args[i])) {
10111010
SET_RESULT_BOT(result);
@@ -1056,7 +1055,7 @@ static void sccp_mark_feasible_successors(
10561055
scdf_ctx *scdf,
10571056
int block_num, zend_basic_block *block,
10581057
zend_op *opline, zend_ssa_op *ssa_op) {
1059-
sccp_ctx *ctx = (sccp_ctx *) scdf->ctx;
1058+
sccp_ctx *ctx = (sccp_ctx *) scdf;
10601059
zval *op1;
10611060
int s;
10621061

@@ -1136,8 +1135,8 @@ static void join_phi_values(zval *a, zval *b) {
11361135
}
11371136

11381137
static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) {
1139-
sccp_ctx *ctx = (sccp_ctx *) scdf->ctx;
1140-
zend_ssa *ssa = ctx->ssa;
1138+
sccp_ctx *ctx = (sccp_ctx *) scdf;
1139+
zend_ssa *ssa = scdf->ssa;
11411140
ZEND_ASSERT(phi->ssa_var >= 0);
11421141
if (!IS_BOT(&ctx->values[phi->ssa_var])) {
11431142
zend_basic_block *block = &ssa->cfg.blocks[phi->block];
@@ -1170,10 +1169,10 @@ static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) {
11701169
}
11711170

11721171
static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
1173-
zend_ssa *ssa = ctx->ssa;
1172+
zend_ssa *ssa = ctx->scdf.ssa;
11741173
zend_ssa_var_info *info = &ssa->var_info[var_num];
11751174

1176-
if (ssa->vars[var_num].var >= ctx->op_array->last_var) {
1175+
if (ssa->vars[var_num].var >= ctx->scdf.op_array->last_var) {
11771176
// TODO Non-CVs may cause issues with FREEs
11781177
return NULL;
11791178
}
@@ -1210,8 +1209,8 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
12101209
* can be replaced, because some instructions don't accept constant operands or only accept them
12111210
* if they have a certain type. */
12121211
static int replace_constant_operands(sccp_ctx *ctx) {
1213-
zend_ssa *ssa = ctx->ssa;
1214-
zend_op_array *op_array = ctx->op_array;
1212+
zend_ssa *ssa = ctx->scdf.ssa;
1213+
zend_op_array *op_array = ctx->scdf.op_array;
12151214
int i;
12161215
zval tmp;
12171216
int removed_ops;
@@ -1352,8 +1351,6 @@ static int replace_constant_operands(sccp_ctx *ctx) {
13521351
static void sccp_context_init(sccp_ctx *ctx,
13531352
zend_ssa *ssa, zend_op_array *op_array, zend_call_info **call_map) {
13541353
int i;
1355-
ctx->op_array = op_array;
1356-
ctx->ssa = ssa;
13571354
ctx->call_map = call_map;
13581355
ctx->values = emalloc(sizeof(zval) * ssa->vars_count);
13591356

@@ -1377,32 +1374,31 @@ static void sccp_context_init(sccp_ctx *ctx,
13771374

13781375
static void sccp_context_free(sccp_ctx *ctx) {
13791376
int i;
1380-
for (i = ctx->op_array->last_var; i < ctx->ssa->vars_count; ++i) {
1377+
for (i = ctx->scdf.op_array->last_var; i < ctx->scdf.ssa->vars_count; ++i) {
13811378
zval_ptr_dtor_nogc(&ctx->values[i]);
13821379
}
13831380
efree(ctx->values);
13841381
}
13851382

13861383
int sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
13871384
{
1388-
scdf_ctx scdf;
13891385
sccp_ctx ctx;
13901386
int removed_ops = 0;
13911387

13921388
sccp_context_init(&ctx, ssa, op_array, call_map);
13931389

1394-
scdf.handlers.visit_instr = sccp_visit_instr;
1395-
scdf.handlers.visit_phi = sccp_visit_phi;
1396-
scdf.handlers.mark_feasible_successors = sccp_mark_feasible_successors;
1390+
ctx.scdf.handlers.visit_instr = sccp_visit_instr;
1391+
ctx.scdf.handlers.visit_phi = sccp_visit_phi;
1392+
ctx.scdf.handlers.mark_feasible_successors = sccp_mark_feasible_successors;
13971393

1398-
scdf_init(&scdf, op_array, ssa, &ctx);
1399-
scdf_solve(&scdf, "SCCP");
1394+
scdf_init(&ctx.scdf, op_array, ssa);
1395+
scdf_solve(&ctx.scdf, "SCCP");
14001396

1401-
removed_ops += scdf_remove_unreachable_blocks(&scdf);
1397+
removed_ops += scdf_remove_unreachable_blocks(&ctx.scdf);
14021398
removed_ops += replace_constant_operands(&ctx);
14031399

1404-
scdf_free(&scdf);
14051400
sccp_context_free(&ctx);
1401+
scdf_free(&ctx.scdf);
14061402

14071403
return removed_ops;
14081404
}

ext/opcache/Optimizer/scdf.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ void scdf_mark_edge_feasible(scdf_ctx *ctx, int from, int to) {
8080
}
8181
}
8282

83-
void scdf_init(scdf_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, void *extra_ctx) {
83+
void scdf_init(scdf_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa) {
8484
uint32_t edges_count = 0;
8585
int b;
8686

@@ -90,7 +90,6 @@ void scdf_init(scdf_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, void *extr
9090

9191
ctx->op_array = op_array;
9292
ctx->ssa = ssa;
93-
ctx->ctx = extra_ctx;
9493

9594
ctx->instr_worklist_len = zend_bitset_len(op_array->last);
9695
ctx->phi_var_worklist_len = zend_bitset_len(ssa->vars_count);

ext/opcache/Optimizer/scdf.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "zend_bitset.h"
2323

2424
typedef struct _scdf_ctx {
25-
void *ctx;
2625
zend_op_array *op_array;
2726
zend_ssa *ssa;
2827
zend_bitset instr_worklist;
@@ -47,7 +46,7 @@ typedef struct _scdf_ctx {
4746
} handlers;
4847
} scdf_ctx;
4948

50-
void scdf_init(scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa, void *ctx);
49+
void scdf_init(scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa);
5150
void scdf_solve(scdf_ctx *scdf, const char *name);
5251
void scdf_free(scdf_ctx *scdf);
5352

0 commit comments

Comments
 (0)