- allocating helper data on an additional obstack that can be easily freed
[r17370]
return e1->irg != e2->irg;
}
return e1->irg != e2->irg;
}
-/** compare two ir graphs */
+/** compare two ir graphs for pointer identity */
static int graph_cmp(const void *elt, const void *key) {
const ir_graph *e1 = elt;
const ir_graph *e2 = key;
static int graph_cmp(const void *elt, const void *key) {
const ir_graph *e1 = elt;
const ir_graph *e2 = key;
static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
int i, n_callees;
static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
int i, n_callees;
- if (cg_irg_visited(irg)) return;
+ if (cg_irg_visited(irg))
+ return;
mark_cg_irg_visited(irg);
if (pre)
mark_cg_irg_visited(irg);
if (pre)
void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
int i, n_irgs = get_irp_n_irgs();
void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
int i, n_irgs = get_irp_n_irgs();
do_walk(get_irp_main_irg(), pre, post, env);
for (i = 0; i < n_irgs; i++) {
do_walk(get_irp_main_irg(), pre, post, env);
for (i = 0; i < n_irgs; i++) {
- * allocates a new scc_info of the obstack
+ * allocates a new scc_info on the obstack
-static INLINE scc_info *new_scc_info(void) {
- scc_info *info = obstack_alloc(outermost_ir_graph->obst, sizeof(*info));
+static INLINE scc_info *new_scc_info(struct obstack *obst) {
+ scc_info *info = obstack_alloc(obst, sizeof(*info));
memset(info, 0, sizeof(*info));
return info;
}
memset(info, 0, sizeof(*info));
return info;
}
/**
* Returns non-zero if a graph was already visited.
*/
/**
* Returns non-zero if a graph was already visited.
*/
-static INLINE int
-cg_irg_visited(ir_graph *irg) {
+static INLINE int cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
return info->visited >= master_cg_visited;
}
/**
* Marks a graph as visited.
*/
return info->visited >= master_cg_visited;
}
/**
* Marks a graph as visited.
*/
-static INLINE void
-mark_cg_irg_visited(ir_graph *irg) {
+static INLINE void mark_cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
info->visited = master_cg_visited;
}
/**
* Set a graphs visited flag to i.
*/
info->visited = master_cg_visited;
}
/**
* Set a graphs visited flag to i.
*/
-static INLINE void
-set_cg_irg_visited(ir_graph *irg, int i) {
+static INLINE void set_cg_irg_visited(ir_graph *irg, int i) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
info->visited = i;
}
/**
* Returns the visited flag of a graph.
*/
info->visited = i;
}
/**
* Returns the visited flag of a graph.
*/
-static INLINE int
-get_cg_irg_visited(ir_graph *irg) {
+static INLINE int get_cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE void
-mark_irg_in_stack(ir_graph *irg) {
+static INLINE void mark_irg_in_stack(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE void
-mark_irg_not_in_stack(ir_graph *irg) {
+static INLINE void mark_irg_not_in_stack(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE int
-irg_is_in_stack(ir_graph *irg) {
+static INLINE int irg_is_in_stack(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE void
-set_irg_uplink(ir_graph *irg, int uplink) {
+static INLINE void set_irg_uplink(ir_graph *irg, int uplink) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE int
-get_irg_uplink(ir_graph *irg) {
+static INLINE int get_irg_uplink(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE void
-set_irg_dfn(ir_graph *irg, int dfn) {
+static INLINE void set_irg_dfn(ir_graph *irg, int dfn) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
-static INLINE int
-get_irg_dfn(ir_graph *irg) {
+static INLINE int get_irg_dfn(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
scc_info *info = get_irg_link(irg);
- assert(info && "missing call to init_scc");
+ assert(info && "missing call to init_scc()");
ir_loop *last_son = lelement.son;
if (get_kind(last_son) == k_ir_loop &&
ir_loop *last_son = lelement.son;
if (get_kind(last_son) == k_ir_loop &&
- get_loop_n_elements(last_son) == 1) {
- ir_loop *gson;
+ get_loop_n_elements(last_son) == 1) {
+ ir_loop *gson;
- lelement = get_loop_element(last_son, 0);
- gson = lelement.son;
- if(get_kind(gson) == k_ir_loop) {
- loop_element new_last_son;
+ lelement = get_loop_element(last_son, 0);
+ gson = lelement.son;
+ if (get_kind(gson) == k_ir_loop) {
+ loop_element new_last_son;
- gson -> outer_loop = l;
- new_last_son.son = gson;
- l -> children[last] = new_last_son;
- }
+ gson->outer_loop = l;
+ new_last_son.son = gson;
+ l->children[last] = new_last_son;
+ }
* to the new loop and returns the father.
*/
static ir_loop *new_loop(void) {
* to the new loop and returns the father.
*/
static ir_loop *new_loop(void) {
- ir_loop *father, *son;
-
- father = current_loop;
-
- son = obstack_alloc(outermost_ir_graph->obst, sizeof(*son));
- memset(son, 0, sizeof(*son));
- son->kind = k_ir_loop;
- son->children = NEW_ARR_F(loop_element, 0);
- son->n_nodes = 0;
- son->n_sons = 0;
- son->link = NULL;
- if (father) {
- son->outer_loop = father;
- add_loop_son(father, son);
- son->depth = father->depth + 1;
- } else { /* The root loop */
- son->outer_loop = son;
- son->depth = 0;
- }
-
-#ifdef DEBUG_libfirm
- son->loop_nr = get_irp_new_node_nr();
-#endif
+ ir_loop *father = current_loop;
+ ir_loop *son = alloc_loop(father, outermost_ir_graph->obst);
current_loop = son;
return father;
}
current_loop = son;
return father;
}
/**********************************************************************/
/* Constructing and destructing the loop/backedge information. **/
/**********************************************************************/
/* Initialization steps. **********************************************/
/**********************************************************************/
/* Constructing and destructing the loop/backedge information. **/
/**********************************************************************/
/* Initialization steps. **********************************************/
-static void
-init_scc(void) {
+static void init_scc(struct obstack *obst) {
n_irgs = get_irp_n_irgs();
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
n_irgs = get_irp_n_irgs();
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
- set_irg_link(irg, new_scc_info());
+ set_irg_link(irg, new_scc_info(obst));
irg->callgraph_recursion_depth = 0;
irg->callgraph_loop_depth = 0;
}
irg->callgraph_recursion_depth = 0;
irg->callgraph_loop_depth = 0;
}
*
* @param root: only needed for assertion.
*/
*
* @param root: only needed for assertion.
*/
-static int
-is_head(ir_graph *n, ir_graph *root)
-{
+static int is_head(ir_graph *n, ir_graph *root) {
int i, arity;
int some_outof_loop = 0, some_in_loop = 0;
int i, arity;
int some_outof_loop = 0, some_in_loop = 0;
* within the loop.
* @arg root: only needed for assertion.
*/
* within the loop.
* @arg root: only needed for assertion.
*/
-static int
-is_endless_head(ir_graph *n, ir_graph *root)
+static int is_endless_head(ir_graph *n, ir_graph *root)
{
int i, arity;
int some_outof_loop = 0, some_in_loop = 0;
{
int i, arity;
int some_outof_loop = 0, some_in_loop = 0;
return !some_outof_loop & some_in_loop;
}
return !some_outof_loop & some_in_loop;
}
* Check whether there is a parallel edge in the ip control flow.
* Only
*/
* Check whether there is a parallel edge in the ip control flow.
* Only
*/
-static int
-is_ip_head(ir_graph *n, ir_graph *pred)
+static int is_ip_head(ir_graph *n, ir_graph *pred)
* Returns index of the predecessor with the smallest dfn number
* greater-equal than limit.
*/
* Returns index of the predecessor with the smallest dfn number
* greater-equal than limit.
*/
-static int
-smallest_dfn_pred(ir_graph *n, int limit)
+static int smallest_dfn_pred(ir_graph *n, int limit)
{
int i, index = -2, min = -1;
{
int i, index = -2, min = -1;
}
/** Returns index of the predecessor with the largest dfn number. */
}
/** Returns index of the predecessor with the largest dfn number. */
-static int
-largest_dfn_pred(ir_graph *n)
-{
+static int largest_dfn_pred(ir_graph *n) {
int i, index = -2, max = -1;
int arity = get_irg_n_callees(n);
int i, index = -2, max = -1;
int arity = get_irg_n_callees(n);
}
#ifndef INTERPROCEDURAL_VIEW
}
#ifndef INTERPROCEDURAL_VIEW
-static ir_graph *
-find_tail(ir_graph *n) {
+static ir_graph *find_tail(ir_graph *n) {
ir_graph *m;
int i, res_index = -2;
ir_graph *m;
int i, res_index = -2;
}
/* We should not walk past our selves on the stack: The upcoming nodes
}
/* We should not walk past our selves on the stack: The upcoming nodes
- are not in this loop. We assume a loop not reachable from Start. */
+ are not in this loop. We assume a loop not reachable from Start. */
if (m == n) {
i = -1;
break;
if (m == n) {
i = -1;
break;
return get_irg_callee(m, res_index);
}
#else
return get_irg_callee(m, res_index);
}
#else
-static ir_graph *
-find_tail(ir_graph *n) {
+static ir_graph *find_tail(ir_graph *n) {
ir_graph *m;
int i, res_index = -2;
ir_graph *m;
int i, res_index = -2;
ir_graph *irg = get_irp_irg(i);
if (irg->caller_isbe)
ir_graph *irg = get_irp_irg(i);
if (irg->caller_isbe)
- free(irg->caller_isbe);
+ xfree(irg->caller_isbe);
irg->caller_isbe = NULL;
if (irg->callee_isbe)
irg->caller_isbe = NULL;
if (irg->callee_isbe)
- free(irg->callee_isbe);
+ xfree(irg->callee_isbe);
irg->callee_isbe = NULL;
}
}
irg->callee_isbe = NULL;
}
}
int i, n_callees;
int pushed = 0;
int i, n_callees;
int pushed = 0;
- if (cg_irg_visited(irg)) return;
+ if (cg_irg_visited(irg))
+ return;
mark_cg_irg_visited(irg);
/* -- compute and set the new nesting value -- */
mark_cg_irg_visited(irg);
/* -- compute and set the new nesting value -- */
int n_callees;
(void) env;
int n_callees;
(void) env;
- if (cg_irg_visited(irg)) return;
+ if (cg_irg_visited(irg))
+ return;
/* We need the values of all predecessors (except backedges).
So they must be marked. Else we will reach the node through
/* We need the values of all predecessors (except backedges).
So they must be marked. Else we will reach the node through
n_callers = get_irg_n_callers(irg);
for (i = 0; i < n_callers; ++i) {
ir_graph *m = get_irg_caller(irg, i);
n_callers = get_irg_n_callers(irg);
for (i = 0; i < n_callers; ++i) {
ir_graph *m = get_irg_caller(irg, i);
- if (is_irg_caller_backedge(irg, i)) continue;
+ if (is_irg_caller_backedge(irg, i))
+ continue;
if (!cg_irg_visited(m)) {
return;
}
if (!cg_irg_visited(m)) {
return;
}
/* Compute the backedges that represent recursions. */
void find_callgraph_recursions(void) {
int i, n_irgs = get_irp_n_irgs();
/* Compute the backedges that represent recursions. */
void find_callgraph_recursions(void) {
int i, n_irgs = get_irp_n_irgs();
reachable from the outermost graph, but call themselves in a cycle. */
assert(get_irp_main_irg());
outermost_ir_graph = get_irp_main_irg();
reachable from the outermost graph, but call themselves in a cycle. */
assert(get_irp_main_irg());
outermost_ir_graph = get_irp_main_irg();
+ obstack_init(&temp);
+ init_scc(&temp);
current_loop = NULL;
new_loop(); /* sets current_loop */
current_loop = NULL;
new_loop(); /* sets current_loop */
cgscc(outermost_ir_graph);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
cgscc(outermost_ir_graph);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if (!cg_irg_visited(irg))
cgscc(irg);
}
if (!cg_irg_visited(irg))
cgscc(irg);
}
+ obstack_free(&temp, NULL);
+
irp->outermost_cg_loop = current_loop;
irp->outermost_cg_loop = current_loop;
+ mature_loops(current_loop, outermost_ir_graph->obst);
/* -- Reverse the backedge information. -- */
for (i = 0; i < n_irgs; ++i) {
/* -- Reverse the backedge information. -- */
for (i = 0; i < n_irgs; ++i) {