Reputation: 11
My problem is probably misunderstanding of dominance frontier algorithm.
I am implementing SSA form according to this paper: https://c9x.me/compile/bib/ssa.pdf
It seems my algorithm for computing dominance frontier is correct and matches with pseudo-code in paper (Figure 2. Calculation of DF), however, it gives weird results.
Paper says:
The dominator tree of CFG has exactly the same set of nodes as CFG but has a very different set of edges. The words predecessor, successor, path always refer to CFG here. The words parent, child, ancestor, descendant always refer to the dominator tree.
So I hope I applied control flow successors and dominator tree children in proper places. Below is my logic, where I cannot see any troubles. df is dominance frontier, idom is immediate dominator.
/* Bottom-up tree traversal. */
static void traverse_cfg_post_order(ir_vector_t *out, struct ir_node *ir)
{
vector_foreach(ir->idom_back, i) {
struct ir_node *x = vector_at(ir->idom_back, i);
if (x)
traverse_cfg_post_order(out, x);
}
vector_push_back(*out, ir);
}
static void dominance_frontier(struct ir_node *ir)
{
ir_vector_t post_order = {0};
traverse_cfg_post_order(&post_order, ir);
vector_foreach(post_order, i) {
struct ir_node *x = vector_at(post_order, i);
vector_free(x->df);
struct ir_node *succs[2] = {0};
control_flow_successors(x, &succs[0], &succs[1]);
for (uint64_t j = 0; j < 2; ++j) {
struct ir_node *y = succs[j];
if (y && y->idom != x)
vector_push_back(x->df, y);
}
vector_foreach(x->idom_back, j) {
struct ir_node *z = vector_at(x->idom_back, j);
vector_foreach(z->df, k) {
struct ir_node *y = vector_at(z->df, k);
if (y && y->idom != x)
vector_push_back(x->df, y);
}
}
}
vector_free(post_order);
}
My assumptions:
Below is dominator tree with calculated dominance frontier (DF). For some reason it always takes one conditional branch and evidently dominance frontier is incorrect.
Upvotes: 1
Views: 137