Skip to content

Commit 58f7c17

Browse files
committed
Use arena for temporary data.
1 parent 93d3e7d commit 58f7c17

File tree

5 files changed

+76
-81
lines changed

5 files changed

+76
-81
lines changed

ext/opcache/Optimizer/dfa_pass.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
453453
zval tmp;
454454

455455
if (ZEND_OPTIMIZER_PASS_8 & ctx->optimization_level) {
456-
if (sccp_optimize_op_array(op_array, ssa, call_map)) {
456+
if (sccp_optimize_op_array(ctx, op_array, ssa, call_map)) {
457457
remove_nops = 1;
458458
}
459459
if (ZEND_FUNC_INFO(op_array)) {

ext/opcache/Optimizer/sccp.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,57 +1348,57 @@ static int replace_constant_operands(sccp_ctx *ctx) {
13481348
return removed_ops;
13491349
}
13501350

1351-
static void sccp_context_init(sccp_ctx *ctx,
1351+
static void sccp_context_init(zend_optimizer_ctx *ctx, sccp_ctx *sccp,
13521352
zend_ssa *ssa, zend_op_array *op_array, zend_call_info **call_map) {
13531353
int i;
1354-
ctx->call_map = call_map;
1355-
ctx->values = emalloc(sizeof(zval) * ssa->vars_count);
1354+
sccp->call_map = call_map;
1355+
sccp->values = zend_arena_alloc(&ctx->arena, sizeof(zval) * ssa->vars_count);
13561356

1357-
MAKE_TOP(&ctx->top);
1358-
MAKE_BOT(&ctx->bot);
1357+
MAKE_TOP(&sccp->top);
1358+
MAKE_BOT(&sccp->bot);
13591359

13601360
i = 0;
13611361
for (; i < op_array->last_var; ++i) {
13621362
/* These are all undefined variables, which we have to mark BOT.
13631363
* Otherwise the undefined variable warning might not be preserved. */
1364-
MAKE_BOT(&ctx->values[i]);
1364+
MAKE_BOT(&sccp->values[i]);
13651365
}
13661366
for (; i < ssa->vars_count; ++i) {
13671367
if (ssa->vars[i].alias) {
1368-
MAKE_BOT(&ctx->values[i]);
1368+
MAKE_BOT(&sccp->values[i]);
13691369
} else {
1370-
MAKE_TOP(&ctx->values[i]);
1370+
MAKE_TOP(&sccp->values[i]);
13711371
}
13721372
}
13731373
}
13741374

1375-
static void sccp_context_free(sccp_ctx *ctx) {
1375+
static void sccp_context_free(sccp_ctx *sccp) {
13761376
int i;
1377-
for (i = ctx->scdf.op_array->last_var; i < ctx->scdf.ssa->vars_count; ++i) {
1378-
zval_ptr_dtor_nogc(&ctx->values[i]);
1377+
for (i = sccp->scdf.op_array->last_var; i < sccp->scdf.ssa->vars_count; ++i) {
1378+
zval_ptr_dtor_nogc(&sccp->values[i]);
13791379
}
1380-
efree(ctx->values);
13811380
}
13821381

1383-
int sccp_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
1382+
int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map)
13841383
{
1385-
sccp_ctx ctx;
1384+
sccp_ctx sccp;
13861385
int removed_ops = 0;
1386+
void *checkpoint = zend_arena_checkpoint(ctx->arena);
13871387

1388-
sccp_context_init(&ctx, ssa, op_array, call_map);
1388+
sccp_context_init(ctx, &sccp, ssa, op_array, call_map);
13891389

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;
1390+
sccp.scdf.handlers.visit_instr = sccp_visit_instr;
1391+
sccp.scdf.handlers.visit_phi = sccp_visit_phi;
1392+
sccp.scdf.handlers.mark_feasible_successors = sccp_mark_feasible_successors;
13931393

1394-
scdf_init(&ctx.scdf, op_array, ssa);
1395-
scdf_solve(&ctx.scdf, "SCCP");
1394+
scdf_init(ctx, &sccp.scdf, op_array, ssa);
1395+
scdf_solve(&sccp.scdf, "SCCP");
13961396

1397-
removed_ops += scdf_remove_unreachable_blocks(&ctx.scdf);
1398-
removed_ops += replace_constant_operands(&ctx);
1397+
removed_ops += scdf_remove_unreachable_blocks(&sccp.scdf);
1398+
removed_ops += replace_constant_operands(&sccp);
13991399

1400-
sccp_context_free(&ctx);
1401-
scdf_free(&ctx.scdf);
1400+
sccp_context_free(&sccp);
1401+
zend_arena_release(&ctx->arena, checkpoint);
14021402

14031403
return removed_ops;
14041404
}

ext/opcache/Optimizer/scdf.c

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -52,140 +52,136 @@
5252
#define DEBUG_PRINT(...)
5353
#endif
5454

55-
void scdf_mark_edge_feasible(scdf_ctx *ctx, int from, int to) {
56-
uint32_t edge = scdf_edge(&ctx->ssa->cfg, from, to);
55+
void scdf_mark_edge_feasible(scdf_ctx *scdf, int from, int to) {
56+
uint32_t edge = scdf_edge(&scdf->ssa->cfg, from, to);
5757

58-
if (zend_bitset_in(ctx->feasible_edges, edge)) {
58+
if (zend_bitset_in(scdf->feasible_edges, edge)) {
5959
/* We already handled this edge */
6060
return;
6161
}
6262

6363
DEBUG_PRINT("Marking edge %d->%d feasible\n", from, to);
64-
zend_bitset_incl(ctx->feasible_edges, edge);
64+
zend_bitset_incl(scdf->feasible_edges, edge);
6565

66-
if (!zend_bitset_in(ctx->executable_blocks, to)) {
67-
if (!zend_bitset_in(ctx->block_worklist, to)) {
66+
if (!zend_bitset_in(scdf->executable_blocks, to)) {
67+
if (!zend_bitset_in(scdf->block_worklist, to)) {
6868
DEBUG_PRINT("Adding block %d to worklist\n", to);
6969
}
70-
zend_bitset_incl(ctx->block_worklist, to);
70+
zend_bitset_incl(scdf->block_worklist, to);
7171
} else {
7272
/* Block is already executable, only a new edge became feasible.
7373
* Reevaluate phi nodes to account for changed source operands. */
74-
zend_ssa_block *ssa_block = &ctx->ssa->blocks[to];
74+
zend_ssa_block *ssa_block = &scdf->ssa->blocks[to];
7575
zend_ssa_phi *phi;
7676
for (phi = ssa_block->phis; phi; phi = phi->next) {
77-
zend_bitset_excl(ctx->phi_var_worklist, phi->ssa_var);
78-
ctx->handlers.visit_phi(ctx, phi);
77+
zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var);
78+
scdf->handlers.visit_phi(scdf, phi);
7979
}
8080
}
8181
}
8282

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

8787
for (b = 0; b < ssa->cfg.blocks_count; b++) {
8888
edges_count += ssa->cfg.blocks[b].predecessors_count;
8989
}
9090

91-
ctx->op_array = op_array;
92-
ctx->ssa = ssa;
91+
scdf->op_array = op_array;
92+
scdf->ssa = ssa;
9393

94-
ctx->instr_worklist_len = zend_bitset_len(op_array->last);
95-
ctx->phi_var_worklist_len = zend_bitset_len(ssa->vars_count);
96-
ctx->block_worklist_len = zend_bitset_len(ssa->cfg.blocks_count);
94+
scdf->instr_worklist_len = zend_bitset_len(op_array->last);
95+
scdf->phi_var_worklist_len = zend_bitset_len(ssa->vars_count);
96+
scdf->block_worklist_len = zend_bitset_len(ssa->cfg.blocks_count);
9797

98-
ctx->instr_worklist = ecalloc(
99-
ctx->instr_worklist_len + ctx->phi_var_worklist_len + 2 * ctx->block_worklist_len + zend_bitset_len(edges_count),
98+
scdf->instr_worklist = zend_arena_calloc(&ctx->arena,
99+
scdf->instr_worklist_len + scdf->phi_var_worklist_len + 2 * scdf->block_worklist_len + zend_bitset_len(edges_count),
100100
sizeof(zend_ulong));
101101

102-
ctx->phi_var_worklist = ctx->instr_worklist + ctx->instr_worklist_len;
103-
ctx->block_worklist = ctx->phi_var_worklist + ctx->phi_var_worklist_len;
104-
ctx->executable_blocks = ctx->block_worklist + ctx->block_worklist_len;
105-
ctx->feasible_edges = ctx->executable_blocks + ctx->block_worklist_len;
102+
scdf->phi_var_worklist = scdf->instr_worklist + scdf->instr_worklist_len;
103+
scdf->block_worklist = scdf->phi_var_worklist + scdf->phi_var_worklist_len;
104+
scdf->executable_blocks = scdf->block_worklist + scdf->block_worklist_len;
105+
scdf->feasible_edges = scdf->executable_blocks + scdf->block_worklist_len;
106106

107-
zend_bitset_incl(ctx->block_worklist, 0);
108-
zend_bitset_incl(ctx->executable_blocks, 0);
107+
zend_bitset_incl(scdf->block_worklist, 0);
108+
zend_bitset_incl(scdf->executable_blocks, 0);
109109
}
110110

111-
void scdf_free(scdf_ctx *ctx) {
112-
efree(ctx->instr_worklist);
113-
}
114-
115-
void scdf_solve(scdf_ctx *ctx, const char *name) {
116-
zend_ssa *ssa = ctx->ssa;
111+
void scdf_solve(scdf_ctx *scdf, const char *name) {
112+
zend_ssa *ssa = scdf->ssa;
117113
DEBUG_PRINT("Start SCDF solve (%s)\n", name);
118-
while (!zend_bitset_empty(ctx->instr_worklist, ctx->instr_worklist_len)
119-
|| !zend_bitset_empty(ctx->phi_var_worklist, ctx->phi_var_worklist_len)
120-
|| !zend_bitset_empty(ctx->block_worklist, ctx->block_worklist_len)
114+
while (!zend_bitset_empty(scdf->instr_worklist, scdf->instr_worklist_len)
115+
|| !zend_bitset_empty(scdf->phi_var_worklist, scdf->phi_var_worklist_len)
116+
|| !zend_bitset_empty(scdf->block_worklist, scdf->block_worklist_len)
121117
) {
122118
int i;
123-
while ((i = zend_bitset_pop_first(ctx->phi_var_worklist, ctx->phi_var_worklist_len)) >= 0) {
119+
while ((i = zend_bitset_pop_first(scdf->phi_var_worklist, scdf->phi_var_worklist_len)) >= 0) {
124120
zend_ssa_phi *phi = ssa->vars[i].definition_phi;
125121
ZEND_ASSERT(phi);
126-
if (zend_bitset_in(ctx->executable_blocks, phi->block)) {
127-
ctx->handlers.visit_phi(ctx, phi);
122+
if (zend_bitset_in(scdf->executable_blocks, phi->block)) {
123+
scdf->handlers.visit_phi(scdf, phi);
128124
}
129125
}
130126

131-
while ((i = zend_bitset_pop_first(ctx->instr_worklist, ctx->instr_worklist_len)) >= 0) {
127+
while ((i = zend_bitset_pop_first(scdf->instr_worklist, scdf->instr_worklist_len)) >= 0) {
132128
int block_num = ssa->cfg.map[i];
133-
if (zend_bitset_in(ctx->executable_blocks, block_num)) {
129+
if (zend_bitset_in(scdf->executable_blocks, block_num)) {
134130
zend_basic_block *block = &ssa->cfg.blocks[block_num];
135-
zend_op *opline = &ctx->op_array->opcodes[i];
131+
zend_op *opline = &scdf->op_array->opcodes[i];
136132
zend_ssa_op *ssa_op = &ssa->ops[i];
137133
if (opline->opcode == ZEND_OP_DATA) {
138134
opline--;
139135
ssa_op--;
140136
}
141-
ctx->handlers.visit_instr(ctx, opline, ssa_op);
137+
scdf->handlers.visit_instr(scdf, opline, ssa_op);
142138
if (i == block->start + block->len - 1) {
143139
if (block->successors_count == 1) {
144-
scdf_mark_edge_feasible(ctx, block_num, block->successors[0]);
140+
scdf_mark_edge_feasible(scdf, block_num, block->successors[0]);
145141
} else if (block->successors_count > 1) {
146-
ctx->handlers.mark_feasible_successors(ctx, block_num, block, opline, ssa_op);
142+
scdf->handlers.mark_feasible_successors(scdf, block_num, block, opline, ssa_op);
147143
}
148144
}
149145
}
150146
}
151147

152-
while ((i = zend_bitset_pop_first(ctx->block_worklist, ctx->block_worklist_len)) >= 0) {
148+
while ((i = zend_bitset_pop_first(scdf->block_worklist, scdf->block_worklist_len)) >= 0) {
153149
/* This block is now live. Interpret phis and instructions in it. */
154150
zend_basic_block *block = &ssa->cfg.blocks[i];
155151
zend_ssa_block *ssa_block = &ssa->blocks[i];
156152

157153
DEBUG_PRINT("Pop block %d from worklist\n", i);
158-
zend_bitset_incl(ctx->executable_blocks, i);
154+
zend_bitset_incl(scdf->executable_blocks, i);
159155

160156
{
161157
zend_ssa_phi *phi;
162158
for (phi = ssa_block->phis; phi; phi = phi->next) {
163-
zend_bitset_excl(ctx->phi_var_worklist, phi->ssa_var);
164-
ctx->handlers.visit_phi(ctx, phi);
159+
zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var);
160+
scdf->handlers.visit_phi(scdf, phi);
165161
}
166162
}
167163

168164
if (block->len == 0) {
169165
/* Zero length blocks don't have a last instruction that would normally do this */
170-
scdf_mark_edge_feasible(ctx, i, block->successors[0]);
166+
scdf_mark_edge_feasible(scdf, i, block->successors[0]);
171167
} else {
172168
zend_op *opline;
173169
int j, end = block->start + block->len;
174170
for (j = block->start; j < end; j++) {
175-
opline = &ctx->op_array->opcodes[j];
176-
zend_bitset_excl(ctx->instr_worklist, j);
171+
opline = &scdf->op_array->opcodes[j];
172+
zend_bitset_excl(scdf->instr_worklist, j);
177173
if (opline->opcode != ZEND_OP_DATA) {
178-
ctx->handlers.visit_instr(ctx, opline, &ssa->ops[j]);
174+
scdf->handlers.visit_instr(scdf, opline, &ssa->ops[j]);
179175
}
180176
}
181177
if (block->successors_count == 1) {
182-
scdf_mark_edge_feasible(ctx, i, block->successors[0]);
178+
scdf_mark_edge_feasible(scdf, i, block->successors[0]);
183179
} else if (block->successors_count > 1) {
184180
if (opline->opcode == ZEND_OP_DATA) {
185181
opline--;
186182
j--;
187183
}
188-
ctx->handlers.mark_feasible_successors(ctx, i, block, opline, &ssa->ops[j-1]);
184+
scdf->handlers.mark_feasible_successors(scdf, i, block, opline, &ssa->ops[j-1]);
189185
}
190186
}
191187
}

ext/opcache/Optimizer/scdf.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,8 @@ typedef struct _scdf_ctx {
4646
} handlers;
4747
} scdf_ctx;
4848

49-
void scdf_init(scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa);
49+
void scdf_init(zend_optimizer_ctx *ctx, scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa);
5050
void scdf_solve(scdf_ctx *scdf, const char *name);
51-
void scdf_free(scdf_ctx *scdf);
5251

5352
int scdf_remove_unreachable_blocks(scdf_ctx *scdf);
5453

@@ -95,6 +94,6 @@ static inline zend_bool scdf_is_edge_feasible(scdf_ctx *scdf, int from, int to)
9594
return zend_bitset_in(scdf->feasible_edges, edge);
9695
}
9796

98-
void scdf_mark_edge_feasible(scdf_ctx *ctx, int from, int to);
97+
void scdf_mark_edge_feasible(scdf_ctx *scdf, int from, int to);
9998

10099
#endif

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-
int sccp_optimize_op_array(zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
113+
int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
114114

115115
#endif

0 commit comments

Comments
 (0)