Add irn_visited_else_mark(), which combines irn_visited() and mark_irn_visited().
[libfirm] / ir / ana / callgraph.c
index f9098c6..dac267e 100644 (file)
 
 #include "irgwalk.h"
 
-static int master_cg_visited = 0;
-static INLINE int  cg_irg_visited     (ir_graph *n);
+static ir_visited_t master_cg_visited = 0;
+static INLINE int cg_irg_visited      (ir_graph *n);
 static INLINE void mark_cg_irg_visited(ir_graph *n);
-static INLINE void set_cg_irg_visited (ir_graph *n, int i);
+static INLINE void set_cg_irg_visited (ir_graph *n, ir_visited_t i);
 
 /** Returns the callgraph state of the program representation. */
 irp_callgraph_state get_irp_callgraph_state(void) {
@@ -390,16 +390,18 @@ void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *e
        int i, n_irgs = get_irp_n_irgs();
        ++master_cg_visited;
 
-       do_walk(get_irp_main_irg(), pre, post, env);
-       for (i = 0; i < n_irgs; i++) {
+       /* roots are methods which have no callers in the current program */
+       for (i = 0; i < n_irgs; ++i) {
                ir_graph *irg = get_irp_irg(i);
-               if (!cg_irg_visited(irg) && get_irg_n_callers(irg) == 0)
+
+               if (get_irg_n_callers(irg) == 0)
                        do_walk(irg, pre, post, env);
        }
+
+       /* in case of unreachable call loops we haven't visited some irgs yet */
        for (i = 0; i < n_irgs; i++) {
                ir_graph *irg = get_irp_irg(i);
-               if (!cg_irg_visited(irg))
-                       do_walk(irg, pre, post, env);
+               do_walk(irg, pre, post, env);
        }
 }
 
@@ -441,36 +443,28 @@ static INLINE scc_info *new_scc_info(struct obstack *obst) {
  * Returns non-zero if a graph was already visited.
  */
 static INLINE int cg_irg_visited(ir_graph *irg) {
-       scc_info *info = get_irg_link(irg);
-       assert(info && "missing call to init_scc()");
-       return info->visited >= master_cg_visited;
+       return irg->self_visited >= master_cg_visited;
 }
 
 /**
  * Marks a graph as visited.
  */
 static INLINE void mark_cg_irg_visited(ir_graph *irg) {
-       scc_info *info = get_irg_link(irg);
-       assert(info && "missing call to init_scc()");
-       info->visited = master_cg_visited;
+       irg->self_visited = master_cg_visited;
 }
 
 /**
  * Set a graphs visited flag to i.
  */
-static INLINE void set_cg_irg_visited(ir_graph *irg, int i) {
-       scc_info *info = get_irg_link(irg);
-       assert(info && "missing call to init_scc()");
-       info->visited = i;
+static INLINE void set_cg_irg_visited(ir_graph *irg, ir_visited_t i) {
+       irg->self_visited = i;
 }
 
 /**
  * Returns the visited flag of a graph.
  */
-static INLINE int get_cg_irg_visited(ir_graph *irg) {
-       scc_info *info = get_irg_link(irg);
-       assert(info && "missing call to init_scc()");
-       return info->visited;
+static INLINE ir_visited_t get_cg_irg_visited(ir_graph *irg) {
+       return irg->self_visited;
 }
 
 static INLINE void mark_irg_in_stack(ir_graph *irg) {
@@ -1015,7 +1009,7 @@ static void reset_isbe(void) {
 static void compute_loop_depth(ir_graph *irg, void *env) {
        int current_nesting = *(int *) env;
        int old_nesting = irg->callgraph_loop_depth;
-       int old_visited = get_cg_irg_visited(irg);
+       ir_visited_t old_visited = get_cg_irg_visited(irg);
        int i, n_callees;
 
        //return ;