mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
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:
parent
964ea7f9fe
commit
1fead50f4e
4 changed files with 43 additions and 0 deletions
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in a new issue