mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +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);
|
struct sblock_s *flow_get_target (struct statement_s *s);
|
||||||
void flow_build_vars (struct function_s *func);
|
void flow_build_vars (struct function_s *func);
|
||||||
void flow_build_graph (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
|
int number; ///< number of this block in flow graph
|
||||||
statement_t *statements;
|
statement_t *statements;
|
||||||
statement_t **tail;
|
statement_t **tail;
|
||||||
|
struct set_s *dom; ///< set of nodes that dominate this node
|
||||||
} sblock_t;
|
} sblock_t;
|
||||||
|
|
||||||
struct expr_s;
|
struct expr_s;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "dags.h"
|
#include "dags.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "set.h"
|
||||||
#include "statements.h"
|
#include "statements.h"
|
||||||
#include "symtab.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);
|
f->sblock = make_statements (e);
|
||||||
flow_build_vars (f);
|
flow_build_vars (f);
|
||||||
flow_build_graph (f);
|
flow_build_graph (f);
|
||||||
|
flow_calc_dominators (f);
|
||||||
if (options.block_dot.flow)
|
if (options.block_dot.flow)
|
||||||
print_flow (f->sblock, nva ("%s.%s.%s.dot", GETSTR (pr.source_file),
|
print_flow (f->sblock, nva ("%s.%s.%s.dot", GETSTR (pr.source_file),
|
||||||
f->name, "flow"));
|
f->name, "flow"));
|
||||||
|
|
Loading…
Reference in a new issue