X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fcallgraph.c;h=a4df9f3fa137ac2cc2adefa86f64f901e0211a12;hb=5ea9d0c93d64963b085ff10cde05f739e1c2606b;hp=5e980679d4dd3ae0a5478e2a88edbdb15dca96f6;hpb=3631cbbff48a2c1622d829ac1c1199bdaf18a669;p=libfirm diff --git a/ir/ana/callgraph.c b/ir/ana/callgraph.c index 5e980679d..a4df9f3fa 100644 --- a/ir/ana/callgraph.c +++ b/ir/ana/callgraph.c @@ -10,14 +10,15 @@ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif #ifdef HAVE_STRING_H -#include +# include #endif - +# ifdef HAVE_STDLIB_H #include +#endif #include "callgraph.h" @@ -31,6 +32,7 @@ #include "array.h" #include "pmap.h" +#include "hashptr.h" #include "irgwalk.h" @@ -145,7 +147,7 @@ int get_irg_callee_loop_depth(ir_graph *irg, int pos) { -double get_irg_callee_execution_freqency(ir_graph *irg, int pos) { +double get_irg_callee_execution_frequency(ir_graph *irg, int pos) { ir_node **arr = ((ana_entry *)irg->callees[pos])->call_list; int i, n_Calls = ARR_LEN(arr); double freq = 0; @@ -156,27 +158,24 @@ double get_irg_callee_execution_freqency(ir_graph *irg, int pos) { return freq; } -double get_irg_callee_method_execution_freqency(ir_graph *irg, int pos) { - double call_freq = get_irg_callee_execution_freqency(irg, pos); +double get_irg_callee_method_execution_frequency(ir_graph *irg, int pos) { + double call_freq = get_irg_callee_execution_frequency(irg, pos); double meth_freq = get_irg_method_execution_frequency(irg); return call_freq * meth_freq; } -double get_irg_caller_method_execution_freqency(ir_graph *irg, int pos) { +double get_irg_caller_method_execution_frequency(ir_graph *irg, int pos) { ir_graph *caller = get_irg_caller(irg, pos); int pos_callee = reverse_pos(irg, pos); - return get_irg_callee_method_execution_freqency(caller, pos_callee); + return get_irg_callee_method_execution_frequency(caller, pos_callee); } /* --------------------- Compute the callgraph ------------------------ */ -/* Hash an address */ -#define HASH_ADDRESS(adr) (((unsigned)(adr)) >> 3) - /** * Walker called by compute_callgraph() */ @@ -197,8 +196,8 @@ static void ana_Call(ir_node *n, void *env) { ana_entry *found; int depth; - pset_insert((pset *)callee->callers, irg, (unsigned)irg >> 3); - found = pset_find((pset *)irg->callees, &buf, HASH_ADDRESS(callee)); + pset_insert((pset *)callee->callers, irg, HASH_PTR(irg)); + found = 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); @@ -209,7 +208,7 @@ static void ana_Call(ir_node *n, void *env) { 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_ADDRESS(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; @@ -361,7 +360,7 @@ static int current_dfn = 1; /**< Counter to generate depth first numberin /**********************************************************************/ typedef struct scc_info { - bool in_stack; /**< Marks whether node is on the stack. */ + int in_stack; /**< Marks whether node is on the stack. */ int dfn; /**< Depth first search number. */ int uplink; /**< dfn number of ancestor. */ int visited; @@ -404,17 +403,17 @@ static INLINE void mark_irg_in_stack (ir_graph *n) { scc_info *info = get_irg_link(n); assert(info); - info->in_stack = true; + info->in_stack = 1; } static INLINE void mark_irg_not_in_stack (ir_graph *n) { scc_info *info = get_irg_link(n); assert(info); - info->in_stack = false; + info->in_stack = 0; } -static INLINE bool +static INLINE int irg_is_in_stack (ir_graph *n) { scc_info *info = get_irg_link(n); assert(info); @@ -616,12 +615,12 @@ init_scc (void) { } } -/** Returns true if n is a loop header, i.e., it is a Block node +/** Returns non-zero if n is a loop header, i.e., it is a Block node * and has predecessors within the cfloop and out of the cfloop. * * @param root: only needed for assertion. */ -static bool +static int is_head (ir_graph *n, ir_graph *root) { int i, arity; @@ -646,12 +645,12 @@ is_head (ir_graph *n, ir_graph *root) } /** - * Returns true if n is possible loop head of an endless loop. + * Returns non-zero if n is possible loop head of an endless loop. * I.e., it is a Block, Phi or Filter node and has only predecessors * within the loop. * @arg root: only needed for assertion. */ -static bool +static int is_endless_head (ir_graph *n, ir_graph *root) { int i, arity; @@ -681,12 +680,12 @@ is_endless_head (ir_graph *n, ir_graph *root) * Check whether there is a parallel edge in the ip control flow. * Only */ -static bool +static int is_ip_head (ir_graph *n, ir_graph *pred) { int is_be = 0; int iv_rem = get_interprocedural_view(); - set_interprocedural_view(true); + set_interprocedural_view(1); { ir_node *sblock = get_irg_start_block(n); int i, arity = get_Block_n_cfgpreds(sblock); @@ -703,7 +702,7 @@ is_ip_head (ir_graph *n, ir_graph *pred) //printf(" "); DDMG(ip_pred); if ((ip_pred == pred) && is_backedge(sblock, i)) { //printf(" found\n"); - is_be = 1; + is_be = 1; } } } @@ -1118,8 +1117,8 @@ static void compute_rec_depth (ir_graph *irg, void *env) { /* ----------------------------------------------------------------------------------- */ -/* Another algorithm to compute recursion nesting depth */ -/* Walk the callgraph. Ignore backedges. Use sum of execution freqencies of Call */ +/* Another algorithm to compute the execution frequency of methods ignoring recursions. */ +/* Walk the callgraph. Ignore backedges. Use sum of execution frequencies of Call */ /* nodes to evaluate a callgraph edge. */ /* ----------------------------------------------------------------------------------- */ @@ -1129,15 +1128,23 @@ double get_irg_method_execution_frequency (ir_graph *irg) { void set_irg_method_execution_frequency (ir_graph *irg, double freq) { irg->method_execution_frequency = freq; + + if (irp->max_method_execution_frequency < freq) + irp->max_method_execution_frequency = freq; } static void compute_method_execution_frequency (ir_graph *irg, void *env) { + int i, n_callers; + double freq; + int found_edge; + int n_callees; + 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 one of the unmarked ones. */ - int i, n_callers = get_irg_n_callers(irg); + 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; @@ -1147,15 +1154,16 @@ static void compute_method_execution_frequency (ir_graph *irg, void *env) { } mark_cg_irg_visited(irg); - /* Compute the new freqency. */ - double freq = 0; - int found_edge = 0; + /* Compute the new frequency. */ + freq = 0; + found_edge = 0; for (i = 0; i < n_callers; i++) { - if (is_irg_caller_backedge(irg, i)) continue; - double edge_freq = get_irg_caller_method_execution_freqency(irg, i); - assert(edge_freq >= 0); - freq += edge_freq; - found_edge = 1; + if (! is_irg_caller_backedge(irg, i)) { + double edge_freq = get_irg_caller_method_execution_frequency(irg, i); + assert(edge_freq >= 0); + freq += edge_freq; + found_edge = 1; + } } if (!found_edge) { @@ -1167,7 +1175,7 @@ static void compute_method_execution_frequency (ir_graph *irg, void *env) { set_irg_method_execution_frequency(irg, freq); /* recur */ - int n_callees = get_irg_n_callees(irg); + n_callees = get_irg_n_callees(irg); for (i = 0; i < n_callees; i++) { compute_method_execution_frequency (get_irg_callee(irg, i), NULL); } @@ -1280,10 +1288,6 @@ void compute_performance_estimates(void) { DEL_ARR_F(e.loop_stack); - //dump_callgraph("-with_nesting"); - //dump_callgraph_loop_tree(current_loop, "-after_cons"); - - /* -- compute the execution frequency -- */ irp->max_method_execution_frequency = 0; master_cg_visited += 2; @@ -1335,4 +1339,18 @@ void analyse_loop_nesting_depth(void) { find_callgraph_recursions(); compute_performance_estimates(); + + set_irp_loop_nesting_depth_state(loop_nesting_depth_consistent); +} + + +loop_nesting_depth_state get_irp_loop_nesting_depth_state(void) { + return irp->lnd_state; +} +void set_irp_loop_nesting_depth_state(loop_nesting_depth_state s) { + irp->lnd_state = s; +} +void set_irp_loop_nesting_depth_state_inconsistent(void) { + if (irp->lnd_state == loop_nesting_depth_consistent) + irp->lnd_state = loop_nesting_depth_inconsistent; }