X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fcallgraph.c;h=3e4df7158d3df08292c63dfb38f426158c3f1047;hb=220d7f081a34a73b9bd480151bd4ff2723043d2c;hp=d6f879f29f986f729e89c16973b74ba3ef69b37c;hpb=f8cc15664f571aa7ef89d6f6bc8d5bd2b8ca7d53;p=libfirm diff --git a/ir/ana/callgraph.c b/ir/ana/callgraph.c index d6f879f29..3e4df7158 100644 --- a/ir/ana/callgraph.c +++ b/ir/ana/callgraph.c @@ -48,33 +48,28 @@ 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); -/** Returns the callgraph state of the program representation. */ irp_callgraph_state get_irp_callgraph_state(void) { return irp->callgraph_state; } -/* Sets the callgraph state of the program representation. */ void set_irp_callgraph_state(irp_callgraph_state s) { irp->callgraph_state = s; } -/* Returns the number of procedures that call the given irg. */ size_t get_irg_n_callers(const ir_graph *irg) { assert(irg->callers); return irg->callers ? ARR_LEN(irg->callers) : 0; } -/* Returns the caller at position pos. */ ir_graph *get_irg_caller(const ir_graph *irg, size_t pos) { assert(pos < get_irg_n_callers(irg)); return irg->callers ? irg->callers[pos] : NULL; } -/* Returns non-zero if the caller at position pos is "a backedge", i.e. a recursion. */ int is_irg_caller_backedge(const ir_graph *irg, size_t pos) { assert(pos < get_irg_n_callers(irg)); @@ -97,7 +92,6 @@ static void set_irg_caller_backedge(ir_graph *irg, const ir_graph *caller) } } -/* Returns non-zero if the irg has a backedge caller. */ int has_irg_caller_backedge(const ir_graph *irg) { size_t i, n_callers = get_irg_n_callers(irg); @@ -131,7 +125,6 @@ static size_t reverse_pos(const ir_graph *callee, size_t pos_caller) return 0; } -/* Returns the maximal loop depth of call nodes that call along this edge. */ size_t get_irg_caller_loop_depth(const ir_graph *irg, size_t pos) { ir_graph *caller = get_irg_caller(irg, pos); @@ -140,29 +133,24 @@ size_t get_irg_caller_loop_depth(const ir_graph *irg, size_t pos) return get_irg_callee_loop_depth(caller, pos_callee); } - -/* Returns the number of procedures that are called by the given irg. */ size_t get_irg_n_callees(const ir_graph *irg) { assert(irg->callees); return irg->callees ? ARR_LEN(irg->callees) : 0; } -/* Returns the callee at position pos. */ ir_graph *get_irg_callee(const ir_graph *irg, size_t pos) { assert(pos < get_irg_n_callees(irg)); return irg->callees ? irg->callees[pos]->irg : NULL; } -/* Returns non-zero if the callee at position pos is "a backedge", i.e. a recursion. */ int is_irg_callee_backedge(const ir_graph *irg, size_t pos) { assert(pos < get_irg_n_callees(irg)); return irg->callee_isbe != NULL ? rbitset_is_set(irg->callee_isbe, pos) : 0; } -/* Returns non-zero if the irg has a backedge callee. */ int has_irg_callee_backedge(const ir_graph *irg) { size_t i, n_callees = get_irg_n_callees(irg); @@ -189,7 +177,6 @@ static void set_irg_callee_backedge(ir_graph *irg, size_t pos) rbitset_set(irg->callee_isbe, pos); } -/* Returns the maximal loop depth of call nodes that call along this edge. */ size_t get_irg_callee_loop_depth(const ir_graph *irg, size_t pos) { assert(pos < get_irg_n_callees(irg)); @@ -197,8 +184,6 @@ size_t get_irg_callee_loop_depth(const ir_graph *irg, size_t pos) } -/* --------------------- Compute the callgraph ------------------------ */ - /** * Pre-Walker called by compute_callgraph(), analyses all Call nodes. */ @@ -223,19 +208,19 @@ static void ana_Call(ir_node *n, void *env) buf.irg = callee; - pset_insert((pset *)callee->callers, irg, HASH_PTR(irg)); - found = (cg_callee_entry*) pset_find((pset *)irg->callees, &buf, HASH_PTR(callee)); + pset_insert((pset *)callee->callers, irg, hash_ptr(irg)); + found = (cg_callee_entry*) pset_find((pset *)irg->callees, &buf, hash_ptr(callee)); if (found) { /* add Call node to list, compute new nesting. */ ir_node **arr = found->call_list; ARR_APP1(ir_node *, arr, n); found->call_list = arr; } else { /* New node, add Call node and init nesting. */ - found = OALLOC(irg->obst, cg_callee_entry); + found = OALLOC(get_irg_obstack(irg), cg_callee_entry); found->irg = callee; found->call_list = NEW_ARR_F(ir_node *, 1); found->call_list[0] = n; found->max_depth = 0; - pset_insert((pset *)irg->callees, found, HASH_PTR(callee)); + pset_insert((pset *)irg->callees, found, hash_ptr(callee)); } depth = get_loop_depth(get_irn_loop(get_nodes_block(n))); found->max_depth = (depth > found->max_depth) ? depth : found->max_depth; @@ -259,8 +244,6 @@ static int graph_cmp(const void *elt, const void *key) return e1 != e2; } - -/* Construct and destruct the callgraph. */ void compute_callgraph(void) { size_t i, n_irgs; @@ -287,38 +270,34 @@ void compute_callgraph(void) /* Change the sets to arrays. */ for (i = 0; i < n_irgs; ++i) { size_t j, count; - cg_callee_entry *callee; - ir_graph *c, *irg = get_irp_irg(i); + ir_graph *irg = get_irp_irg(i); pset *callee_set, *caller_set; callee_set = (pset *)irg->callees; count = pset_count(callee_set); irg->callees = NEW_ARR_F(cg_callee_entry *, count); irg->callee_isbe = NULL; - callee = (cg_callee_entry*) pset_first(callee_set); - for (j = 0; j < count; ++j) { - irg->callees[j] = callee; - callee = (cg_callee_entry*) pset_next(callee_set); + j = 0; + foreach_pset(callee_set, cg_callee_entry, callee) { + irg->callees[j++] = callee; } del_pset(callee_set); - assert(callee == NULL); + assert(j == count); caller_set = (pset *)irg->callers; count = pset_count(caller_set); irg->callers = NEW_ARR_F(ir_graph *, count); irg->caller_isbe = NULL; - c = (ir_graph*) pset_first(caller_set); - for (j = 0; j < count; ++j) { - irg->callers[j] = c; - c = (ir_graph*) pset_next(caller_set); + j = 0; + foreach_pset(caller_set, ir_graph, c) { + irg->callers[j++] = c; } del_pset(caller_set); - assert(c == NULL); + assert(j == count); } set_irp_callgraph_state(irp_callgraph_consistent); } -/* Destruct the callgraph. */ void free_callgraph(void) { size_t i, n_irgs = get_irp_n_irgs(); @@ -336,10 +315,6 @@ void free_callgraph(void) set_irp_callgraph_state(irp_callgraph_none); } -/* ----------------------------------------------------------------------------------- */ -/* A walker for the callgraph */ -/* ----------------------------------------------------------------------------------- */ - static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func *post, void *env) { @@ -382,10 +357,6 @@ void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *e } } -/* ----------------------------------------------------------------------------------- */ -/* loop construction algorithm */ -/* ----------------------------------------------------------------------------------- */ - static ir_graph *outermost_ir_graph; /**< The outermost graph the scc is computed for */ static ir_loop *current_loop; /**< Current cfloop construction is working @@ -396,10 +367,6 @@ static size_t loop_node_cnt = 0; /**< Counts the number of allocated cfloop no static size_t current_dfn = 1; /**< Counter to generate depth first numbering of visited nodes. */ -/*-----------------*/ -/* Node attributes */ -/*-----------------*/ - typedef struct scc_info { size_t dfn; /**< Depth first search number. */ size_t uplink; /**< dfn number of ancestor. */ @@ -496,10 +463,6 @@ static inline size_t get_irg_dfn(const ir_graph *irg) return info->dfn; } -/**********************************************************************/ -/* A stack. **/ -/**********************************************************************/ - static ir_graph **stack = NULL; static size_t tos = 0; /**< top of stack */ @@ -601,10 +564,6 @@ static inline void pop_scc_unmark_visit(ir_graph *n) } } -/**********************************************************************/ -/* The loop data structure. **/ -/**********************************************************************/ - /** * Allocates a new loop as son of current_loop. Sets current_loop * to the new loop and returns the father. @@ -612,19 +571,13 @@ static inline void pop_scc_unmark_visit(ir_graph *n) static ir_loop *new_loop(void) { ir_loop *father = current_loop; - ir_loop *son = alloc_loop(father, outermost_ir_graph->obst); + ir_loop *son = alloc_loop(father, get_irg_obstack(outermost_ir_graph)); current_loop = son; return father; } -/**********************************************************************/ -/* Constructing and destructing the loop/backedge information. **/ -/**********************************************************************/ - -/* Initialization steps. **********************************************/ - static void init_scc(struct obstack *obst) { size_t i, n_irgs; @@ -807,11 +760,6 @@ static ir_graph *find_tail(const ir_graph *n) return get_irg_callee(m, res_index); } -/*-----------------------------------------------------------* - * The core algorithm. * - *-----------------------------------------------------------*/ - - static void cgscc(ir_graph *n) { size_t i, n_callees; @@ -904,11 +852,6 @@ static void reset_isbe(void) } } -/* ----------------------------------------------------------------------------------- */ -/* The recursion stuff driver. */ -/* ----------------------------------------------------------------------------------- */ - -/* Compute the backedges that represent recursions. */ void find_callgraph_recursions(void) { size_t i, n_irgs; @@ -946,7 +889,7 @@ void find_callgraph_recursions(void) obstack_free(&temp, NULL); irp->outermost_cg_loop = current_loop; - mature_loops(current_loop, outermost_ir_graph->obst); + mature_loops(current_loop, get_irg_obstack(outermost_ir_graph)); /* -- Reverse the backedge information. -- */ for (i = 0; i < n_irgs; ++i) { @@ -961,8 +904,6 @@ void find_callgraph_recursions(void) irp->callgraph_state = irp_callgraph_and_calltree_consistent; } -/* Returns the maximal loop depth of all paths from an external visible method to - this irg. */ size_t get_irg_loop_depth(const ir_graph *irg) { assert(irp->callgraph_state == irp_callgraph_consistent || @@ -970,15 +911,12 @@ size_t get_irg_loop_depth(const ir_graph *irg) return irg->callgraph_loop_depth; } -/* Returns the maximal recursion depth of all paths from an external visible method to - this irg. */ size_t get_irg_recursion_depth(const ir_graph *irg) { assert(irp->callgraph_state == irp_callgraph_and_calltree_consistent); return irg->callgraph_recursion_depth; } -/* Computes the interprocedural loop nesting information. */ void analyse_loop_nesting_depth(void) { /* establish preconditions. */