Calculate the dominators of each node in the flow graph.

The dominators are represented by sets using the node numbers.
This commit is contained in:
Bill Currie 2012-10-30 20:12:44 +09:00
parent 964ea7f9fe
commit 1fead50f4e
4 changed files with 43 additions and 0 deletions

View file

@ -45,6 +45,7 @@ int flow_is_return (struct statement_s *s);
struct sblock_s *flow_get_target (struct statement_s *s);
void flow_build_vars (struct function_s *func);
void flow_build_graph (struct function_s *func);
void flow_calc_dominators (struct function_s *func);
//@}

View file

@ -81,6 +81,7 @@ typedef struct sblock_s {
int number; ///< number of this block in flow graph
statement_t *statements;
statement_t **tail;
struct set_s *dom; ///< set of nodes that dominate this node
} sblock_t;
struct expr_s;

View file

@ -44,6 +44,7 @@
#include "dags.h"
#include "flow.h"
#include "function.h"
#include "set.h"
#include "statements.h"
#include "symtab.h"
@ -226,3 +227,42 @@ flow_build_graph (function_t *func)
}
}
}
void
flow_calc_dominators (function_t *func)
{
set_t *work;
sblock_t **pred;
int i;
int changed;
if (!func->num_nodes)
return;
// First, create a base set for the initial state of the non-initial nodes
work = set_new ();
for (i = 0; i < func->num_nodes; i++)
set_add (work, i);
func->graph[0]->dom = set_new ();
set_add (func->graph[0]->dom, 0);
// initialize dom for the non-initial nodes
for (i = 1; i < func->num_nodes; i++) {
func->graph[i]->dom = set_new ();
set_assign (func->graph[i]->dom, work);
}
do {
changed = 0;
for (i = 1; i < func->num_nodes; i++) {
set_assign (work, func->graph[i]->pred[0]->dom);
for (pred = func->graph[i]->pred + 1; *pred; pred++)
set_intersection (work, (*pred)->dom);
set_add (work, i);
if (!set_is_equivalent (work, func->graph[i]->dom))
changed = 1;
set_assign (func->graph[i]->dom, work);
}
} while (changed);
}

View file

@ -645,6 +645,7 @@ emit_function (function_t *f, expr_t *e)
f->sblock = make_statements (e);
flow_build_vars (f);
flow_build_graph (f);
flow_calc_dominators (f);
if (options.block_dot.flow)
print_flow (f->sblock, nva ("%s.%s.%s.dot", GETSTR (pr.source_file),
f->name, "flow"));