3 * File name: ir/ana/irscc.c
4 * Purpose: Compute the strongly connected regions and build
5 * backedge/loop datastructures.
6 * A variation on the Tarjan algorithm. See also [Trapp:99],
8 * Author: Goetz Lindenmaier
12 * Copyright: (c) 2002-2003 Universität Karlsruhe
13 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
24 #include "irgraph_t.h"
31 ir_graph *outermost_ir_graph; /* The outermost graph the scc is computed
33 static ir_loop *current_loop; /* Current loop construction is working
35 static int loop_node_cnt = 0; /* Counts the number of allocated loop nodes.
36 Each loop node gets a unique number.
37 What for? ev. remove. @@@ */
38 static int current_dfn = 1; /* Counter to generate depth first numbering
41 /**********************************************************************/
42 /* Node attributes **/
43 /**********************************************************************/
45 /* A map to get from irnodes to loop nodes. */
46 static pmap *node_loop_map = NULL;
48 /**********************************************************************/
49 /* Node attributes needed for the construction. **/
50 /**********************************************************************/
52 typedef struct scc_info {
53 bool in_stack; /* Marks whether node is on the stack. */
54 int dfn; /* Depth first search number. */
55 int uplink; /* dfn number of ancestor. */
56 /* ir_loop *loop; *//* Refers to the containing loop. */
58 struct section *section;
64 static INLINE scc_info* new_scc_info(void) {
65 scc_info *info = obstack_alloc (outermost_ir_graph->obst, sizeof (scc_info));
66 memset (info, 0, sizeof (scc_info));
71 mark_irn_in_stack (ir_node *n) {
72 assert(get_irn_link(n));
74 /* ((scc_info *)get_irn_link(n))->in_stack = true; */
75 ((scc_info *)n->link)->in_stack = true;
79 mark_irn_not_in_stack (ir_node *n) {
80 assert(get_irn_link(n));
82 /* ((scc_info *)get_irn_link(n))->in_stack = false; */
83 ((scc_info *)n->link)->in_stack = false;
87 irn_is_in_stack (ir_node *n) {
88 assert(get_irn_link(n));
90 /* return ((scc_info *)get_irn_link(n))->in_stack; */
91 return ((scc_info *)n->link)->in_stack;
95 set_irn_uplink (ir_node *n, int uplink) {
96 assert(get_irn_link(n));
98 /* ((scc_info *)get_irn_link(n))->uplink = uplink; */
99 ((scc_info *)n->link)->uplink = uplink;
103 get_irn_uplink (ir_node *n) {
104 assert(get_irn_link(n));
105 /* from fast to slow */
106 /* return ((scc_info *)get_irn_link(n))->uplink; */
107 return ((scc_info *)n->link)->uplink;
111 set_irn_dfn (ir_node *n, int dfn) {
112 assert(get_irn_link(n));
114 /* ((scc_info *)get_irn_link(n))->dfn = dfn; */
115 ((scc_info *)n->link)->dfn = dfn;
119 get_irn_dfn (ir_node *n) {
120 assert(get_irn_link(n));
122 /* return ((scc_info *)get_irn_link(n))->dfn; */
123 return ((scc_info *)n->link)->dfn;
127 /* Replaced node loop map by real field as hash access dominates runtime
128 * of the algorithm. ! */
129 /* Uses temporary information to set the loop */
131 set_irn_loop (ir_node *n, ir_loop* loop) {
132 assert(node_loop_map && "not initialized!");
133 pmap_insert(node_loop_map, (void *)n, (void *)loop);
136 /* Uses temporary information to get the loop */
138 get_irn_loop (ir_node *n) {
140 if (!node_loop_map) return NULL;
142 if (pmap_contains(node_loop_map, (void *)n))
143 res = (ir_loop *) pmap_get(node_loop_map, (void *)n);
149 set_irn_loop (ir_node *n, ir_loop* loop) {
153 /* Uses temporary information to get the loop */
155 get_irn_loop (ir_node *n) {
162 static ir_loop *find_nodes_loop (ir_node *n, ir_loop *l) {
166 /* Test whether n is contained in this loop. */
167 for (i = 0; i < get_loop_n_nodes(l); i++)
168 if (n == get_loop_node(l, i)) return l;
170 /* Is this a leave in the loop tree? If so loop not found. */
171 if (get_loop_n_sons(l) == 0) return NULL;
173 /* Else descend in the loop tree. */
174 for (i = 0; i < get_loop_n_sons(l); i++) {
175 res = find_nodes_loop(n, get_loop_son(l, i));
181 /* @@@ temporary implementation, costly!!! */
182 ir_loop * get_irn_loop(ir_node *n) {
183 ir_loop *l = get_irg_loop(current_ir_graph);
184 l = find_nodes_loop(n, l);
189 /**********************************************************************/
191 /**********************************************************************/
193 static ir_node **stack = NULL;
194 static int tos = 0; /* top of stack */
196 static INLINE void init_stack(void) {
198 ARR_RESIZE (ir_node *, stack, 1000);
200 stack = NEW_ARR_F (ir_node *, 1000);
206 static INLINE void free_stack(void) {
218 if (tos == ARR_LEN (stack)) {
219 int nlen = ARR_LEN (stack) * 2;
220 ARR_RESIZE (ir_node *, stack, nlen);
223 mark_irn_in_stack(n);
226 static INLINE ir_node *
229 ir_node *n = stack[--tos];
230 mark_irn_not_in_stack(n);
234 /* The nodes up to n belong to the current loop.
235 Removes them from the stack and adds them to the current loop. */
237 pop_scc_to_loop (ir_node *n)
247 set_irn_dfn(m, loop_node_cnt);
248 add_loop_node(current_loop, m);
249 set_irn_loop(m, current_loop);
251 /* if (m==n) break;*/
255 printf("Mehr als eine Iteration!!!!!!!!!!!!!!!!!!!!!!!!!!!!11111\n");
258 /* GL ??? my last son is my grandson??? Removes loops with no
259 ir_nodes in them. Such loops have only another loop as son. (Why
260 can't they have two loops as sons? Does it never get that far? ) */
261 void close_loop (ir_loop *l)
263 int last = get_loop_n_elements(l) - 1;
264 loop_element lelement = get_loop_element(l, last);
265 ir_loop *last_son = lelement.son;
267 if (get_kind(last_son) == k_ir_loop &&
268 get_loop_n_elements(last_son) == 1)
272 lelement = get_loop_element(last_son, 0);
274 if(get_kind(gson) == k_ir_loop)
276 loop_element new_last_son;
278 gson -> outer_loop = l;
279 new_last_son.son = gson;
280 l -> children[last] = new_last_son;
287 /* Removes and unmarks all nodes up to n from the stack.
288 The nodes must be visited once more to assign them to a scc. */
290 pop_scc_unmark_visit (ir_node *n)
296 set_irn_visited(m, 0);
300 /**********************************************************************/
301 /* The loop datastructure. **/
302 /**********************************************************************/
304 /* Allocates a new loop as son of current_loop. Sets current_loop
305 to the new loop and returns the father. */
306 static ir_loop *new_loop (void) {
307 ir_loop *father, *son;
309 father = current_loop;
311 son = (ir_loop *) obstack_alloc (outermost_ir_graph->obst, sizeof (ir_loop));
312 memset (son, 0, sizeof (ir_loop));
313 son->kind = k_ir_loop;
314 son->children = NEW_ARR_F (loop_element, 0);
318 son->outer_loop = father;
319 add_loop_son(father, son);
320 son->depth = father->depth+1;
321 } else { /* The root loop */
322 son->outer_loop = son;
327 son->loop_nr = get_irp_new_node_nr();
336 /* Finishes the datastructures, copies the arrays to the obstack
338 A. Schoesser: Caution: loop -> sons is gone. */
339 static void mature_loop (ir_loop *loop) {
342 new_sons = NEW_ARR_D (ir_loop *, current_ir_graph->obst, ARR_LEN(loop->sons));
343 memcpy (new_sons, loop->sons, sizeof (ir_loop *) * ARR_LEN(loop->sons));
344 DEL_ARR_F(loop->sons);
345 loop->sons = new_sons;
349 /* Returns outer loop, itself if outermost. */
350 ir_loop *get_loop_outer_loop (ir_loop *loop) {
351 assert(loop && loop->kind == k_ir_loop);
352 return loop->outer_loop;
355 /* Returns nesting depth of this loop */
356 int get_loop_depth (ir_loop *loop) {
357 assert(loop); assert(loop->kind == k_ir_loop);
361 /* Returns the number of inner loops */
362 int get_loop_n_sons (ir_loop *loop) {
363 assert(loop && loop->kind == k_ir_loop);
364 return(loop -> n_sons);
367 /* Returns the pos`th loop_node-child *
368 * TODO: This method isn`t very efficient ! *
369 * Returns NULL if there isnt`t a pos`th loop_node */
370 ir_loop *get_loop_son (ir_loop *loop, int pos) {
371 int child_nr = 0, loop_nr = -1;
373 assert(loop && loop->kind == k_ir_loop);
374 while(child_nr < ARR_LEN(loop->children))
376 if(*(loop -> children[child_nr].kind) == k_ir_loop)
379 return(loop -> children[child_nr].son);
385 /* Use EXCLUSIVELY this function to add sons, otherwise the loop->n_sons
389 add_loop_son(ir_loop *loop, ir_loop *son) {
392 assert(loop && loop->kind == k_ir_loop);
393 assert(get_kind(son) == k_ir_loop);
394 ARR_APP1 (loop_element, loop->children, lson);
398 /* Returns the number of nodes in the loop */
399 int get_loop_n_nodes (ir_loop *loop) {
400 assert(loop); assert(loop->kind == k_ir_loop);
401 return loop -> n_nodes;
402 /* return ARR_LEN(loop->nodes); */
405 /* Returns the pos`th ir_node-child *
406 * TODO: This method isn`t very efficient ! *
407 * Returns NULL if there isnt`t a pos`th ir_node */
408 ir_node *get_loop_node (ir_loop *loop, int pos) {
409 int child_nr, node_nr = -1;
411 assert(loop && loop->kind == k_ir_loop);
412 assert(pos < get_loop_n_nodes(loop));
414 for (child_nr = 0; child_nr < ARR_LEN(loop->children); child_nr++) {
415 if(*(loop -> children[child_nr].kind) == k_ir_node)
418 return(loop -> children[child_nr].node);
421 printf("pos: %d\n", pos);
422 assert(0 && "no child at pos found");
426 /* Use EXCLUSIVELY this function to add nodes, otherwise the loop->n_nodes
430 add_loop_node(ir_loop *loop, ir_node *n) {
433 assert(loop && loop->kind == k_ir_loop);
434 assert(get_kind(n) == k_ir_node);
435 ARR_APP1 (loop_element, loop->children, ln);
439 /** Returns the number of elements contained in loop. */
440 int get_loop_n_elements (ir_loop *loop) {
441 assert(loop && loop->kind == k_ir_loop);
442 return(ARR_LEN(loop->children));
446 Returns the pos`th loop element.
447 This may be a loop_node or a ir_node. The caller of this function has
448 to check the *(loop_element.kind) field for "k_ir_node" or "k_ir_loop"
449 and then select the apropriate "loop_element.node" or "loop_element.son".
452 loop_element get_loop_element (ir_loop *loop, int pos) {
453 assert(loop && loop->kind == k_ir_loop && pos < ARR_LEN(loop->children));
455 return(loop -> children[pos]);
458 int get_loop_element_pos(ir_loop *loop, void *le) {
460 assert(loop && loop->kind == k_ir_loop);
462 for (i = 0; i < get_loop_n_elements(loop); i++)
463 if (get_loop_element(loop, i).node == le) return i;
467 int get_loop_loop_nr(ir_loop *loop) {
468 assert(loop && loop->kind == k_ir_loop);
470 return loop->loop_nr;
477 /** A field to connect additional information to a loop. Only valid
478 if libfirm_debug is set. */
479 void set_loop_link (ir_loop *loop, void *link) {
480 assert(loop && loop->kind == k_ir_loop);
485 void *get_loop_link (const ir_loop *loop) {
486 assert(loop && loop->kind == k_ir_loop);
494 /* The outermost loop is remarked in the surrounding graph. */
495 void set_irg_loop(ir_graph *irg, ir_loop *loop) {
499 ir_loop *get_irg_loop(ir_graph *irg) {
505 /**********************************************************************/
506 /* Constructing and destructing the loop/backedge information. **/
507 /**********************************************************************/
509 /* Initialization steps. **********************************************/
512 init_node (ir_node *n, void *env) {
513 set_irn_link (n, new_scc_info());
516 /* Also init nodes not visible in intraproc_view. */
517 /* @@@ init_node is called for too many nodes -- this wastes memory!.
518 The mem is not lost as its on the obstack. */
519 if (intern_get_irn_op(n) == op_Filter) {
520 for (i = 0; i < get_Filter_n_cg_preds(n); i++)
521 init_node(get_Filter_cg_pred(n, i), NULL);
523 if (intern_get_irn_op(n) == op_Block) {
524 for (i = 0; i < get_Block_cg_n_cfgpreds(n); i++) {
525 init_node(get_Block_cg_cfgpred(n, i), NULL);
528 /* The following pattern matches only after a call from above pattern. */
529 if ((intern_get_irn_op(n) == op_Proj) /*&& (get_Proj_proj(n) == 0)*/) {
530 /* @@@ init_node is called for every proj -- this wastes memory!.
531 The mem is not lost as its on the obstack. */
532 ir_node *cb = get_Proj_pred(n);
533 if ((intern_get_irn_op(cb) == op_CallBegin) ||
534 (intern_get_irn_op(cb) == op_EndReg) ||
535 (intern_get_irn_op(cb) == op_EndExcept)) {
537 init_node(get_nodes_Block(cb), NULL);
544 init_scc_common (void) {
547 if (!node_loop_map) node_loop_map = pmap_create();
552 init_scc (ir_graph *irg) {
554 irg_walk_graph (irg, init_node, NULL, NULL);
556 irg_walk (irg, link_to_reg_end, NULL, NULL);
563 cg_walk (init_node, NULL, NULL);
566 /* Condition for breaking the recursion. */
567 static bool is_outermost_Start(ir_node *n) {
568 /* Test whether this is the outermost Start node. If so
569 recursion must end. */
570 if ((intern_get_irn_op(n) == op_Block) &&
571 (get_Block_n_cfgpreds(n) == 1) &&
572 (intern_get_irn_op(skip_Proj(get_Block_cfgpred(n, 0))) == op_Start) &&
573 (get_nodes_Block(skip_Proj(get_Block_cfgpred(n, 0))) == n)) {
577 /* @@@ Bad condition:
578 not possible in interprocedural view as outermost_graph is
579 not necessarily the only with a dead-end start block.
580 Besides current_ir_graph is not set properly. */
581 if ((intern_get_irn_op(n) == op_Block) &&
582 (n == get_irg_start_block(current_ir_graph))) {
583 if ((!interprocedural_view) ||
584 (current_ir_graph == outermost_ir_graph))
591 /* Don't walk from nodes to blocks except for Control flow operations. */
593 get_start_index(ir_node *n) {
595 if (is_cfop(n) || is_fragile_op(n) || intern_get_irn_op(n) == op_Start)
596 // this should be sufficient.
601 /* This version causes deeper loop trees (at least we verified this for Polymor).
602 But it guarantees that Blocks are analysed before nodes contained in the
603 block. If so, we can set the value to undef if the block is not executed. */
604 if (intern_get_irn_op(n) == op_Phi ||
605 intern_get_irn_op(n) == op_Block ||
606 (intern_get_irn_op(n) == op_Filter && interprocedural_view))
607 // Here we could test for backedge at -1 which is illegal
614 /* Returns current_ir_graph and set it to the irg of predecessor index
616 static INLINE ir_graph *
617 switch_irg (ir_node *n, int index) {
618 ir_graph *old_current = current_ir_graph;
620 if (interprocedural_view) {
621 /* Only Filter and Block nodes can have predecessors in other graphs. */
622 if (intern_get_irn_op(n) == op_Filter)
623 n = get_nodes_Block(n);
624 if (intern_get_irn_op(n) == op_Block) {
625 ir_node *cfop = skip_Proj(get_Block_cfgpred(n, index));
626 if (is_ip_cfop(cfop)) {
627 current_ir_graph = get_irn_irg(cfop);
628 set_irg_visited(current_ir_graph, get_max_irg_visited());
636 /* Walks up the stack passing n and then finding the node
637 where we walked into the irg n is contained in.
638 Here we switch the irg. */
640 find_irg_on_stack (ir_node *n) {
642 ir_graph *old_current = current_ir_graph;
645 if (interprocedural_view) {
646 for (i = tos; i >= 0; i--) {
647 if (stack[i] == n) break;
652 for (; i >= 0; i--) {
654 /*printf(" Visiting %d ", i); DDMN(m);*/
656 current_ir_graph = get_irn_irg(m);
659 if (intern_get_irn_op(m) == op_Filter) {
660 /* Find the corresponding ip_cfop */
661 ir_node *pred = stack[i+1];
663 for (j = 0; j < get_Filter_n_cg_preds(m); j++)
664 if (get_Filter_cg_pred(m, j) == pred) break;
665 if (j >= get_Filter_n_cg_preds(m))
666 /* It is a filter we didn't pass as the predecessors are marked. */
668 assert(get_Filter_cg_pred(m, j) == pred);
680 static void test(ir_node *pred, ir_node *root, ir_node *this) {
682 if (get_irn_uplink(pred) >= get_irn_uplink(root)) return;
684 printf("this: %d ", get_irn_uplink(this)); DDMN(this);
685 printf("pred: %d ", get_irn_uplink(pred)); DDMN(pred);
686 printf("root: %d ", get_irn_uplink(root)); DDMN(root);
688 printf("tos: %d\n", tos);
690 for (i = tos; i >= 0; i--) {
691 ir_node *n = stack[i];
693 printf(" uplink: %d, pos: %d ", get_irn_uplink(n), i); DDMN(n);
698 /* Test for legal loop header: Block, Phi, ... */
699 INLINE static bool is_possible_loop_head(ir_node *n) {
700 ir_op *op = intern_get_irn_op(n);
701 return ((op == op_Block) ||
703 ((op == op_Filter) && interprocedural_view));
706 /* Returns true if n is a loop header, i.e., it is a Block, Phi
707 or Filter node and has predecessors within the loop and out
709 @arg root: only needed for assertion. */
711 is_head (ir_node *n, ir_node *root)
714 int some_outof_loop = 0, some_in_loop = 0;
716 /* Test for legal loop header: Block, Phi, ... */
717 if (!is_possible_loop_head(n))
720 if (!is_outermost_Start(n)) {
721 arity = intern_get_irn_arity(n);
722 for (i = get_start_index(n); i < arity; i++) {
723 ir_node *pred = intern_get_irn_n(n, i);
725 if (is_backedge(n, i)) continue;
726 if (!irn_is_in_stack(pred)) {
729 assert(get_irn_uplink(pred) >= get_irn_uplink(root));
734 return some_outof_loop && some_in_loop;
737 /* Returns index of the predecessor with the smallest dfn number
738 greater-equal than limit. */
740 smallest_dfn_pred (ir_node *n, int limit)
742 int i, index = -2, min = -1;
744 if (!is_outermost_Start(n)) {
745 int arity = intern_get_irn_arity(n);
746 for (i = get_start_index(n); i < arity; i++) {
747 ir_node *pred = intern_get_irn_n(n, i);
749 if (is_backedge(n, i) || !irn_is_in_stack(pred)) continue;
750 if (get_irn_dfn(pred) >= limit && (min == -1 || get_irn_dfn(pred) < min)) {
752 min = get_irn_dfn(pred);
759 /* Returns index of the predecessor with the largest dfn number. */
761 largest_dfn_pred (ir_node *n)
763 int i, index = -2, max = -1;
765 if (!is_outermost_Start(n)) {
766 int arity = intern_get_irn_arity(n);
767 for (i = get_start_index(n); i < arity; i++) {
768 ir_node *pred = intern_get_irn_n(n, i);
769 if (is_backedge (n, i) || !irn_is_in_stack(pred)) continue;
770 if (get_irn_dfn(pred) > max) {
772 max = get_irn_dfn(pred);
779 /* Searches the stack for possible loop heads. Tests these for backedges.
780 If it finds a head with an unmarked backedge it marks this edge and
781 returns the tail of the loop.
782 If it finds no backedge returns NULL.
783 ("disable_backedge" in fiasco) */
786 find_tail (ir_node *n) {
788 int i, res_index = -2;
791 if (!icfg && rm_cyclic_phis && remove_cyclic_phis (n)) return NULL;
794 m = stack[tos-1]; /* tos = top of stack */
795 if (is_head (m, n)) {
796 res_index = smallest_dfn_pred(m, 0);
797 if ((res_index == -2) && /* no smallest dfn pred found. */
801 if (m == n) return NULL;
802 for (i = tos-2; ; --i) {
804 if (is_head (m, n)) {
805 res_index = smallest_dfn_pred (m, get_irn_dfn(m) + 1);
806 if (res_index == -2) /* no smallest dfn pred found. */
807 res_index = largest_dfn_pred (m);
812 assert (res_index > -2);
814 set_backedge (m, res_index);
815 return is_outermost_Start(n) ? NULL : intern_get_irn_n(m, res_index);
819 /* The core algorithm. *****************************************/
821 static void scc (ir_node *n) {
823 if (irn_visited(n)) return;
826 /* Initialize the node */
827 set_irn_dfn(n, current_dfn); /* Depth first number for this node */
828 set_irn_uplink(n, current_dfn); /* ... is default uplink. */
829 set_irn_loop(n, NULL);
833 /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
834 array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
835 so is_backedge does not access array[-1] but correctly returns false! */
837 if (!is_outermost_Start(n)) {
838 int arity = intern_get_irn_arity(n);
839 for (i = get_start_index(n); i < arity; i++) {
841 if (is_backedge(n, i)) continue;
843 m = intern_get_irn_n(n, i); /* get_irn_ip_pred(n, i); */
844 /* if ((!m) || (intern_get_irn_op(m) == op_Unknown)) continue; */
846 if (irn_is_in_stack(m)) {
847 /* Uplink of m is smaller if n->m is a backedge.
848 Propagate the uplink to mark the loop. */
849 if (get_irn_uplink(m) < get_irn_uplink(n))
850 set_irn_uplink(n, get_irn_uplink(m));
855 if (get_irn_dfn(n) == get_irn_uplink(n)) {
856 /* This condition holds for the node with the incoming backedge.
857 AS: That is: For the loop head. */
858 ir_node *tail = find_tail(n);
860 /* We found a new inner loop! */
862 /* This is an adaption of the algorithm from fiasco / optscc to
863 * avoid loops without Block or Phi as first node. This should
864 * severely reduce the number of evaluations of nodes to detect
865 * a fixpoint in the heap analyses.
866 * Further it avoids loops without firm nodes that cause errors
867 * in the heap analyses. */
868 #define NO_LOOPS_WITHOUT_HEAD 1
869 #if NO_LOOPS_WITHOUT_HEAD
872 if (get_loop_n_elements(current_loop) > 0) {
880 ir_loop *l = new_loop();
883 /* Remove the loop from the stack ... */
884 pop_scc_unmark_visit (n);
885 /* and recompute it in a better order; and so that it goes into
887 /* GL @@@ remove experimental stuff rem = find_irg_on_stack(tail); */
890 /* GL @@@ remove experimental stuff current_ir_graph = rem; */
892 assert (irn_visited(n));
893 #if NO_LOOPS_WITHOUT_HEAD
898 /* AS: No inner loop was found. Pop all nodes from the stack
899 to the current loop. */
905 /* Constructs backedge information for irg. In interprocedural view constructs
906 backedges for all methods called by irg, too. */
907 void construct_backedges(ir_graph *irg) {
908 ir_graph *rem = current_ir_graph;
911 assert(!interprocedural_view &&
912 "not implemented, use construct_ip_backedges");
914 current_ir_graph = irg;
915 outermost_ir_graph = irg;
917 init_scc(current_ir_graph);
920 new_loop(); /* sets current_loop */
921 head_rem = current_loop; /* Just for assertion */
923 if (interprocedural_view) {
924 set_irg_visited(current_ir_graph, inc_max_irg_visited());
927 inc_irg_visited(current_ir_graph);
930 scc(get_irg_end(current_ir_graph));
932 if (interprocedural_view) finish_ip_walk();
934 assert(head_rem == current_loop);
935 set_irg_loop(current_ir_graph, current_loop);
936 set_irg_loopinfo_state(current_ir_graph, loopinfo_consistent);
937 assert(get_irg_loop(current_ir_graph)->kind == k_ir_loop);
939 irg->loops = current_loop;
943 count_loop (the_loop, &count, &depth);
947 current_ir_graph = rem;
952 void construct_ip_backedges (void) {
953 ir_graph *rem = current_ir_graph;
954 int rem_ipv = interprocedural_view;
957 outermost_ir_graph = get_irp_main_irg();
962 new_loop(); /* sets current_loop */
963 interprocedural_view = 1;
965 inc_max_irg_visited();
966 for (i = 0; i < get_irp_n_irgs(); i++)
967 set_irg_visited(get_irp_irg(i), get_max_irg_visited());
969 for (i = 0; i < get_irp_n_irgs(); i++) {
971 current_ir_graph = get_irp_irg(i);
972 /* Find real entry points */
973 sb = get_irg_start_block(current_ir_graph);
974 if ((get_Block_n_cfgpreds(sb) > 1) ||
975 (get_nodes_Block(get_Block_cfgpred(sb, 0)) != sb)) continue;
976 /* Compute scc for this graph */
977 outermost_ir_graph = current_ir_graph;
978 set_irg_visited(outermost_ir_graph, get_max_irg_visited());
979 scc(get_irg_end(current_ir_graph));
980 for (j = 0; j < get_End_n_keepalives(get_irg_end(outermost_ir_graph)); j++)
981 scc(get_End_keepalive(get_irg_end(outermost_ir_graph), j));
984 set_irg_loop(outermost_ir_graph, current_loop);
985 set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
986 assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
988 current_ir_graph = rem;
989 interprocedural_view = rem_ipv;
992 void construct_ip_backedges (void) {
993 ir_graph *rem = current_ir_graph;
994 int rem_ipv = interprocedural_view;
997 outermost_ir_graph = get_irp_main_irg();
1001 current_loop = NULL;
1002 new_loop(); /* sets current_loop */
1003 interprocedural_view = 1;
1005 inc_max_irg_visited();
1006 for (i = 0; i < get_irp_n_irgs(); i++)
1007 set_irg_visited(get_irp_irg(i), get_max_irg_visited());
1009 /** We have to start the walk at the same nodes as cg_walk. **/
1010 /* Walk starting at unreachable procedures. Only these
1011 * have End blocks visible in interprocedural view. */
1012 for (i = 0; i < get_irp_n_irgs(); i++) {
1014 current_ir_graph = get_irp_irg(i);
1016 sb = get_irg_start_block(current_ir_graph);
1018 if ((get_Block_n_cfgpreds(sb) > 1) ||
1019 (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
1021 scc(get_irg_end(current_ir_graph));
1024 /* Check whether we walked all procedures: there could be procedures
1025 with cyclic calls but no call from the outside. */
1026 for (i = 0; i < get_irp_n_irgs(); i++) {
1028 current_ir_graph = get_irp_irg(i);
1030 /* Test start block: if inner procedure end and end block are not
1031 * visible and therefore not marked. */
1032 sb = get_irg_start_block(current_ir_graph);
1033 if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) scc(sb);
1036 /* Walk all endless loops in inner procedures.
1037 * We recognize an inner procedure if the End node is not visited. */
1038 for (i = 0; i < get_irp_n_irgs(); i++) {
1040 current_ir_graph = get_irp_irg(i);
1042 e = get_irg_end(current_ir_graph);
1043 if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
1045 /* Don't visit the End node. */
1046 for (j = 0; j < get_End_n_keepalives(e); j++) scc(get_End_keepalive(e, j));
1050 set_irg_loop(outermost_ir_graph, current_loop);
1051 set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
1052 assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
1054 current_ir_graph = rem;
1055 interprocedural_view = rem_ipv;
1059 static void reset_backedges(ir_node *n) {
1060 if (is_possible_loop_head(n)) {
1061 int rem = interprocedural_view;
1062 interprocedural_view = 1;
1064 interprocedural_view = 0;
1066 interprocedural_view = rem;
1070 static void loop_reset_backedges(ir_loop *l) {
1072 reset_backedges(get_loop_node(l, 0));
1073 for (i = 0; i < get_loop_n_nodes(l); ++i)
1074 set_irn_loop(get_loop_node(l, i), NULL);
1075 for (i = 0; i < get_loop_n_sons(l); ++i) {
1076 loop_reset_backedges(get_loop_son(l, i));
1080 /** Removes all loop information.
1081 Resets all backedges */
1082 void free_loop_information(ir_graph *irg) {
1083 if (get_irg_loop(irg))
1084 loop_reset_backedges(get_irg_loop(irg));
1085 set_irg_loop(irg, NULL);
1086 set_irg_loopinfo_state(current_ir_graph, loopinfo_none);
1087 /* We cannot free the loop nodes, they are on the obstack. */
1091 void free_all_loop_information (void) {
1093 int rem = interprocedural_view;
1094 interprocedural_view = 1; /* To visit all filter nodes */
1095 for (i = 0; i < get_irp_n_irgs(); i++) {
1096 free_loop_information(get_irp_irg(i));
1098 pmap_destroy(node_loop_map);
1099 node_loop_map = NULL;
1100 interprocedural_view = rem;
1107 /* Debug stuff *************************************************/
1109 static int test_loop_node(ir_loop *l) {
1110 int i, has_node = 0, found_problem = 0;
1113 assert(l && l->kind == k_ir_loop);
1115 if (get_loop_n_elements(l) == 0) {
1116 printf(" Loop completely empty! "); DDML(l);
1118 dump_loop(l, "-ha");
1121 le = get_loop_element(l, 0);
1122 if (*(le.kind) != k_ir_node) {
1123 assert(le.kind && *(le.kind) == k_ir_loop);
1124 printf(" First loop element is not a node! "); DDML(l);
1125 printf(" "); DDML(le.son);
1128 dump_loop(l, "-ha");
1131 if ((*(le.kind) == k_ir_node) && !is_possible_loop_head(le.node)) {
1132 printf(" Wrong node as head! "); DDML(l);
1133 printf(" "); DDMN(le.node);
1135 dump_loop(l, "-ha");
1138 if ((get_loop_depth(l) != 0) &&
1139 (*(le.kind) == k_ir_node) && !has_backedges(le.node)) {
1140 printf(" Loop head has no backedges! "); DDML(l);
1141 printf(" "); DDMN(le.node);
1143 dump_loop(l, "-ha");
1148 for (i = 0; i < get_loop_n_elements(l); ++i) {
1149 le = get_loop_element(l, i);
1150 if (*(le.kind) == k_ir_node)
1153 if (test_loop_node(le.son)) found_problem = 1;
1156 if (has_node == 0) {
1157 printf(" Loop has no firm node! "); DDML(l);
1159 dump_loop(l, "-ha");
1162 if (get_loop_loop_nr(l) == 11819)
1163 dump_loop(l, "-ha-debug");
1165 return found_problem;
1168 /** Prints all loop nodes that
1169 * - do not have any firm nodes, only loop sons
1170 * - the header is not a Phi, Block or Filter.
1172 void find_strange_loop_nodes(ir_loop *l) {
1173 int found_problem = 0;
1174 printf("\nTesting loop "); DDML(l);
1175 found_problem = test_loop_node(l);
1176 printf("Finished Test\n\n");
1177 if (found_problem) exit(0);