construction now returns depth of loop tree.
[libfirm] / ir / ana / ircfscc.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ana/irscc.c
4  * Purpose:     Compute the strongly connected regions and build
5  *              backedge/cfloop datastructures.
6  *              A variation on the Tarjan algorithm. See also [Trapp:99],
7  *              Chapter 5.2.1.2.
8  * Author:      Goetz Lindenmaier
9  * Modified by:
10  * Created:     7.2002
11  * CVS-ID:      $Id$
12  * Copyright:   (c) 2002-2003 Universität Karlsruhe
13  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
14  */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include <string.h>
21
22 #include "irloop_t.h"
23 #include "irnode_t.h"
24 #include "irgraph_t.h"
25 #include "array.h"
26 #include "pmap.h"
27 #include "irgwalk.h"
28 #include "irprog_t.h"
29 #include "irdump.h"
30
31 #define NO_CFLOOPS_WITHOUT_HEAD 1
32
33 static ir_graph *outermost_ir_graph;      /* The outermost graph the scc is computed
34                       for */
35 static ir_loop *current_loop;      /* Current cfloop construction is working
36                       on. */
37 static int loop_node_cnt = 0;      /* Counts the number of allocated cfloop nodes.
38                                       Each cfloop node gets a unique number.
39                                       What for? ev. remove. @@@ */
40 static int current_dfn = 1;        /* Counter to generate depth first numbering
41                                       of visited nodes.  */
42
43 static int max_loop_depth = 0;
44
45 void link_to_reg_end (ir_node *n, void *env);
46
47 /**********************************************************************/
48 /* Node attributes                                                   **/
49 /**********************************************************************/
50
51 /**********************************************************************/
52 /* Node attributes needed for the construction.                      **/
53 /**********************************************************************/
54
55 typedef struct scc_info {
56   bool in_stack;         /* Marks whether node is on the stack. */
57   int dfn;               /* Depth first search number. */
58   int uplink;            /* dfn number of ancestor. */
59 } scc_info;
60
61 static INLINE scc_info* new_scc_info(void) {
62   scc_info *info = obstack_alloc (outermost_ir_graph->obst, sizeof (scc_info));
63   memset (info, 0, sizeof (scc_info));
64   return info;
65 }
66
67 static INLINE void
68 mark_irn_in_stack (ir_node *n) {
69   assert(get_irn_link(n));
70   ((scc_info *)n->link)->in_stack = true;
71 }
72
73 static INLINE void
74 mark_irn_not_in_stack (ir_node *n) {
75   assert(get_irn_link(n));
76   ((scc_info *)n->link)->in_stack = false;
77 }
78
79 static INLINE bool
80 irn_is_in_stack (ir_node *n) {
81   assert(get_irn_link(n));
82   return ((scc_info *)n->link)->in_stack;
83 }
84
85 static INLINE void
86 set_irn_uplink (ir_node *n, int uplink) {
87   assert(get_irn_link(n));
88   ((scc_info *)n->link)->uplink = uplink;
89 }
90
91 static INLINE int
92 get_irn_uplink (ir_node *n) {
93   assert(get_irn_link(n));
94   return ((scc_info *)n->link)->uplink;
95 }
96
97 static INLINE void
98 set_irn_dfn (ir_node *n, int dfn) {
99   assert(get_irn_link(n));
100   ((scc_info *)n->link)->dfn = dfn;
101 }
102
103 static INLINE int
104 get_irn_dfn (ir_node *n) {
105   assert(get_irn_link(n));
106   return ((scc_info *)n->link)->dfn;
107 }
108
109 /**********************************************************************/
110 /* A stack.                                                          **/
111 /**********************************************************************/
112
113 static ir_node **stack = NULL;
114 static int tos = 0;                /* top of stack */
115
116 static INLINE void init_stack(void) {
117   if (stack) {
118     ARR_RESIZE (ir_node *, stack, 1000);
119   } else {
120     stack = NEW_ARR_F (ir_node *, 1000);
121   }
122   tos = 0;
123 }
124
125
126 static INLINE void
127 push (ir_node *n)
128 {
129   if (tos == ARR_LEN (stack)) {
130     int nlen = ARR_LEN (stack) * 2;
131     ARR_RESIZE (ir_node *, stack, nlen);
132   }
133   stack [tos++] = n;
134   mark_irn_in_stack(n);
135 }
136
137 static INLINE ir_node *
138 pop (void)
139 {
140   ir_node *n = stack[--tos];
141   mark_irn_not_in_stack(n);
142   return n;
143 }
144
145 /* The nodes up to n belong to the current loop.
146    Removes them from the stack and adds them to the current loop. */
147 static INLINE void
148 pop_scc_to_loop (ir_node *n)
149 {
150   ir_node *m;
151
152   /*for (;;) {*/
153   do {
154     m = pop();
155     loop_node_cnt++;
156     set_irn_dfn(m, loop_node_cnt);
157     add_loop_node(current_loop, m);
158     set_irn_loop(m, current_loop);
159     /*    if (m==n) break;*/
160   } while(m != n);
161 }
162
163 /* GL ??? my last son is my grandson???  Removes cfloops with no
164    ir_nodes in them.  Such loops have only another loop as son. (Why
165    can't they have two loops as sons? Does it never get that far? ) */
166 static void close_loop (ir_loop *l)
167 {
168   int last = get_loop_n_elements(l) - 1;
169   loop_element lelement = get_loop_element(l, last);
170   ir_loop *last_son = lelement.son;
171
172   if (get_kind(last_son) == k_ir_loop &&
173       get_loop_n_elements(last_son) == 1) {
174     ir_loop *gson;
175
176     lelement = get_loop_element(last_son, 0);
177     gson = lelement.son;
178     if(get_kind(gson) == k_ir_loop) {
179       loop_element new_last_son;
180
181       gson -> outer_loop = l;
182       new_last_son.son = gson;
183       l -> children[last] = new_last_son;
184     }
185   }
186
187   current_loop = l;
188 }
189
190 /* Removes and unmarks all nodes up to n from the stack.
191    The nodes must be visited once more to assign them to a scc. */
192 static INLINE void
193 pop_scc_unmark_visit (ir_node *n)
194 {
195   ir_node *m = NULL;
196
197   while (m != n) {
198     m = pop();
199     set_irn_visited(m, 0);
200   }
201 }
202
203 /**********************************************************************/
204 /* The loop datastructure.                                           **/
205 /**********************************************************************/
206
207 /* Allocates a new loop as son of current_loop.  Sets current_loop
208    to the new loop and returns the father. */
209 static ir_loop *new_loop (void) {
210   ir_loop *father, *son;
211
212   father = current_loop;
213
214   son = (ir_loop *) obstack_alloc (outermost_ir_graph->obst, sizeof (ir_loop));
215   memset (son, 0, sizeof (ir_loop));
216   son->kind = k_ir_loop;
217   son->children = NEW_ARR_F (loop_element, 0);
218   son->n_nodes = 0;
219   son->n_sons=0;
220   if (father) {
221     son->outer_loop = father;
222     add_loop_son(father, son);
223     son->depth = father->depth+1;
224     if (son->depth > max_loop_depth) max_loop_depth = son->depth;
225   } else {  /* The root loop */
226     son->outer_loop = son;
227     son->depth = 0;
228   }
229
230 #ifdef DEBUG_libfirm
231   son->loop_nr = get_irp_new_node_nr();
232   son->link = NULL;
233 #endif
234
235   current_loop = son;
236   return father;
237 }
238
239 /**********************************************************************/
240 /* Constructing and destructing the loop/backedge information.       **/
241 /**********************************************************************/
242
243 /* Initialization steps. **********************************************/
244
245 static INLINE void
246 init_node (ir_node *n, void *env) {
247   if (is_Block(n))
248     set_irn_link (n, new_scc_info());
249   clear_backedges(n);
250 }
251
252 static INLINE void
253 init_scc_common (void) {
254   current_dfn = 1;
255   loop_node_cnt = 0;
256   init_stack();
257 }
258
259 static INLINE void
260 init_scc (ir_graph *irg) {
261   init_scc_common();
262   irg_walk_graph (irg, init_node, NULL, NULL);
263 }
264
265 static INLINE void
266 init_ip_scc (void) {
267   init_scc_common();
268   cg_walk (init_node, NULL, NULL);
269
270 #if EXPERIMENTAL_CFLOOP_TREE
271   cg_walk (link_to_reg_end, NULL, NULL);
272 #endif
273 }
274
275 /* Condition for breaking the recursion. */
276 static bool is_outermost_StartBlock(ir_node *n) {
277   /* Test whether this is the outermost Start node.  If so
278      recursion must end. */
279   assert(is_Block(n));
280   if ((get_Block_n_cfgpreds(n) == 1)  &&
281       (get_irn_op(skip_Proj(get_Block_cfgpred(n, 0))) == op_Start) &&
282       (get_nodes_block(skip_Proj(get_Block_cfgpred(n, 0))) == n)) {
283     return true;
284   }
285   return false;
286 }
287
288 /** Returns true if n is a loop header, i.e., it is a Block node
289  *  and has predecessors within the cfloop and out of the cfloop.
290  *
291  *  @param root: only needed for assertion.
292  */
293 static bool
294 is_head (ir_node *n, ir_node *root)
295 {
296   int i, arity;
297   int some_outof_loop = 0, some_in_loop = 0;
298
299   assert(is_Block(n));
300
301   if (!is_outermost_StartBlock(n)) {
302     arity = get_irn_arity(n);
303     for (i = 0; i < arity; i++) {
304       ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
305       if (is_backedge(n, i)) continue;
306       if (!irn_is_in_stack(pred)) {
307         some_outof_loop = 1;
308       } else {
309         if (get_irn_uplink(pred) < get_irn_uplink(root))  {
310           DDMN(pred); DDMN(root);
311           assert(get_irn_uplink(pred) >= get_irn_uplink(root));
312         }
313         some_in_loop = 1;
314       }
315     }
316   }
317   return some_outof_loop && some_in_loop;
318 }
319
320
321 /* Returns true if n is possible loop head of an endless loop.
322    I.e., it is a Block, Phi or Filter node and has only predecessors
323    within the loop.
324    @arg root: only needed for assertion. */
325 static bool
326 is_endless_head (ir_node *n, ir_node *root)
327 {
328   int i, arity;
329   int some_outof_loop = 0, some_in_loop = 0;
330
331   assert(is_Block(n));
332   /* Test for legal loop header: Block, Phi, ... */
333   if (!is_outermost_StartBlock(n)) {
334     arity = get_irn_arity(n);
335     for (i = 0; i < arity; i++) {
336       ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
337       assert(pred);
338       if (is_backedge(n, i)) { continue; }
339       if (!irn_is_in_stack(pred)) {
340         some_outof_loop = 1; //printf(" some out of loop ");
341       } else {
342         if(get_irn_uplink(pred) < get_irn_uplink(root)) {
343           DDMN(pred); DDMN(root);
344           assert(get_irn_uplink(pred) >= get_irn_uplink(root));
345         }
346         some_in_loop = 1;
347       }
348     }
349   }
350   return !some_outof_loop && some_in_loop;
351 }
352
353 /* Returns index of the predecessor with the smallest dfn number
354    greater-equal than limit. */
355 static int
356 smallest_dfn_pred (ir_node *n, int limit)
357 {
358   int i, index = -2, min = -1;
359
360   if (!is_outermost_StartBlock(n)) {
361     int arity = get_irn_arity(n);
362     for (i = 0; i < arity; i++) {
363       ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
364       if (is_backedge(n, i) || !irn_is_in_stack(pred)) continue;
365       if (get_irn_dfn(pred) >= limit && (min == -1 || get_irn_dfn(pred) < min)) {
366         index = i;
367         min = get_irn_dfn(pred);
368       }
369     }
370   }
371   return index;
372 }
373
374 /* Returns index of the predecessor with the largest dfn number. */
375 static int
376 largest_dfn_pred (ir_node *n)
377 {
378   int i, index = -2, max = -1;
379
380   if (!is_outermost_StartBlock(n)) {
381     int arity = get_irn_arity(n);
382     for (i = 0; i < arity; i++) {
383       ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
384       if (is_backedge (n, i) || !irn_is_in_stack(pred)) continue;
385       if (get_irn_dfn(pred) > max) {
386         index = i;
387         max = get_irn_dfn(pred);
388       }
389     }
390   }
391   return index;
392 }
393
394 /* Searches the stack for possible loop heads.  Tests these for backedges.
395    If it finds a head with an unmarked backedge it marks this edge and
396    returns the tail of the loop.
397    If it finds no backedge returns NULL. */
398 static ir_node *
399 find_tail (ir_node *n) {
400   ir_node *m;
401   int i, res_index = -2;
402
403   m = stack[tos-1];  /* tos = top of stack */
404   if (is_head (m, n)) {
405     res_index = smallest_dfn_pred(m, 0);
406     if ((res_index == -2) &&  /* no smallest dfn pred found. */
407         (n ==  m))
408       return NULL;
409   } else {
410     if (m == n) return NULL;
411     for (i = tos-2; i >= 0; --i) {
412
413       m = stack[i];
414       if (is_head (m, n)) {
415         res_index = smallest_dfn_pred (m, get_irn_dfn(m) + 1);
416         if (res_index == -2)  /* no smallest dfn pred found. */
417           res_index = largest_dfn_pred (m);
418
419         if ((m == n) && (res_index == -2)) {
420           i = -1;
421         }
422         break;
423       }
424
425
426       /* We should not walk past our selves on the stack:  The upcoming nodes
427          are not in this loop. We assume a loop not reachable from Start. */
428       if (m == n) {
429         i = -1;
430         break;
431       }
432
433     }
434
435
436     if (i < 0) {
437       /* A dead loop not reachable from Start. */
438       for (i = tos-2; i >= 0; --i) {
439         m = stack[i];
440         if (is_endless_head (m, n)) {
441           res_index = smallest_dfn_pred (m, get_irn_dfn(m) + 1);
442           if (res_index == -2)  /* no smallest dfn pred found. */
443             res_index = largest_dfn_pred (m);
444           break;
445         }
446         if (m == n) { break; }  /* It's not an unreachable loop, either. */
447       }
448       //assert(0 && "no head found on stack");
449     }
450
451   }
452   assert (res_index > -2);
453
454   set_backedge (m, res_index);
455   return is_outermost_StartBlock(n) ? NULL : get_nodes_block(skip_Proj(get_irn_n(m, res_index)));
456 }
457
458 INLINE static int
459 is_outermost_loop(ir_loop *l) {
460   return l == get_loop_outer_loop(l);
461 }
462
463 /*-----------------------------------------------------------*
464  *                   The core algorithm.                     *
465  *-----------------------------------------------------------*/
466
467
468 static void cfscc (ir_node *n) {
469   int i;
470
471   assert(is_Block(n));
472
473   if (irn_visited(n)) return;
474   mark_irn_visited(n);
475
476   /* Initialize the node */
477   set_irn_dfn(n, current_dfn);      /* Depth first number for this node */
478   set_irn_uplink(n, current_dfn);   /* ... is default uplink. */
479   set_irn_loop(n, NULL);
480   current_dfn ++;
481   push(n);
482
483   /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
484      array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
485      so is_backedge does not access array[-1] but correctly returns false! */
486
487   if (!is_outermost_StartBlock(n)) {
488     int arity = get_irn_arity(n);
489
490     for (i = 0; i < arity; i++) {
491       ir_node *m;
492       if (is_backedge(n, i)) continue;
493       m = get_nodes_block(skip_Proj(get_irn_n(n, i)));
494
495       cfscc (m);
496       if (irn_is_in_stack(m)) {
497         /* Uplink of m is smaller if n->m is a backedge.
498            Propagate the uplink to mark the cfloop. */
499         if (get_irn_uplink(m) < get_irn_uplink(n))
500           set_irn_uplink(n, get_irn_uplink(m));
501       }
502     }
503   }
504
505   if (get_irn_dfn(n) == get_irn_uplink(n)) {
506     /* This condition holds for
507        1) the node with the incoming backedge.
508           That is: We found a cfloop!
509        2) Straight line code, because no uplink has been propagated, so the
510           uplink still is the same as the dfn.
511
512        But n might not be a proper cfloop head for the analysis. Proper cfloop
513        heads are Block and Phi nodes. find_tail searches the stack for
514        Block's and Phi's and takes those nodes as cfloop heads for the current
515        cfloop instead and marks the incoming edge as backedge. */
516
517     ir_node *tail = find_tail(n);
518     if (tail) {
519       /* We have a cfloop, that is no straight line code,
520          because we found a cfloop head!
521          Next actions: Open a new cfloop on the cfloop tree and
522                        try to find inner cfloops */
523
524 #if NO_CFLOOPS_WITHOUT_HEAD
525
526       /* This is an adaption of the algorithm from fiasco / optscc to
527        * avoid cfloops without Block or Phi as first node.  This should
528        * severely reduce the number of evaluations of nodes to detect
529        * a fixpoint in the heap analysis.
530        * Further it avoids cfloops without firm nodes that cause errors
531        * in the heap analyses. */
532
533       ir_loop *l;
534       int close;
535       if ((get_loop_n_elements(current_loop) > 0) || (is_outermost_loop(current_loop))) {
536         l = new_loop();
537         close = 1;
538       } else {
539         l = current_loop;
540         close = 0;
541       }
542
543 #else
544
545       ir_loop *l = new_loop();
546
547 #endif
548
549       /* Remove the cfloop from the stack ... */
550       pop_scc_unmark_visit (n);
551
552       /* The current backedge has been marked, that is temporarily eliminated,
553          by find tail. Start the scc algorithm
554          anew on the subgraph thats left (the current cfloop without the backedge)
555          in order to find more inner cfloops. */
556
557       cfscc (tail);
558
559       assert (irn_visited(n));
560 #if NO_CFLOOPS_WITHOUT_HEAD
561       if (close)
562 #endif
563         close_loop(l);
564     }
565     else
566       {
567         /* AS: No cfloop head was found, that is we have straightline code.
568                Pop all nodes from the stack to the current cfloop. */
569       pop_scc_to_loop(n);
570     }
571   }
572 }
573
574 /* Constructs backedge information for irg. */
575 int construct_cf_backedges(ir_graph *irg) {
576   ir_graph *rem = current_ir_graph;
577   ir_loop *head_rem;
578   ir_node *end = get_irg_end(irg);
579   int i;
580
581   assert(!interprocedural_view &&
582      "use construct_ip_backedges");
583   max_loop_depth = 0;
584
585   current_ir_graph = irg;
586   outermost_ir_graph = irg;
587
588   init_scc(current_ir_graph);
589
590   current_loop = NULL;
591   new_loop();  /* sets current_loop */
592   head_rem = current_loop; /* Just for assertion */
593
594   inc_irg_visited(current_ir_graph);
595
596   cfscc(get_irg_end_block(current_ir_graph));
597   for (i = 0; i < get_End_n_keepalives(end); i++) {
598     ir_node *el = get_End_keepalive(end, i);
599     if (is_Block(el)) cfscc(el);
600   }
601
602   assert(head_rem == current_loop);
603   set_irg_loop(current_ir_graph, current_loop);
604   set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_consistent);
605   assert(get_irg_loop(current_ir_graph)->kind == k_ir_loop);
606
607   current_ir_graph = rem;
608   return max_loop_depth;
609 }
610
611
612 int construct_ip_cf_backedges (void) {
613   ir_graph *rem = current_ir_graph;
614   int rem_ipv = interprocedural_view;
615   int i;
616
617   assert(get_irp_ip_view_state() == ip_view_valid);
618   max_loop_depth = 0;
619   outermost_ir_graph = get_irp_main_irg();
620
621   init_ip_scc();
622
623   current_loop = NULL;
624   new_loop();  /* sets current_loop */
625   interprocedural_view = 1;
626
627   inc_max_irg_visited();
628   for (i = 0; i < get_irp_n_irgs(); i++)
629     set_irg_visited(get_irp_irg(i), get_max_irg_visited());
630
631   /** We have to start the walk at the same nodes as cg_walk. **/
632   /* Walk starting at unreachable procedures. Only these
633    * have End blocks visible in interprocedural view. */
634   for (i = 0; i < get_irp_n_irgs(); i++) {
635     ir_node *sb;
636     current_ir_graph = get_irp_irg(i);
637
638     sb = get_irg_start_block(current_ir_graph);
639
640     if ((get_Block_n_cfgpreds(sb) > 1) ||
641         (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
642
643     cfscc(get_irg_end_block(current_ir_graph));
644   }
645
646   /* Check whether we walked all procedures: there could be procedures
647      with cyclic calls but no call from the outside. */
648   for (i = 0; i < get_irp_n_irgs(); i++) {
649     ir_node *sb;
650     current_ir_graph = get_irp_irg(i);
651
652     /* Test start block: if inner procedure end and end block are not
653      * visible and therefore not marked. */
654     sb = get_irg_start_block(current_ir_graph);
655     if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) cfscc(sb);
656   }
657
658   /* Walk all endless cfloops in inner procedures.
659    * We recognize an inner procedure if the End node is not visited. */
660   for (i = 0; i < get_irp_n_irgs(); i++) {
661     ir_node *e;
662     current_ir_graph = get_irp_irg(i);
663
664     e = get_irg_end(current_ir_graph);
665     if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
666       int j;
667       /* Don't visit the End node. */
668       for (j = 0; j < get_End_n_keepalives(e); j++) {
669         ir_node *el = get_End_keepalive(e, j);
670         if (is_Block(el)) cfscc(el);
671       }
672     }
673   }
674
675   set_irg_loop(outermost_ir_graph, current_loop);
676   set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_ip_consistent);
677   assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
678
679   current_ir_graph = rem;
680   interprocedural_view = rem_ipv;
681   return max_loop_depth;
682 }
683
684
685 static void reset_backedges(ir_node *n) {
686   assert(is_Block(n));
687   int rem = interprocedural_view;
688   interprocedural_view = 1;
689   clear_backedges(n);
690   interprocedural_view = 0;
691   clear_backedges(n);
692   interprocedural_view = rem;
693 }
694
695 static void loop_reset_backedges(ir_loop *l) {
696   int i;
697   reset_backedges(get_loop_node(l, 0));
698   for (i = 0; i < get_loop_n_nodes(l); ++i)
699     set_irn_loop(get_loop_node(l, i), NULL);
700   for (i = 0; i < get_loop_n_sons(l); ++i) {
701     loop_reset_backedges(get_loop_son(l, i));
702   }
703 }
704
705 /* Removes all cfloop information.
706    Resets all backedges */
707 void free_cfloop_information(ir_graph *irg) {
708   if (get_irg_loop(irg))
709     loop_reset_backedges(get_irg_loop(irg));
710   set_irg_loop(irg, NULL);
711   set_irg_loopinfo_state(current_ir_graph, loopinfo_none);
712   /* We cannot free the cfloop nodes, they are on the obstack. */
713 }
714
715
716 void free_all_cfloop_information (void) {
717   int i;
718   int rem = interprocedural_view;
719   interprocedural_view = 1;  /* To visit all filter nodes */
720   for (i = 0; i < get_irp_n_irgs(); i++) {
721     free_cfloop_information(get_irp_irg(i));
722   }
723   interprocedural_view = rem;
724 }