Skip to content

Commit c88ffa9

Browse files
committed
Added e-SSA based DFA optimisation framework (incomplete)
1 parent 8d6d28d commit c88ffa9

21 files changed

+7083
-186
lines changed

ext/opcache/Optimizer/block_pass.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1745,13 +1745,13 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
17451745

17461746
/* Build CFG */
17471747
checkpoint = zend_arena_checkpoint(ctx->arena);
1748-
if (zend_build_cfg(&ctx->arena, op_array, 0, 0, &cfg, NULL) != SUCCESS) {
1748+
if (zend_build_cfg(&ctx->arena, op_array, 0, &cfg, NULL) != SUCCESS) {
17491749
zend_arena_release(&ctx->arena, checkpoint);
17501750
return;
17511751
}
17521752

17531753
if (ctx->debug_level & ZEND_DUMP_BEFORE_BLOCK_PASS) {
1754-
zend_dump_op_array(op_array, &cfg, ZEND_DUMP_UNREACHABLE, "before block pass");
1754+
zend_dump_op_array(op_array, ZEND_DUMP_CFG, "before block pass", &cfg);
17551755
}
17561756

17571757
if (op_array->last_var || op_array->T) {
@@ -1805,7 +1805,7 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
18051805
assemble_code_blocks(&cfg, op_array);
18061806

18071807
if (ctx->debug_level & ZEND_DUMP_AFTER_BLOCK_PASS) {
1808-
zend_dump_op_array(op_array, &cfg, 0, "after block pass");
1808+
zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNREACHABLE, "after block pass", &cfg);
18091809
}
18101810

18111811
/* Destroy CFG */

ext/opcache/Optimizer/dfa_pass.c

+49-19
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "zend_bitset.h"
2727
#include "zend_cfg.h"
2828
#include "zend_ssa.h"
29+
#include "zend_func_info.h"
30+
#include "zend_inference.h"
2931
#include "zend_dump.h"
3032

3133
#ifndef HAVE_DFA_PASS
@@ -35,18 +37,19 @@
3537
void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
3638
{
3739
void *checkpoint;
38-
uint32_t flags;
39-
zend_cfg cfg;
40+
uint32_t build_flags;
41+
uint32_t flags = 0;
4042
zend_ssa ssa;
4143

4244
#if !HAVE_DFA_PASS
4345
return;
4446
#endif
4547

4648
/* Build SSA */
49+
memset(&ssa, 0, sizeof(ssa));
4750
checkpoint = zend_arena_checkpoint(ctx->arena);
4851

49-
if (zend_build_cfg(&ctx->arena, op_array, 0, 0, &cfg, &flags) != SUCCESS) {
52+
if (zend_build_cfg(&ctx->arena, op_array, 0, &ssa.cfg, &flags) != SUCCESS) {
5053
zend_arena_release(&ctx->arena, checkpoint);
5154
return;
5255
}
@@ -56,52 +59,79 @@ void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
5659
return;
5760
}
5861

59-
if (zend_cfg_build_predecessors(&ctx->arena, &cfg) != SUCCESS) {
62+
if (zend_cfg_build_predecessors(&ctx->arena, &ssa.cfg) != SUCCESS) {
6063
zend_arena_release(&ctx->arena, checkpoint);
6164
return;
6265
}
6366

6467
if (ctx->debug_level & ZEND_DUMP_DFA_CFG) {
65-
zend_dump_op_array(op_array, &cfg, 0, "dfa cfg");
68+
zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNUSED_VARS, "dfa cfg", &ssa.cfg);
6669
}
6770

6871
/* Compute Dominators Tree */
69-
if (zend_cfg_compute_dominators_tree(op_array, &cfg) != SUCCESS) {
72+
if (zend_cfg_compute_dominators_tree(op_array, &ssa.cfg) != SUCCESS) {
7073
zend_arena_release(&ctx->arena, checkpoint);
7174
return;
7275
}
7376

7477
/* Identify reducible and irreducible loops */
75-
if (zend_cfg_identify_loops(op_array, &cfg, &flags) != SUCCESS) {
78+
if (zend_cfg_identify_loops(op_array, &ssa.cfg, &flags) != SUCCESS) {
7679
zend_arena_release(&ctx->arena, checkpoint);
7780
return;
7881
}
7982

8083
if (ctx->debug_level & ZEND_DUMP_DFA_DOMINATORS) {
81-
int j;
84+
zend_dump_dominators(op_array, &ssa.cfg);
85+
}
8286

83-
fprintf(stderr, "DOMINATORS-TREE:\n");
84-
for (j = 0; j < cfg.blocks_count; j++) {
85-
zend_basic_block *b = cfg.blocks + j;
86-
if (b->flags & ZEND_BB_REACHABLE) {
87-
zend_dump_block_info(&cfg, j, 0);
88-
}
89-
}
87+
build_flags = 0;
88+
if (ctx->debug_level & ZEND_DUMP_DFA_LIVENESS) {
89+
build_flags |= ZEND_SSA_DEBUG_LIVENESS;
90+
}
91+
if (ctx->debug_level & ZEND_DUMP_DFA_PHI) {
92+
build_flags |= ZEND_SSA_DEBUG_PHI_PLACEMENT;
93+
}
94+
if (zend_build_ssa(&ctx->arena, op_array, build_flags, &ssa, &flags) != SUCCESS) {
95+
zend_arena_release(&ctx->arena, checkpoint);
96+
return;
9097
}
9198

92-
if (zend_build_ssa(&ctx->arena, op_array, &cfg, 0, &ssa, &flags) != SUCCESS) {
99+
if (ctx->debug_level & ZEND_DUMP_DFA_SSA) {
100+
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", &ssa);
101+
}
102+
103+
104+
if (zend_ssa_compute_use_def_chains(&ctx->arena, op_array, &ssa) != SUCCESS){
93105
zend_arena_release(&ctx->arena, checkpoint);
94106
return;
95107
}
96108

109+
if (zend_ssa_find_false_dependencies(op_array, &ssa) != SUCCESS) {
110+
zend_arena_release(&ctx->arena, checkpoint);
111+
return;
112+
}
113+
114+
if (zend_ssa_find_sccs(op_array, &ssa) != SUCCESS){
115+
zend_arena_release(&ctx->arena, checkpoint);
116+
return;
117+
}
118+
119+
if (zend_ssa_inference(&ctx->arena, op_array, ctx->script, &ssa) != SUCCESS) {
120+
return;
121+
}
122+
123+
if (ctx->debug_level & ZEND_DUMP_DFA_SSA_VARS) {
124+
zend_dump_ssa_variables(op_array, &ssa);
125+
}
126+
97127
if (ctx->debug_level & ZEND_DUMP_BEFORE_DFA_PASS) {
98-
zend_dump_op_array(op_array, &cfg, ZEND_DUMP_UNREACHABLE, "before dfa pass");
128+
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", &ssa);
99129
}
100130

101-
//TODO: ???
131+
//TODO: Add optimization???
102132

103133
if (ctx->debug_level & ZEND_DUMP_AFTER_DFA_PASS) {
104-
zend_dump_op_array(op_array, &cfg, 0, "after dfa pass");
134+
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "after dfa pass", &ssa);
105135
}
106136

107137
/* Destroy SSA */

0 commit comments

Comments
 (0)