3 * File name: ir/ana/callgraph.c
4 * Purpose: Representation and computation of the callgraph.
5 * Author: Goetz Lindenmaier
9 * Copyright: (c) 2004 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
22 #include "callgraph.h"
26 #include "irgraph_t.h"
36 /* For callees, we want to remember the Call nodes, too. */
43 typedef struct ana_entry ana_entry;
45 static int master_cg_visited = 0;
46 static INLINE int cg_irg_visited (ir_graph *n);
47 static INLINE void mark_cg_irg_visited(ir_graph *n);
48 static INLINE void set_cg_irg_visited (ir_graph *n, int i);
50 irp_callgraph_state get_irp_callgraph_state(void) {
51 return irp->callgraph_state;
53 void set_irp_callgraph_state(irp_callgraph_state s) {
54 irp->callgraph_state = s;
57 /* The functions that call irg. */
58 int get_irg_n_callers(ir_graph *irg) {
59 if (irg->callers) return ARR_LEN(irg->callers);
62 ir_graph *get_irg_caller(ir_graph *irg, int pos) {
63 assert (pos >= 0 && pos < get_irg_n_callers(irg));
64 if (irg->callers) return irg->callers[pos];
67 int is_irg_caller_backedge(ir_graph *irg, int pos) {
68 assert (pos >= 0 && pos < get_irg_n_callers(irg));
69 return irg->caller_isbe[pos];
72 static void set_irg_caller_backedge(ir_graph *irg, ir_graph *caller) {
73 int i, n_callers = get_irg_n_callers(irg);
74 for (i = 0; i < n_callers; ++i) {
75 if (get_irg_caller(irg, i) == caller) {
76 irg->caller_isbe[i] = 1;
82 int has_irg_caller_backedge(ir_graph *irg) {
83 int i, n_callers = get_irg_n_callers(irg);
84 for (i = 0; i < n_callers; ++i)
85 if (is_irg_caller_backedge(irg, i)) return 1;
89 int get_irg_caller_loop_depth(ir_graph *irg, int pos) {
90 ir_graph *caller = get_irg_caller(irg, pos);
92 /* search the other relation for the corresponding edge. */
94 int i, n_callees = get_irg_n_callees(caller);
95 for (i = 0; i < n_callees; ++i) {
96 if (get_irg_callee(caller, i) == irg) {
102 assert(pos_callee >= 0);
104 return get_irg_callee_loop_depth(caller, pos_callee);
108 /* The functions called by irg. */
109 int get_irg_n_callees(ir_graph *irg) {
110 if (irg->callees) return ARR_LEN(irg->callees);
113 ir_graph *get_irg_callee(ir_graph *irg, int pos) {
114 assert (pos >= 0 && pos < get_irg_n_callees(irg));
115 if (irg->callees) return ((ana_entry *)irg->callees[pos])->irg;
118 int is_irg_callee_backedge(ir_graph *irg, int pos) {
119 assert (pos >= 0 && pos < get_irg_n_callees(irg));
120 return irg->callee_isbe[pos];
122 int has_irg_callee_backedge(ir_graph *irg) {
123 int i, n_callees = get_irg_n_callees(irg);
124 for (i = 0; i < n_callees; ++i)
125 if (is_irg_callee_backedge(irg, i)) return 1;
128 void set_irg_callee_backedge(ir_graph *irg, int pos) {
129 assert (pos >= 0 && pos < get_irg_n_callees(irg));
130 irg->callee_isbe[pos] = 1;
133 int get_irg_callee_loop_depth(ir_graph *irg, int pos) {
134 assert (pos >= 0 && pos < get_irg_n_callees(irg));
135 if (irg->callees) return ((ana_entry *)irg->callees[pos])->max_depth;
139 /* --------------------- Compute the callgraph ------------------------ */
141 /* Hash an address */
142 #define HASH_ADDRESS(adr) (((unsigned)(adr)) >> 3)
145 * Walker called by compute_callgraph()
147 static void ana_Call(ir_node *n, void *env) {
151 if (get_irn_op(n) != op_Call) return;
153 irg = get_irn_irg(n);
154 n_callees = get_Call_n_callees(n);
155 for (i = 0; i < n_callees; ++i) {
156 entity *callee_e = get_Call_callee(n, i);
157 ir_graph *callee = get_entity_irg(callee_e);
158 if (callee) { /* For unknown caller */
159 ana_entry buf = { callee, NULL, 0};
163 pset_insert((pset *)callee->callers, irg, (unsigned)irg >> 3);
164 found = pset_find((pset *)irg->callees, &buf, HASH_ADDRESS(callee));
165 if (found) { /* add Call node to list, compute new nesting. */
166 } else { /* New node, add Call node and init nesting. */
167 found = (ana_entry *) obstack_alloc (irg->obst, sizeof (ana_entry));
169 found->call_list = NULL;
170 found->max_depth = 0;
171 pset_insert((pset *)irg->callees, found, HASH_ADDRESS(callee));
173 depth = get_loop_depth(get_irn_loop(get_nodes_block(n)));
174 found->max_depth = (depth > found->max_depth) ? depth : found->max_depth;
179 /** compare two ir graphs in a ana_entry */
180 static int ana_entry_cmp(const void *elt, const void *key) {
181 const ana_entry *e1 = elt;
182 const ana_entry *e2 = key;
183 return e1->irg != e2->irg;
186 /** compare two ir graphs */
187 static int graph_cmp(const void *elt, const void *key) {
192 /* Construct and destruct the callgraph. */
193 void compute_callgraph(void) {
194 int i, n_irgs = get_irp_n_irgs();
196 assert(! get_interprocedural_view()); /* Else walking will not reach the Call nodes. */
200 for (i = 0; i < n_irgs; ++i) {
201 ir_graph *irg = get_irp_irg(i);
202 assert(get_irg_callee_info_state(irg) == irg_callee_info_consistent);
203 irg->callees = (ir_graph **)new_pset(ana_entry_cmp, 8);
204 irg->callers = (ir_graph **)new_pset(graph_cmp, 8);
205 construct_cf_backedges(irg);
208 /* Compute the call graph */
209 for (i = 0; i < n_irgs; ++i) {
210 ir_graph *irg = get_irp_irg(i);
211 construct_cf_backedges(irg);
212 irg_walk_graph(irg, ana_Call, NULL, NULL);
215 /* Change the sets to arrays. */
216 for (i = 0; i < n_irgs; ++i) {
218 ir_graph *c, *irg = get_irp_irg(i);
219 pset *callee_set, *caller_set;
221 callee_set = (pset *)irg->callees;
222 count = pset_count(callee_set);
223 irg->callees = NEW_ARR_F(ir_graph *, count);
224 irg->callee_isbe = calloc(count, sizeof(int));
225 c = pset_first(callee_set);
226 for (j = 0; j < count; ++j) {
228 c = pset_next(callee_set);
230 del_pset(callee_set);
233 caller_set = (pset *)irg->callers;
234 count = pset_count(caller_set);
235 irg->callers = NEW_ARR_F(ir_graph *, count);
236 irg->caller_isbe = calloc(count, sizeof(int));
237 c = pset_first(caller_set);
238 for (j = 0; j < count; ++j) {
240 c = pset_next(caller_set);
242 del_pset(caller_set);
245 set_irp_callgraph_state(irp_callgraph_consistent);
248 void free_callgraph(void) {
249 int i, n_irgs = get_irp_n_irgs();
250 for (i = 0; i < n_irgs; ++i) {
251 ir_graph *irg = get_irp_irg(i);
252 if (irg->callees) DEL_ARR_F(irg->callees);
253 if (irg->callers) DEL_ARR_F(irg->callers);
254 if (irg->callee_isbe) free(irg->callee_isbe);
255 if (irg->caller_isbe) free(irg->caller_isbe);
258 irg->callee_isbe = NULL;
259 irg->caller_isbe = NULL;
261 set_irp_callgraph_state(irp_callgraph_none);
264 /* ----------------------------------------------------------------------------------- */
265 /* A walker for the callgraph */
266 /* ----------------------------------------------------------------------------------- */
269 static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
272 if (cg_irg_visited(irg)) return;
273 mark_cg_irg_visited(irg);
277 n_callees = get_irg_n_callees(irg);
278 for (i = 0; i < n_callees; i++) {
279 ir_graph *m = get_irg_callee(irg, i);
280 do_walk(m, pre, post, env);
286 void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
287 int i, n_irgs = get_irp_n_irgs();
290 do_walk(get_irp_main_irg(), pre, post, env);
291 for (i = 0; i < n_irgs; i++) {
292 ir_graph *irg = get_irp_irg(i);
293 if (!cg_irg_visited(irg) && get_irg_n_callers(irg) == 0)
294 do_walk(irg, pre, post, env);
296 for (i = 0; i < n_irgs; i++) {
297 ir_graph *irg = get_irp_irg(i);
298 if (!cg_irg_visited(irg))
299 do_walk(irg, pre, post, env);
303 /* ----------------------------------------------------------------------------------- */
304 /* loop construction algorithm */
305 /* ----------------------------------------------------------------------------------- */
307 static ir_graph *outermost_ir_graph; /* The outermost graph the scc is computed
309 static ir_loop *current_loop; /* Current cfloop construction is working
311 static int loop_node_cnt = 0; /* Counts the number of allocated cfloop nodes.
312 Each cfloop node gets a unique number.
313 What for? ev. remove. @@@ */
314 static int current_dfn = 1; /* Counter to generate depth first numbering
318 /**********************************************************************/
319 /* Node attributes **/
320 /**********************************************************************/
322 typedef struct scc_info {
323 bool in_stack; /* Marks whether node is on the stack. */
324 int dfn; /* Depth first search number. */
325 int uplink; /* dfn number of ancestor. */
329 static INLINE scc_info* new_scc_info(void) {
330 scc_info *info = obstack_alloc (outermost_ir_graph->obst, sizeof (scc_info));
331 memset (info, 0, sizeof (scc_info));
336 cg_irg_visited(ir_graph *n) {
337 return (((scc_info *)n->link)->visited >= master_cg_visited);
341 mark_cg_irg_visited(ir_graph *n) {
342 ((scc_info *)n->link)->visited = master_cg_visited;
346 set_cg_irg_visited(ir_graph *n, int i) {
347 ((scc_info *)n->link)->visited = i;
351 get_cg_irg_visited(ir_graph *n) {
352 return ((scc_info *)n->link)->visited;
356 mark_irg_in_stack (ir_graph *n) {
357 assert(get_irg_link(n));
358 ((scc_info *)n->link)->in_stack = true;
362 mark_irg_not_in_stack (ir_graph *n) {
363 assert(get_irg_link(n));
364 ((scc_info *)n->link)->in_stack = false;
368 irg_is_in_stack (ir_graph *n) {
369 assert(get_irg_link(n));
370 return ((scc_info *)n->link)->in_stack;
374 set_irg_uplink (ir_graph *n, int uplink) {
375 assert(get_irg_link(n));
376 ((scc_info *)n->link)->uplink = uplink;
380 get_irg_uplink (ir_graph *n) {
381 assert(get_irg_link(n));
382 return ((scc_info *)n->link)->uplink;
386 set_irg_dfn (ir_graph *n, int dfn) {
387 assert(get_irg_link(n));
388 ((scc_info *)n->link)->dfn = dfn;
392 get_irg_dfn (ir_graph *n) {
393 assert(get_irg_link(n));
394 return ((scc_info *)n->link)->dfn;
397 /**********************************************************************/
399 /**********************************************************************/
401 static ir_graph **stack = NULL;
402 static int tos = 0; /* top of stack */
404 static INLINE void init_stack(void) {
406 ARR_RESIZE (ir_graph *, stack, 1000);
408 stack = NEW_ARR_F (ir_graph *, 1000);
417 if (tos == ARR_LEN (stack)) {
418 int nlen = ARR_LEN (stack) * 2;
419 ARR_RESIZE (ir_node *, stack, nlen);
422 mark_irg_in_stack(n);
425 static INLINE ir_graph *
428 ir_graph *n = stack[--tos];
429 mark_irg_not_in_stack(n);
433 /* The nodes up to n belong to the current loop.
434 Removes them from the stack and adds them to the current loop. */
436 pop_scc_to_loop (ir_graph *n)
443 set_irg_dfn(m, loop_node_cnt);
444 add_loop_node(current_loop, (ir_node *)m);
446 //m->callgraph_loop_depth = current_loop->depth;
450 /* GL ??? my last son is my grandson??? Removes cfloops with no
451 ir_nodes in them. Such loops have only another loop as son. (Why
452 can't they have two loops as sons? Does it never get that far? ) */
453 static void close_loop (ir_loop *l)
455 int last = get_loop_n_elements(l) - 1;
456 loop_element lelement = get_loop_element(l, last);
457 ir_loop *last_son = lelement.son;
459 if (get_kind(last_son) == k_ir_loop &&
460 get_loop_n_elements(last_son) == 1) {
463 lelement = get_loop_element(last_son, 0);
465 if(get_kind(gson) == k_ir_loop) {
466 loop_element new_last_son;
468 gson -> outer_loop = l;
469 new_last_son.son = gson;
470 l -> children[last] = new_last_son;
477 /* Removes and unmarks all nodes up to n from the stack.
478 The nodes must be visited once more to assign them to a scc. */
480 pop_scc_unmark_visit (ir_graph *n)
486 set_cg_irg_visited(m, 0);
490 /**********************************************************************/
491 /* The loop datastructure. **/
492 /**********************************************************************/
494 /* Allocates a new loop as son of current_loop. Sets current_loop
495 to the new loop and returns the father. */
496 static ir_loop *new_loop (void) {
497 ir_loop *father, *son;
499 father = current_loop;
501 son = (ir_loop *) obstack_alloc (outermost_ir_graph->obst, sizeof (ir_loop));
502 memset (son, 0, sizeof (ir_loop));
503 son->kind = k_ir_loop;
504 son->children = NEW_ARR_F (loop_element, 0);
508 son->outer_loop = father;
509 add_loop_son(father, son);
510 son->depth = father->depth+1;
511 } else { /* The root loop */
512 son->outer_loop = son;
517 son->loop_nr = get_irp_new_node_nr();
525 /**********************************************************************/
526 /* Constructing and destructing the loop/backedge information. **/
527 /**********************************************************************/
529 /* Initialization steps. **********************************************/
537 for (i = 0; i < get_irp_n_irgs(); ++i) {
538 set_irg_link(get_irp_irg(i), new_scc_info());
539 get_irp_irg(i)->callgraph_recursion_depth = 0;
540 get_irp_irg(i)->callgraph_loop_depth = 0;
544 /** Returns true if n is a loop header, i.e., it is a Block node
545 * and has predecessors within the cfloop and out of the cfloop.
547 * @param root: only needed for assertion.
550 is_head (ir_graph *n, ir_graph *root)
553 int some_outof_loop = 0, some_in_loop = 0;
555 arity = get_irg_n_callees(n);
556 for (i = 0; i < arity; i++) {
557 ir_graph *pred = get_irg_callee(n, i);
558 if (is_irg_callee_backedge(n, i)) continue;
559 if (!irg_is_in_stack(pred)) {
562 if (get_irg_uplink(pred) < get_irg_uplink(root)) {
563 DDMG(pred); DDMG(root);
564 assert(get_irg_uplink(pred) >= get_irg_uplink(root));
570 return some_outof_loop && some_in_loop;
572 /* Returns true if n is possible loop head of an endless loop.
573 I.e., it is a Block, Phi or Filter node and has only predecessors
575 @arg root: only needed for assertion. */
577 is_endless_head (ir_graph *n, ir_graph *root)
580 int some_outof_loop = 0, some_in_loop = 0;
582 arity = get_irg_n_callees(n);
583 for (i = 0; i < arity; i++) {
584 ir_graph *pred = get_irg_callee(n, i);
586 if (is_irg_callee_backedge(n, i)) { continue; }
587 if (!irg_is_in_stack(pred)) {
590 if(get_irg_uplink(pred) < get_irg_uplink(root)) {
591 DDMG(pred); DDMG(root);
592 assert(get_irg_uplink(pred) >= get_irg_uplink(root));
598 return !some_outof_loop && some_in_loop;
602 /* Check whether there is a parallel edge in the ip control flow.
605 is_ip_head (ir_graph *n, ir_graph *pred)
608 int iv_rem = get_interprocedural_view();
609 set_interprocedural_view(true);
611 ir_node *sblock = get_irg_start_block(n);
612 int i, arity = get_Block_n_cfgpreds(sblock);
614 //printf(" edge from "); DDMG(n);
615 //printf(" to pred "); DDMG(pred);
616 //printf(" sblock "); DDMN(sblock);
618 for (i = 0; i < arity; i++) {
619 ir_node *pred_cfop = skip_Proj(get_Block_cfgpred(sblock, i));
620 //printf(" "); DDMN(pred_cfop);
621 if (get_irn_op(pred_cfop) == op_CallBegin) { /* could be Unknown */
622 ir_graph *ip_pred = get_irn_irg(pred_cfop);
623 //printf(" "); DDMG(ip_pred);
624 if ((ip_pred == pred) && is_backedge(sblock, i)) {
625 //printf(" found\n");
631 set_interprocedural_view(iv_rem);
635 /* Returns index of the predecessor with the smallest dfn number
636 greater-equal than limit. */
638 smallest_dfn_pred (ir_graph *n, int limit)
640 int i, index = -2, min = -1;
642 int arity = get_irg_n_callees(n);
643 for (i = 0; i < arity; i++) {
644 ir_graph *pred = get_irg_callee(n, i);
645 if (is_irg_callee_backedge(n, i) || !irg_is_in_stack(pred)) continue;
646 if (get_irg_dfn(pred) >= limit && (min == -1 || get_irg_dfn(pred) < min)) {
648 min = get_irg_dfn(pred);
655 /* Returns index of the predecessor with the largest dfn number. */
657 largest_dfn_pred (ir_graph *n)
659 int i, index = -2, max = -1;
661 int arity = get_irg_n_callees(n);
662 for (i = 0; i < arity; i++) {
663 ir_graph *pred = get_irg_callee(n, i);
664 if (is_irg_callee_backedge (n, i) || !irg_is_in_stack(pred)) continue;
665 if (get_irg_dfn(pred) > max) {
667 max = get_irg_dfn(pred);
676 find_tail (ir_graph *n) {
678 int i, res_index = -2;
681 if (!icfg && rm_cyclic_phis && remove_cyclic_phis (n)) return NULL;
683 m = stack[tos-1]; /* tos = top of stack */
684 if (is_head (m, n)) {
685 res_index = smallest_dfn_pred(m, 0);
686 if ((res_index == -2) && /* no smallest dfn pred found. */
690 if (m == n) return NULL; // Is this to catch Phi - self loops?
691 for (i = tos-2; i >= 0; --i) {
694 if (is_head (m, n)) {
695 res_index = smallest_dfn_pred (m, get_irg_dfn(m) + 1);
696 if (res_index == -2) /* no smallest dfn pred found. */
697 res_index = largest_dfn_pred (m);
699 if ((m == n) && (res_index == -2)) {
705 /* We should not walk past our selves on the stack: The upcoming nodes
706 are not in this loop. We assume a loop not reachable from Start. */
715 /* A dead loop not reachable from Start. */
716 for (i = tos-2; i >= 0; --i) {
718 if (is_endless_head (m, n)) {
719 res_index = smallest_dfn_pred (m, get_irg_dfn(m) + 1);
720 if (res_index == -2) /* no smallest dfn pred found. */
721 res_index = largest_dfn_pred (m);
724 if (m == n) { break; } /* It's not an unreachable loop, either. */
726 //assert(0 && "no head found on stack");
730 assert (res_index > -2);
732 set_irg_callee_backedge (m, res_index);
733 return get_irg_callee(m, res_index);
737 find_tail (ir_graph *n) {
739 int i, res_index = -2;
742 ir_graph *in_and_out = NULL;
743 ir_graph *only_in = NULL;
744 ir_graph *ip_in_and_out = NULL;
745 ir_graph *ip_only_in = NULL;
747 //printf("find tail for "); DDMG(n);
749 for (i = tos-1; i >= 0; --i) {
750 ir_graph *pred = (i < tos -1) ? stack[i+1] : n;
753 if (is_head (m, n)) {
754 //printf(" found 1a! "); DDM;
756 if (is_ip_head(pred, m)) {
757 //printf(" found 1b! "); DDM;
760 } else if (!ip_only_in && is_endless_head(m, n)) {
762 //printf(" found 2a! "); DDM;
763 if (is_ip_head(pred, m)) {
764 //printf(" found 2b! "); DDM;
767 } else if (is_ip_head(pred, m)) {
768 //printf(" found 3! "); DDM; This happens for self recursions in the second
769 //assert(0); scc iteration (the one to flip the loop.)
772 if (ip_in_and_out) break; /* That's what we really want. */
774 if (m == n) break; /* Don't walk past n on the stack! */
778 if (!in_and_out && !only_in)
779 /* There is no loop */
783 /* Is there a head in the callgraph without a head in the
785 assert(in_and_out || only_in);
787 m = (ip_in_and_out) ? ip_in_and_out : ip_only_in;
790 m = (in_and_out) ? in_and_out : only_in;
792 //printf("*** head is "); DDMG(m);
794 res_index = smallest_dfn_pred (m, get_irg_dfn(m) + 1);
795 if (res_index == -2) /* no smallest dfn pred found. */
796 res_index = largest_dfn_pred (m);
798 set_irg_callee_backedge (m, res_index);
799 res = get_irg_callee(m, res_index);
800 //printf("*** tail is "); DDMG(res);
806 /*-----------------------------------------------------------*
807 * The core algorithm. *
808 *-----------------------------------------------------------*/
811 static void cgscc (ir_graph *n) {
814 if (cg_irg_visited(n)) return;
815 mark_cg_irg_visited(n);
817 /* Initialize the node */
818 set_irg_dfn(n, current_dfn); /* Depth first number for this node */
819 set_irg_uplink(n, current_dfn); /* ... is default uplink. */
823 arity = get_irg_n_callees(n);
824 for (i = 0; i < arity; i++) {
826 if (is_irg_callee_backedge(n, i)) continue;
827 m = get_irg_callee(n, i);
829 /** This marks the backedge, but does it guarantee a correct loop tree? */
830 //if (m == n) { set_irg_callee_backedge(n, i); continue; }
833 if (irg_is_in_stack(m)) {
834 /* Uplink of m is smaller if n->m is a backedge.
835 Propagate the uplink to mark the cfloop. */
836 if (get_irg_uplink(m) < get_irg_uplink(n))
837 set_irg_uplink(n, get_irg_uplink(m));
841 if (get_irg_dfn(n) == get_irg_uplink(n)) {
842 /* This condition holds for
843 1) the node with the incoming backedge.
844 That is: We found a cfloop!
845 2) Straight line code, because no uplink has been propagated, so the
846 uplink still is the same as the dfn.
848 But n might not be a proper cfloop head for the analysis. Proper cfloop
849 heads are Block and Phi nodes. find_tail searches the stack for
850 Block's and Phi's and takes those nodes as cfloop heads for the current
851 cfloop instead and marks the incoming edge as backedge. */
853 ir_graph *tail = find_tail(n);
855 /* We have a cfloop, that is no straight line code,
856 because we found a cfloop head!
857 Next actions: Open a new cfloop on the cfloop tree and
858 try to find inner cfloops */
861 ir_loop *l = new_loop();
863 /* Remove the cfloop from the stack ... */
864 pop_scc_unmark_visit (n);
866 /* The current backedge has been marked, that is temporarily eliminated,
867 by find tail. Start the scc algorithm
868 anew on the subgraph thats left (the current cfloop without the backedge)
869 in order to find more inner cfloops. */
873 assert (cg_irg_visited(n));
883 static void reset_isbe(void) {
884 int i, n_irgs = get_irp_n_irgs();
886 for (i = 0; i < n_irgs; ++i) {
888 ir_graph *irg = get_irp_irg(i);
890 n_cs = get_irg_n_callers(irg);
891 for (j = 0; j < n_cs; ++j) {
892 irg->caller_isbe[j] = 0;
894 n_cs = get_irg_n_callees(irg);
895 for (j = 0; j < n_cs; ++j) {
896 irg->callee_isbe[j] = 0;
904 /* ----------------------------------------------------------------------------------- */
905 /* Another algorithm to compute recursion nesting depth */
906 /* Walk the callgraph. For each crossed edge increase the loop depth by the edge */
907 /* weight. Assign graphs the maximal depth. */
908 /* ----------------------------------------------------------------------------------- */
910 void compute_loop_depth (ir_graph *irg, void *env) {
911 int current_nesting = *(int *) env;
912 int old_nesting = irg->callgraph_loop_depth;
913 int old_visited = get_cg_irg_visited(irg);
918 if (cg_irg_visited(irg)) return;
920 mark_cg_irg_visited(irg);
922 //printf(" old: %d new %d master %d", old_visited, get_cg_irg_visited(irg), master_cg_visited); DDMG(irg);
925 if (old_nesting < current_nesting)
926 irg->callgraph_loop_depth = current_nesting;
928 if (current_nesting > irp->max_callgraph_loop_depth)
929 irp->max_callgraph_loop_depth = current_nesting;
931 if ((old_visited +1 < get_cg_irg_visited(irg)) || /* not yet visited */
932 (old_nesting < current_nesting)) { /* propagate larger nesting */
933 /* Don't walk the graph, but a tree that is an unfolded graph. */
934 n_callees = get_irg_n_callees(irg);
935 for (i = 0; i < n_callees; i++) {
936 ir_graph *m = get_irg_callee(irg, i);
937 *(int *)env += get_irg_callee_loop_depth(irg, i);
938 compute_loop_depth(m, env);
939 *(int *)env -= get_irg_callee_loop_depth(irg, i);
943 set_cg_irg_visited(irg, master_cg_visited-1);
947 /* ----------------------------------------------------------------------------------- */
948 /* Another algorithm to compute recursion nesting depth */
949 /* Walk the callgraph. For each crossed loop increase the nesting depth by one. */
950 /* Assign graphs the maximal nesting depth. Don't increas if passing loops more than */
952 /* ----------------------------------------------------------------------------------- */
955 /* For callees, we want to remember the Call nodes, too. */
957 ir_loop **loop_stack;
959 int recursion_nesting;
962 typedef struct ana_entry2 ana_entry2;
964 static void push2(ana_entry2 *e, ir_loop *g) {
965 if (ARR_LEN(e->loop_stack) == e->tos) {
966 ARR_APP1(ir_loop *, e->loop_stack, g);
968 e->loop_stack[e->tos] = g;
973 static ir_loop *pop2(ana_entry2 *e) {
975 return e->loop_stack[e->tos+1];
978 static int in_stack(ana_entry2 *e, ir_loop *g) {
980 for (i = e->tos-1; i >= 0; --i) {
981 if (e->loop_stack[i] == g) return 1;
986 void compute_rec_depth (ir_graph *irg, void *env) {
987 ana_entry2 *e = (ana_entry2 *)env;
989 int depth, old_depth = irg->callgraph_recursion_depth;
993 if (cg_irg_visited(irg)) return;
994 mark_cg_irg_visited(irg);
996 /* -- compute and set the new nesting value -- */
997 if ((l != irp->outermost_cg_loop) && !in_stack(e, l)) {
999 e->recursion_nesting++;
1002 depth = e->recursion_nesting;
1004 if (old_depth < depth)
1005 irg->callgraph_recursion_depth = depth;
1007 if (depth > irp->max_callgraph_recursion_depth)
1008 irp->max_callgraph_recursion_depth = depth;
1010 /* -- spread the nesting value -- */
1011 if (depth == 0 || old_depth < depth) {
1012 /* Don't walk the graph, but a tree that is an unfolded graph. */
1013 n_callees = get_irg_n_callees(irg);
1014 for (i = 0; i < n_callees; i++) {
1015 ir_graph *m = get_irg_callee(irg, i);
1016 compute_rec_depth(m, env);
1020 /* -- clean up -- */
1023 e->recursion_nesting--;
1025 set_cg_irg_visited(irg, master_cg_visited-1);
1029 /* Compute the backedges that represent recursions. */
1030 void find_callgraph_recursions(void) {
1031 int i, n_irgs = get_irp_n_irgs();
1032 int current_nesting;
1037 /* -- Compute the looptree -- */
1039 /* The outermost graph. We start here. Then we start at all
1040 functions in irg list that are never called, then at the remaining
1042 assert(get_irp_main_irg());
1043 outermost_ir_graph = get_irp_main_irg();
1046 current_loop = NULL;
1047 new_loop(); /* sets current_loop */
1049 master_cg_visited++;
1050 cgscc(outermost_ir_graph);
1051 for (i = 0; i < n_irgs; i++) {
1052 ir_graph *irg = get_irp_irg(i);
1053 if (!cg_irg_visited(irg) && get_irg_n_callers(irg) == 0)
1056 for (i = 0; i < n_irgs; i++) {
1057 ir_graph *irg = get_irp_irg(i);
1058 if (!cg_irg_visited(irg))
1061 irp->outermost_cg_loop = current_loop;
1063 /* -- Reverse the backedge information. -- */
1064 for (i = 0; i < n_irgs; i++) {
1065 ir_graph *irg = get_irp_irg(i);
1066 int j, n_callees = get_irg_n_callees(irg);
1067 for (j = 0; j < n_callees; ++j) {
1068 if (is_irg_callee_backedge(irg, j))
1069 set_irg_caller_backedge(get_irg_callee(irg, j), irg);
1073 /* -- compute the loop depth -- */
1074 current_nesting = 0;
1075 irp->max_callgraph_loop_depth = 0;
1076 master_cg_visited += 2;
1077 //printf (" ** starting at "); DDMG(get_irp_main_irg());
1078 compute_loop_depth(get_irp_main_irg(), ¤t_nesting);
1079 for (i = 0; i < n_irgs; i++) {
1080 ir_graph *irg = get_irp_irg(i);
1081 if ((get_cg_irg_visited(irg) < master_cg_visited-1) &&
1082 get_irg_n_callers(irg) == 0) {
1083 compute_loop_depth(irg, ¤t_nesting);
1084 //printf (" ** starting at "); DDMG(irg);
1087 for (i = 0; i < n_irgs; i++) {
1088 ir_graph *irg = get_irp_irg(i);
1089 if (get_cg_irg_visited(irg) < master_cg_visited-1) {
1090 compute_loop_depth(irg, ¤t_nesting);
1091 //printf (" ** starting at "); DDMG(irg);
1095 /* -- compute the recursion depth -- */
1096 e.loop_stack = NEW_ARR_F(ir_loop *, 0);
1098 e.recursion_nesting = 0;
1099 irp->max_callgraph_recursion_depth = 0;
1101 master_cg_visited += 2;
1102 compute_rec_depth(get_irp_main_irg(), &e);
1103 //printf (" ++ starting at "); DDMG(get_irp_main_irg());
1104 for (i = 0; i < n_irgs; i++) {
1105 ir_graph *irg = get_irp_irg(i);
1106 if ((get_cg_irg_visited(irg) < master_cg_visited-1) &&
1107 get_irg_n_callers(irg) == 0) {
1108 compute_rec_depth(irg, &e);
1109 //printf (" ++ starting at "); DDMG(irg);
1112 for (i = 0; i < n_irgs; i++) {
1113 ir_graph *irg = get_irp_irg(i);
1114 if (get_cg_irg_visited(irg) < master_cg_visited-1) {
1115 compute_rec_depth(irg, &e);
1116 //printf (" ++ starting at "); DDMG(irg);
1120 DEL_ARR_F(e.loop_stack);
1122 //dump_callgraph("-with_nesting");
1124 //dump_callgraph_loop_tree(current_loop, "-after_cons");
1125 irp->callgraph_state = irp_callgraph_and_calltree_consistent;
1128 /* Maximal loop depth of all paths from an external visible method to
1130 int get_irg_loop_depth(ir_graph *irg) {
1131 assert(irp->callgraph_state == irp_callgraph_consistent ||
1132 irp->callgraph_state == irp_callgraph_and_calltree_consistent);
1133 return irg->callgraph_loop_depth;
1136 /* Maximal recursion depth of all paths from an external visible method to
1138 int get_irg_recursion_depth(ir_graph *irg) {
1139 assert(irp->callgraph_state == irp_callgraph_and_calltree_consistent);
1140 return irg->callgraph_recursion_depth;
1143 void analyse_loop_nesting_depth(void) {
1144 entity **free_methods = NULL;
1147 /* establish preconditions. */
1148 if (get_irp_callee_info_state() != irg_callee_info_consistent) {
1149 cgana(&arr_len, &free_methods);
1152 if (irp_callgraph_consistent != get_irp_callgraph_state()) {
1153 compute_callgraph();
1156 find_callgraph_recursions();