OSDN Git Service

PR c++/45399
[pf3gnuchains/gcc-fork.git] / gcc / graphite-scop-detection.c
1 /* Detection of Static Control Parts (SCoP) for Graphite.
2    Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3    Contributed by Sebastian Pop <sebastian.pop@amd.com> and
4    Tobias Grosser <grosser@fim.uni-passau.de>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree-flow.h"
26 #include "cfgloop.h"
27 #include "tree-chrec.h"
28 #include "tree-data-ref.h"
29 #include "tree-scalar-evolution.h"
30 #include "tree-pass.h"
31 #include "sese.h"
32
33 #ifdef HAVE_cloog
34 #include "ppl_c.h"
35 #include "graphite-ppl.h"
36 #include "graphite-poly.h"
37 #include "graphite-scop-detection.h"
38
39 /* The type of the analyzed basic block.  */
40
41 typedef enum gbb_type {
42   GBB_UNKNOWN,
43   GBB_LOOP_SING_EXIT_HEADER,
44   GBB_LOOP_MULT_EXIT_HEADER,
45   GBB_LOOP_EXIT,
46   GBB_COND_HEADER,
47   GBB_SIMPLE,
48   GBB_LAST
49 } gbb_type;
50
51 /* Detect the type of BB.  Loop headers are only marked, if they are
52    new.  This means their loop_father is different to LAST_LOOP.
53    Otherwise they are treated like any other bb and their type can be
54    any other type.  */
55
56 static gbb_type
57 get_bb_type (basic_block bb, struct loop *last_loop)
58 {
59   VEC (basic_block, heap) *dom;
60   int nb_dom, nb_suc;
61   struct loop *loop = bb->loop_father;
62
63   /* Check, if we entry into a new loop. */
64   if (loop != last_loop)
65     {
66       if (single_exit (loop) != NULL)
67         return GBB_LOOP_SING_EXIT_HEADER;
68       else if (loop->num != 0)
69         return GBB_LOOP_MULT_EXIT_HEADER;
70       else
71         return GBB_COND_HEADER;
72     }
73
74   dom = get_dominated_by (CDI_DOMINATORS, bb);
75   nb_dom = VEC_length (basic_block, dom);
76   VEC_free (basic_block, heap, dom);
77
78   if (nb_dom == 0)
79     return GBB_LAST;
80
81   nb_suc = VEC_length (edge, bb->succs);
82
83   if (nb_dom == 1 && nb_suc == 1)
84     return GBB_SIMPLE;
85
86   return GBB_COND_HEADER;
87 }
88
89 /* A SCoP detection region, defined using bbs as borders.
90
91    All control flow touching this region, comes in passing basic_block
92    ENTRY and leaves passing basic_block EXIT.  By using bbs instead of
93    edges for the borders we are able to represent also regions that do
94    not have a single entry or exit edge.
95
96    But as they have a single entry basic_block and a single exit
97    basic_block, we are able to generate for every sd_region a single
98    entry and exit edge.
99
100    1   2
101     \ /
102      3  <- entry
103      |
104      4
105     / \                 This region contains: {3, 4, 5, 6, 7, 8}
106    5   6
107    |   |
108    7   8
109     \ /
110      9  <- exit  */
111
112
113 typedef struct sd_region_p
114 {
115   /* The entry bb dominates all bbs in the sd_region.  It is part of
116      the region.  */
117   basic_block entry;
118
119   /* The exit bb postdominates all bbs in the sd_region, but is not
120      part of the region.  */
121   basic_block exit;
122 } sd_region;
123
124 DEF_VEC_O(sd_region);
125 DEF_VEC_ALLOC_O(sd_region, heap);
126
127
128 /* Moves the scops from SOURCE to TARGET and clean up SOURCE.  */
129
130 static void
131 move_sd_regions (VEC (sd_region, heap) **source,
132                  VEC (sd_region, heap) **target)
133 {
134   sd_region *s;
135   int i;
136
137   FOR_EACH_VEC_ELT (sd_region, *source, i, s)
138     VEC_safe_push (sd_region, heap, *target, s);
139
140   VEC_free (sd_region, heap, *source);
141 }
142
143 /* Something like "n * m" is not allowed.  */
144
145 static bool
146 graphite_can_represent_init (tree e)
147 {
148   switch (TREE_CODE (e))
149     {
150     case POLYNOMIAL_CHREC:
151       return graphite_can_represent_init (CHREC_LEFT (e))
152         && graphite_can_represent_init (CHREC_RIGHT (e));
153
154     case MULT_EXPR:
155       if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
156         return graphite_can_represent_init (TREE_OPERAND (e, 0))
157           && host_integerp (TREE_OPERAND (e, 1), 0);
158       else
159         return graphite_can_represent_init (TREE_OPERAND (e, 1))
160           && host_integerp (TREE_OPERAND (e, 0), 0);
161
162     case PLUS_EXPR:
163     case POINTER_PLUS_EXPR:
164     case MINUS_EXPR:
165       return graphite_can_represent_init (TREE_OPERAND (e, 0))
166         && graphite_can_represent_init (TREE_OPERAND (e, 1));
167
168     case NEGATE_EXPR:
169     case BIT_NOT_EXPR:
170     CASE_CONVERT:
171     case NON_LVALUE_EXPR:
172       return graphite_can_represent_init (TREE_OPERAND (e, 0));
173
174    default:
175      break;
176     }
177
178   return true;
179 }
180
181 /* Return true when SCEV can be represented in the polyhedral model.
182
183    An expression can be represented, if it can be expressed as an
184    affine expression.  For loops (i, j) and parameters (m, n) all
185    affine expressions are of the form:
186
187    x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
188
189    1 i + 20 j + (-2) m + 25
190
191    Something like "i * n" or "n * m" is not allowed.  */
192
193 static bool
194 graphite_can_represent_scev (tree scev)
195 {
196   if (chrec_contains_undetermined (scev))
197     return false;
198
199   switch (TREE_CODE (scev))
200     {
201     case PLUS_EXPR:
202     case MINUS_EXPR:
203       return graphite_can_represent_scev (TREE_OPERAND (scev, 0))
204         && graphite_can_represent_scev (TREE_OPERAND (scev, 1));
205
206     case MULT_EXPR:
207       return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0)))
208         && !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1)))
209         && !(chrec_contains_symbols (TREE_OPERAND (scev, 0))
210              && chrec_contains_symbols (TREE_OPERAND (scev, 1)))
211         && graphite_can_represent_init (scev)
212         && graphite_can_represent_scev (TREE_OPERAND (scev, 0))
213         && graphite_can_represent_scev (TREE_OPERAND (scev, 1));
214
215     case POLYNOMIAL_CHREC:
216       /* Check for constant strides.  With a non constant stride of
217          'n' we would have a value of 'iv * n'.  Also check that the
218          initial value can represented: for example 'n * m' cannot be
219          represented.  */
220       if (!evolution_function_right_is_integer_cst (scev)
221           || !graphite_can_represent_init (scev))
222         return false;
223
224     default:
225       break;
226     }
227
228   /* Only affine functions can be represented.  */
229   if (!scev_is_linear_expression (scev))
230     return false;
231
232   return true;
233 }
234
235
236 /* Return true when EXPR can be represented in the polyhedral model.
237
238    This means an expression can be represented, if it is linear with
239    respect to the loops and the strides are non parametric.
240    LOOP is the place where the expr will be evaluated.  SCOP_ENTRY defines the
241    entry of the region we analyse.  */
242
243 static bool
244 graphite_can_represent_expr (basic_block scop_entry, loop_p loop,
245                              tree expr)
246 {
247   tree scev = analyze_scalar_evolution (loop, expr);
248
249   scev = instantiate_scev (scop_entry, loop, scev);
250
251   return graphite_can_represent_scev (scev);
252 }
253
254 /* Return true if the data references of STMT can be represented by
255    Graphite.  */
256
257 static bool
258 stmt_has_simple_data_refs_p (loop_p outermost_loop, gimple stmt)
259 {
260   data_reference_p dr;
261   unsigned i;
262   int j;
263   bool res = true;
264   VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
265
266   graphite_find_data_references_in_stmt (outermost_loop,
267                                          loop_containing_stmt (stmt),
268                                          stmt, &drs);
269
270   FOR_EACH_VEC_ELT (data_reference_p, drs, j, dr)
271     for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
272       if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i)))
273         {
274           res = false;
275           goto done;
276         }
277
278  done:
279   free_data_refs (drs);
280   return res;
281 }
282
283 /* Return true only when STMT is simple enough for being handled by
284    Graphite.  This depends on SCOP_ENTRY, as the parameters are
285    initialized relatively to this basic block, the linear functions
286    are initialized to OUTERMOST_LOOP and BB is the place where we try
287    to evaluate the STMT.  */
288
289 static bool
290 stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop,
291                         gimple stmt, basic_block bb)
292 {
293   loop_p loop = bb->loop_father;
294
295   gcc_assert (scop_entry);
296
297   /* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
298      Calls have side-effects, except those to const or pure
299      functions.  */
300   if (gimple_has_volatile_ops (stmt)
301       || (gimple_code (stmt) == GIMPLE_CALL
302           && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
303       || (gimple_code (stmt) == GIMPLE_ASM))
304     return false;
305
306   if (is_gimple_debug (stmt))
307     return true;
308
309   if (!stmt_has_simple_data_refs_p (outermost_loop, stmt))
310     return false;
311
312   switch (gimple_code (stmt))
313     {
314     case GIMPLE_RETURN:
315     case GIMPLE_LABEL:
316       return true;
317
318     case GIMPLE_COND:
319       {
320         tree op;
321         ssa_op_iter op_iter;
322         enum tree_code code = gimple_cond_code (stmt);
323
324         /* We can handle all binary comparisons.  Inequalities are
325            also supported as they can be represented with union of
326            polyhedra.  */
327         if (!(code == LT_EXPR
328               || code == GT_EXPR
329               || code == LE_EXPR
330               || code == GE_EXPR
331               || code == EQ_EXPR
332               || code == NE_EXPR))
333           return false;
334
335         FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
336           if (!graphite_can_represent_expr (scop_entry, loop, op)
337               /* We can not handle REAL_TYPE. Failed for pr39260.  */
338               || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
339             return false;
340
341         return true;
342       }
343
344     case GIMPLE_ASSIGN:
345     case GIMPLE_CALL:
346       return true;
347
348     default:
349       /* These nodes cut a new scope.  */
350       return false;
351     }
352
353   return false;
354 }
355
356 /* Returns the statement of BB that contains a harmful operation: that
357    can be a function call with side effects, the induction variables
358    are not linear with respect to SCOP_ENTRY, etc.  The current open
359    scop should end before this statement.  The evaluation is limited using
360    OUTERMOST_LOOP as outermost loop that may change.  */
361
362 static gimple
363 harmful_stmt_in_bb (basic_block scop_entry, loop_p outer_loop, basic_block bb)
364 {
365   gimple_stmt_iterator gsi;
366
367   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
368     if (!stmt_simple_for_scop_p (scop_entry, outer_loop, gsi_stmt (gsi), bb))
369       return gsi_stmt (gsi);
370
371   return NULL;
372 }
373
374 /* Return true if LOOP can be represented in the polyhedral
375    representation.  This is evaluated taking SCOP_ENTRY and
376    OUTERMOST_LOOP in mind.  */
377
378 static bool
379 graphite_can_represent_loop (basic_block scop_entry, loop_p loop)
380 {
381   tree niter = number_of_latch_executions (loop);
382
383   /* Number of iterations unknown.  */
384   if (chrec_contains_undetermined (niter))
385     return false;
386
387   /* Number of iterations not affine.  */
388   if (!graphite_can_represent_expr (scop_entry, loop, niter))
389     return false;
390
391   return true;
392 }
393
394 /* Store information needed by scopdet_* functions.  */
395
396 struct scopdet_info
397 {
398   /* Exit of the open scop would stop if the current BB is harmful.  */
399   basic_block exit;
400
401   /* Where the next scop would start if the current BB is harmful.  */
402   basic_block next;
403
404   /* The bb or one of its children contains open loop exits.  That means
405      loop exit nodes that are not surrounded by a loop dominated by bb.  */
406   bool exits;
407
408   /* The bb or one of its children contains only structures we can handle.  */
409   bool difficult;
410 };
411
412 static struct scopdet_info build_scops_1 (basic_block, loop_p,
413                                           VEC (sd_region, heap) **, loop_p);
414
415 /* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB
416    to SCOPS.  TYPE is the gbb_type of BB.  */
417
418 static struct scopdet_info
419 scopdet_basic_block_info (basic_block bb, loop_p outermost_loop,
420                           VEC (sd_region, heap) **scops, gbb_type type)
421 {
422   loop_p loop = bb->loop_father;
423   struct scopdet_info result;
424   gimple stmt;
425
426   /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps.  */
427   basic_block entry_block = ENTRY_BLOCK_PTR;
428   stmt = harmful_stmt_in_bb (entry_block, outermost_loop, bb);
429   result.difficult = (stmt != NULL);
430   result.exit = NULL;
431
432   switch (type)
433     {
434     case GBB_LAST:
435       result.next = NULL;
436       result.exits = false;
437
438       /* Mark bbs terminating a SESE region difficult, if they start
439          a condition.  */
440       if (!single_succ_p (bb))
441         result.difficult = true;
442       else
443         result.exit = single_succ (bb);
444
445       break;
446
447     case GBB_SIMPLE:
448       result.next = single_succ (bb);
449       result.exits = false;
450       result.exit = single_succ (bb);
451       break;
452
453     case GBB_LOOP_SING_EXIT_HEADER:
454       {
455         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
456         struct scopdet_info sinfo;
457         edge exit_e = single_exit (loop);
458
459         sinfo = build_scops_1 (bb, outermost_loop, &regions, loop);
460
461         if (!graphite_can_represent_loop (entry_block, loop))
462           result.difficult = true;
463
464         result.difficult |= sinfo.difficult;
465
466         /* Try again with another loop level.  */
467         if (result.difficult
468             && loop_depth (outermost_loop) + 1 == loop_depth (loop))
469           {
470             outermost_loop = loop;
471
472             VEC_free (sd_region, heap, regions);
473             regions = VEC_alloc (sd_region, heap, 3);
474
475             sinfo = scopdet_basic_block_info (bb, outermost_loop, scops, type);
476
477             result = sinfo;
478             result.difficult = true;
479
480             if (sinfo.difficult)
481               move_sd_regions (&regions, scops);
482             else
483               {
484                 sd_region open_scop;
485                 open_scop.entry = bb;
486                 open_scop.exit = exit_e->dest;
487                 VEC_safe_push (sd_region, heap, *scops, &open_scop);
488                 VEC_free (sd_region, heap, regions);
489               }
490           }
491         else
492           {
493             result.exit = exit_e->dest;
494             result.next = exit_e->dest;
495
496             /* If we do not dominate result.next, remove it.  It's either
497                the EXIT_BLOCK_PTR, or another bb dominates it and will
498                call the scop detection for this bb.  */
499             if (!dominated_by_p (CDI_DOMINATORS, result.next, bb))
500               result.next = NULL;
501
502             if (exit_e->src->loop_father != loop)
503               result.next = NULL;
504
505             result.exits = false;
506
507             if (result.difficult)
508               move_sd_regions (&regions, scops);
509             else
510               VEC_free (sd_region, heap, regions);
511           }
512
513         break;
514       }
515
516     case GBB_LOOP_MULT_EXIT_HEADER:
517       {
518         /* XXX: For now we just do not join loops with multiple exits.  If the
519            exits lead to the same bb it may be possible to join the loop.  */
520         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
521         VEC (edge, heap) *exits = get_loop_exit_edges (loop);
522         edge e;
523         int i;
524         build_scops_1 (bb, loop, &regions, loop);
525
526         /* Scan the code dominated by this loop.  This means all bbs, that are
527            are dominated by a bb in this loop, but are not part of this loop.
528
529            The easiest case:
530              - The loop exit destination is dominated by the exit sources.
531
532            TODO: We miss here the more complex cases:
533                   - The exit destinations are dominated by another bb inside
534                     the loop.
535                   - The loop dominates bbs, that are not exit destinations.  */
536         FOR_EACH_VEC_ELT (edge, exits, i, e)
537           if (e->src->loop_father == loop
538               && dominated_by_p (CDI_DOMINATORS, e->dest, e->src))
539             {
540               if (loop_outer (outermost_loop))
541                 outermost_loop = loop_outer (outermost_loop);
542
543               /* Pass loop_outer to recognize e->dest as loop header in
544                  build_scops_1.  */
545               if (e->dest->loop_father->header == e->dest)
546                 build_scops_1 (e->dest, outermost_loop, &regions,
547                                loop_outer (e->dest->loop_father));
548               else
549                 build_scops_1 (e->dest, outermost_loop, &regions,
550                                e->dest->loop_father);
551             }
552
553         result.next = NULL;
554         result.exit = NULL;
555         result.difficult = true;
556         result.exits = false;
557         move_sd_regions (&regions, scops);
558         VEC_free (edge, heap, exits);
559         break;
560       }
561     case GBB_COND_HEADER:
562       {
563         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
564         struct scopdet_info sinfo;
565         VEC (basic_block, heap) *dominated;
566         int i;
567         basic_block dom_bb;
568         basic_block last_exit = NULL;
569         edge e;
570         result.exits = false;
571
572         /* First check the successors of BB, and check if it is
573            possible to join the different branches.  */
574         FOR_EACH_VEC_ELT (edge, bb->succs, i, e)
575           {
576             /* Ignore loop exits.  They will be handled after the loop
577                body.  */
578             if (loop_exits_to_bb_p (loop, e->dest))
579               {
580                 result.exits = true;
581                 continue;
582               }
583
584             /* Do not follow edges that lead to the end of the
585                conditions block.  For example, in
586
587                |   0
588                |  /|\
589                | 1 2 |
590                | | | |
591                | 3 4 |
592                |  \|/
593                |   6
594
595                the edge from 0 => 6.  Only check if all paths lead to
596                the same node 6.  */
597
598             if (!single_pred_p (e->dest))
599               {
600                 /* Check, if edge leads directly to the end of this
601                    condition.  */
602                 if (!last_exit)
603                   last_exit = e->dest;
604
605                 if (e->dest != last_exit)
606                   result.difficult = true;
607
608                 continue;
609               }
610
611             if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
612               {
613                 result.difficult = true;
614                 continue;
615               }
616
617             sinfo = build_scops_1 (e->dest, outermost_loop, &regions, loop);
618
619             result.exits |= sinfo.exits;
620             result.difficult |= sinfo.difficult;
621
622             /* Checks, if all branches end at the same point.
623                If that is true, the condition stays joinable.
624                Have a look at the example above.  */
625             if (sinfo.exit)
626               {
627                 if (!last_exit)
628                   last_exit = sinfo.exit;
629
630                 if (sinfo.exit != last_exit)
631                   result.difficult = true;
632               }
633             else
634               result.difficult = true;
635           }
636
637         if (!last_exit)
638           result.difficult = true;
639
640         /* Join the branches of the condition if possible.  */
641         if (!result.exits && !result.difficult)
642           {
643             /* Only return a next pointer if we dominate this pointer.
644                Otherwise it will be handled by the bb dominating it.  */
645             if (dominated_by_p (CDI_DOMINATORS, last_exit, bb)
646                 && last_exit != bb)
647               result.next = last_exit;
648             else
649               result.next = NULL;
650
651             result.exit = last_exit;
652
653             VEC_free (sd_region, heap, regions);
654             break;
655           }
656
657         /* Scan remaining bbs dominated by BB.  */
658         dominated = get_dominated_by (CDI_DOMINATORS, bb);
659
660         FOR_EACH_VEC_ELT (basic_block, dominated, i, dom_bb)
661           {
662             /* Ignore loop exits: they will be handled after the loop body.  */
663             if (loop_depth (find_common_loop (loop, dom_bb->loop_father))
664                 < loop_depth (loop))
665               {
666                 result.exits = true;
667                 continue;
668               }
669
670             /* Ignore the bbs processed above.  */
671             if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
672               continue;
673
674             if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
675               sinfo = build_scops_1 (dom_bb, outermost_loop, &regions,
676                                      loop_outer (loop));
677             else
678               sinfo = build_scops_1 (dom_bb, outermost_loop, &regions, loop);
679
680             result.exits |= sinfo.exits;
681             result.difficult = true;
682             result.exit = NULL;
683           }
684
685         VEC_free (basic_block, heap, dominated);
686
687         result.next = NULL;
688         move_sd_regions (&regions, scops);
689
690         break;
691       }
692
693     default:
694       gcc_unreachable ();
695     }
696
697   return result;
698 }
699
700 /* Starting from CURRENT we walk the dominance tree and add new sd_regions to
701    SCOPS. The analyse if a sd_region can be handled is based on the value
702    of OUTERMOST_LOOP. Only loops inside OUTERMOST loops may change.  LOOP
703    is the loop in which CURRENT is handled.
704
705    TODO: These functions got a little bit big. They definitely should be cleaned
706          up.  */
707
708 static struct scopdet_info
709 build_scops_1 (basic_block current, loop_p outermost_loop,
710                VEC (sd_region, heap) **scops, loop_p loop)
711 {
712   bool in_scop = false;
713   sd_region open_scop;
714   struct scopdet_info sinfo;
715
716   /* Initialize result.  */
717   struct scopdet_info result;
718   result.exits = false;
719   result.difficult = false;
720   result.next = NULL;
721   result.exit = NULL;
722   open_scop.entry = NULL;
723   open_scop.exit = NULL;
724   sinfo.exit = NULL;
725
726   /* Loop over the dominance tree.  If we meet a difficult bb, close
727      the current SCoP.  Loop and condition header start a new layer,
728      and can only be added if all bbs in deeper layers are simple.  */
729   while (current != NULL)
730     {
731       sinfo = scopdet_basic_block_info (current, outermost_loop, scops,
732                                         get_bb_type (current, loop));
733
734       if (!in_scop && !(sinfo.exits || sinfo.difficult))
735         {
736           open_scop.entry = current;
737           open_scop.exit = NULL;
738           in_scop = true;
739         }
740       else if (in_scop && (sinfo.exits || sinfo.difficult))
741         {
742           open_scop.exit = current;
743           VEC_safe_push (sd_region, heap, *scops, &open_scop);
744           in_scop = false;
745         }
746
747       result.difficult |= sinfo.difficult;
748       result.exits |= sinfo.exits;
749
750       current = sinfo.next;
751     }
752
753   /* Try to close open_scop, if we are still in an open SCoP.  */
754   if (in_scop)
755     {
756       open_scop.exit = sinfo.exit;
757       gcc_assert (open_scop.exit);
758       VEC_safe_push (sd_region, heap, *scops, &open_scop);
759     }
760
761   result.exit = sinfo.exit;
762   return result;
763 }
764
765 /* Checks if a bb is contained in REGION.  */
766
767 static bool
768 bb_in_sd_region (basic_block bb, sd_region *region)
769 {
770   return bb_in_region (bb, region->entry, region->exit);
771 }
772
773 /* Returns the single entry edge of REGION, if it does not exits NULL.  */
774
775 static edge
776 find_single_entry_edge (sd_region *region)
777 {
778   edge e;
779   edge_iterator ei;
780   edge entry = NULL;
781
782   FOR_EACH_EDGE (e, ei, region->entry->preds)
783     if (!bb_in_sd_region (e->src, region))
784       {
785         if (entry)
786           {
787             entry = NULL;
788             break;
789           }
790
791         else
792           entry = e;
793       }
794
795   return entry;
796 }
797
798 /* Returns the single exit edge of REGION, if it does not exits NULL.  */
799
800 static edge
801 find_single_exit_edge (sd_region *region)
802 {
803   edge e;
804   edge_iterator ei;
805   edge exit = NULL;
806
807   FOR_EACH_EDGE (e, ei, region->exit->preds)
808     if (bb_in_sd_region (e->src, region))
809       {
810         if (exit)
811           {
812             exit = NULL;
813             break;
814           }
815
816         else
817           exit = e;
818       }
819
820   return exit;
821 }
822
823 /* Create a single entry edge for REGION.  */
824
825 static void
826 create_single_entry_edge (sd_region *region)
827 {
828   if (find_single_entry_edge (region))
829     return;
830
831   /* There are multiple predecessors for bb_3
832
833   |  1  2
834   |  | /
835   |  |/
836   |  3  <- entry
837   |  |\
838   |  | |
839   |  4 ^
840   |  | |
841   |  |/
842   |  5
843
844   There are two edges (1->3, 2->3), that point from outside into the region,
845   and another one (5->3), a loop latch, lead to bb_3.
846
847   We split bb_3.
848
849   |  1  2
850   |  | /
851   |  |/
852   |3.0
853   |  |\     (3.0 -> 3.1) = single entry edge
854   |3.1 |        <- entry
855   |  | |
856   |  | |
857   |  4 ^
858   |  | |
859   |  |/
860   |  5
861
862   If the loop is part of the SCoP, we have to redirect the loop latches.
863
864   |  1  2
865   |  | /
866   |  |/
867   |3.0
868   |  |      (3.0 -> 3.1) = entry edge
869   |3.1          <- entry
870   |  |\
871   |  | |
872   |  4 ^
873   |  | |
874   |  |/
875   |  5  */
876
877   if (region->entry->loop_father->header != region->entry
878       || dominated_by_p (CDI_DOMINATORS,
879                          loop_latch_edge (region->entry->loop_father)->src,
880                          region->exit))
881     {
882       edge forwarder = split_block_after_labels (region->entry);
883       region->entry = forwarder->dest;
884     }
885   else
886     /* This case is never executed, as the loop headers seem always to have a
887        single edge pointing from outside into the loop.  */
888     gcc_unreachable ();
889
890   gcc_checking_assert (find_single_entry_edge (region));
891 }
892
893 /* Check if the sd_region, mentioned in EDGE, has no exit bb.  */
894
895 static bool
896 sd_region_without_exit (edge e)
897 {
898   sd_region *r = (sd_region *) e->aux;
899
900   if (r)
901     return r->exit == NULL;
902   else
903     return false;
904 }
905
906 /* Create a single exit edge for REGION.  */
907
908 static void
909 create_single_exit_edge (sd_region *region)
910 {
911   edge e;
912   edge_iterator ei;
913   edge forwarder = NULL;
914   basic_block exit;
915
916   /* We create a forwarder bb (5) for all edges leaving this region
917      (3->5, 4->5).  All other edges leading to the same bb, are moved
918      to a new bb (6).  If these edges where part of another region (2->5)
919      we update the region->exit pointer, of this region.
920
921      To identify which edge belongs to which region we depend on the e->aux
922      pointer in every edge.  It points to the region of the edge or to NULL,
923      if the edge is not part of any region.
924
925      1 2 3 4    1->5 no region,                 2->5 region->exit = 5,
926       \| |/     3->5 region->exit = NULL,       4->5 region->exit = NULL
927         5       <- exit
928
929      changes to
930
931      1 2 3 4    1->6 no region,                         2->6 region->exit = 6,
932      | | \/     3->5 no region,                         4->5 no region,
933      | |  5
934       \| /      5->6 region->exit = 6
935         6
936
937      Now there is only a single exit edge (5->6).  */
938   exit = region->exit;
939   region->exit = NULL;
940   forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL);
941
942   /* Unmark the edges, that are no longer exit edges.  */
943   FOR_EACH_EDGE (e, ei, forwarder->src->preds)
944     if (e->aux)
945       e->aux = NULL;
946
947   /* Mark the new exit edge.  */
948   single_succ_edge (forwarder->src)->aux = region;
949
950   /* Update the exit bb of all regions, where exit edges lead to
951      forwarder->dest.  */
952   FOR_EACH_EDGE (e, ei, forwarder->dest->preds)
953     if (e->aux)
954       ((sd_region *) e->aux)->exit = forwarder->dest;
955
956   gcc_checking_assert (find_single_exit_edge (region));
957 }
958
959 /* Unmark the exit edges of all REGIONS.
960    See comment in "create_single_exit_edge". */
961
962 static void
963 unmark_exit_edges (VEC (sd_region, heap) *regions)
964 {
965   int i;
966   sd_region *s;
967   edge e;
968   edge_iterator ei;
969
970   FOR_EACH_VEC_ELT (sd_region, regions, i, s)
971     FOR_EACH_EDGE (e, ei, s->exit->preds)
972       e->aux = NULL;
973 }
974
975
976 /* Mark the exit edges of all REGIONS.
977    See comment in "create_single_exit_edge". */
978
979 static void
980 mark_exit_edges (VEC (sd_region, heap) *regions)
981 {
982   int i;
983   sd_region *s;
984   edge e;
985   edge_iterator ei;
986
987   FOR_EACH_VEC_ELT (sd_region, regions, i, s)
988     FOR_EACH_EDGE (e, ei, s->exit->preds)
989       if (bb_in_sd_region (e->src, s))
990         e->aux = s;
991 }
992
993 /* Create for all scop regions a single entry and a single exit edge.  */
994
995 static void
996 create_sese_edges (VEC (sd_region, heap) *regions)
997 {
998   int i;
999   sd_region *s;
1000
1001   FOR_EACH_VEC_ELT (sd_region, regions, i, s)
1002     create_single_entry_edge (s);
1003
1004   mark_exit_edges (regions);
1005
1006   FOR_EACH_VEC_ELT (sd_region, regions, i, s)
1007     /* Don't handle multiple edges exiting the function.  */
1008     if (!find_single_exit_edge (s)
1009         && s->exit != EXIT_BLOCK_PTR)
1010       create_single_exit_edge (s);
1011
1012   unmark_exit_edges (regions);
1013
1014   fix_loop_structure (NULL);
1015
1016 #ifdef ENABLE_CHECKING
1017   verify_loop_structure ();
1018   verify_dominators (CDI_DOMINATORS);
1019   verify_ssa (false);
1020 #endif
1021 }
1022
1023 /* Create graphite SCoPs from an array of scop detection REGIONS.  */
1024
1025 static void
1026 build_graphite_scops (VEC (sd_region, heap) *regions,
1027                       VEC (scop_p, heap) **scops)
1028 {
1029   int i;
1030   sd_region *s;
1031
1032   FOR_EACH_VEC_ELT (sd_region, regions, i, s)
1033     {
1034       edge entry = find_single_entry_edge (s);
1035       edge exit = find_single_exit_edge (s);
1036       scop_p scop;
1037
1038       if (!exit)
1039         continue;
1040
1041       scop = new_scop (new_sese (entry, exit));
1042       VEC_safe_push (scop_p, heap, *scops, scop);
1043
1044       /* Are there overlapping SCoPs?  */
1045 #ifdef ENABLE_CHECKING
1046         {
1047           int j;
1048           sd_region *s2;
1049
1050           FOR_EACH_VEC_ELT (sd_region, regions, j, s2)
1051             if (s != s2)
1052               gcc_assert (!bb_in_sd_region (s->entry, s2));
1053         }
1054 #endif
1055     }
1056 }
1057
1058 /* Returns true when BB contains only close phi nodes.  */
1059
1060 static bool
1061 contains_only_close_phi_nodes (basic_block bb)
1062 {
1063   gimple_stmt_iterator gsi;
1064
1065   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1066     if (gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
1067       return false;
1068
1069   return true;
1070 }
1071
1072 /* Print statistics for SCOP to FILE.  */
1073
1074 static void
1075 print_graphite_scop_statistics (FILE* file, scop_p scop)
1076 {
1077   long n_bbs = 0;
1078   long n_loops = 0;
1079   long n_stmts = 0;
1080   long n_conditions = 0;
1081   long n_p_bbs = 0;
1082   long n_p_loops = 0;
1083   long n_p_stmts = 0;
1084   long n_p_conditions = 0;
1085
1086   basic_block bb;
1087
1088   FOR_ALL_BB (bb)
1089     {
1090       gimple_stmt_iterator psi;
1091       loop_p loop = bb->loop_father;
1092
1093       if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
1094         continue;
1095
1096       n_bbs++;
1097       n_p_bbs += bb->count;
1098
1099       if (VEC_length (edge, bb->succs) > 1)
1100         {
1101           n_conditions++;
1102           n_p_conditions += bb->count;
1103         }
1104
1105       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
1106         {
1107           n_stmts++;
1108           n_p_stmts += bb->count;
1109         }
1110
1111       if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
1112         {
1113           n_loops++;
1114           n_p_loops += bb->count;
1115         }
1116
1117     }
1118
1119   fprintf (file, "\nBefore limit_scops SCoP statistics (");
1120   fprintf (file, "BBS:%ld, ", n_bbs);
1121   fprintf (file, "LOOPS:%ld, ", n_loops);
1122   fprintf (file, "CONDITIONS:%ld, ", n_conditions);
1123   fprintf (file, "STMTS:%ld)\n", n_stmts);
1124   fprintf (file, "\nBefore limit_scops SCoP profiling statistics (");
1125   fprintf (file, "BBS:%ld, ", n_p_bbs);
1126   fprintf (file, "LOOPS:%ld, ", n_p_loops);
1127   fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
1128   fprintf (file, "STMTS:%ld)\n", n_p_stmts);
1129 }
1130
1131 /* Print statistics for SCOPS to FILE.  */
1132
1133 static void
1134 print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
1135 {
1136   int i;
1137   scop_p scop;
1138
1139   FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
1140     print_graphite_scop_statistics (file, scop);
1141 }
1142
1143 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
1144
1145    Example:
1146
1147    for (i      |
1148      {         |
1149        for (j  |  SCoP 1
1150        for (k  |
1151      }         |
1152
1153    * SCoP frontier, as this line is not surrounded by any loop. *
1154
1155    for (l      |  SCoP 2
1156
1157    This is necessary as scalar evolution and parameter detection need a
1158    outermost loop to initialize parameters correctly.
1159
1160    TODO: FIX scalar evolution and parameter detection to allow more flexible
1161          SCoP frontiers.  */
1162
1163 static void
1164 limit_scops (VEC (scop_p, heap) **scops)
1165 {
1166   VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
1167
1168   int i;
1169   scop_p scop;
1170
1171   FOR_EACH_VEC_ELT (scop_p, *scops, i, scop)
1172     {
1173       int j;
1174       loop_p loop;
1175       sese region = SCOP_REGION (scop);
1176       build_sese_loop_nests (region);
1177
1178       FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), j, loop)
1179         if (!loop_in_sese_p (loop_outer (loop), region)
1180             && single_exit (loop))
1181           {
1182             sd_region open_scop;
1183             open_scop.entry = loop->header;
1184             open_scop.exit = single_exit (loop)->dest;
1185
1186             /* This is a hack on top of the limit_scops hack.  The
1187                limit_scops hack should disappear all together.  */
1188             if (single_succ_p (open_scop.exit)
1189                 && contains_only_close_phi_nodes (open_scop.exit))
1190               open_scop.exit = single_succ_edge (open_scop.exit)->dest;
1191
1192             VEC_safe_push (sd_region, heap, regions, &open_scop);
1193           }
1194     }
1195
1196   free_scops (*scops);
1197   *scops = VEC_alloc (scop_p, heap, 3);
1198
1199   create_sese_edges (regions);
1200   build_graphite_scops (regions, scops);
1201   VEC_free (sd_region, heap, regions);
1202 }
1203
1204 /* Returns true when P1 and P2 are close phis with the same
1205    argument.  */
1206
1207 static inline bool
1208 same_close_phi_node (gimple p1, gimple p2)
1209 {
1210   return operand_equal_p (gimple_phi_arg_def (p1, 0),
1211                           gimple_phi_arg_def (p2, 0), 0);
1212 }
1213
1214 /* Remove the close phi node at GSI and replace its rhs with the rhs
1215    of PHI.  */
1216
1217 static void
1218 remove_duplicate_close_phi (gimple phi, gimple_stmt_iterator *gsi)
1219 {
1220   gimple use_stmt;
1221   use_operand_p use_p;
1222   imm_use_iterator imm_iter;
1223   tree res = gimple_phi_result (phi);
1224   tree def = gimple_phi_result (gsi_stmt (*gsi));
1225
1226   gcc_assert (same_close_phi_node (phi, gsi_stmt (*gsi)));
1227
1228   FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1229     {
1230       FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1231         SET_USE (use_p, res);
1232
1233       update_stmt (use_stmt);
1234     }
1235
1236   remove_phi_node (gsi, true);
1237 }
1238
1239 /* Removes all the close phi duplicates from BB.  */
1240
1241 static void
1242 make_close_phi_nodes_unique (basic_block bb)
1243 {
1244   gimple_stmt_iterator psi;
1245
1246   for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1247     {
1248       gimple_stmt_iterator gsi = psi;
1249       gimple phi = gsi_stmt (psi);
1250
1251       /* At this point, PHI should be a close phi in normal form.  */
1252       gcc_assert (gimple_phi_num_args (phi) == 1);
1253
1254       /* Iterate over the next phis and remove duplicates.  */
1255       gsi_next (&gsi);
1256       while (!gsi_end_p (gsi))
1257         if (same_close_phi_node (phi, gsi_stmt (gsi)))
1258           remove_duplicate_close_phi (phi, &gsi);
1259         else
1260           gsi_next (&gsi);
1261     }
1262 }
1263
1264 /* Transforms LOOP to the canonical loop closed SSA form.  */
1265
1266 static void
1267 canonicalize_loop_closed_ssa (loop_p loop)
1268 {
1269   edge e = single_exit (loop);
1270   basic_block bb;
1271
1272   if (!e || e->flags & EDGE_ABNORMAL)
1273     return;
1274
1275   bb = e->dest;
1276
1277   if (VEC_length (edge, bb->preds) == 1)
1278     {
1279       e = split_block_after_labels (bb);
1280       make_close_phi_nodes_unique (e->src);
1281     }
1282   else
1283     {
1284       gimple_stmt_iterator psi;
1285       basic_block close = split_edge (e);
1286
1287       e = single_succ_edge (close);
1288
1289       for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1290         {
1291           gimple phi = gsi_stmt (psi);
1292           unsigned i;
1293
1294           for (i = 0; i < gimple_phi_num_args (phi); i++)
1295             if (gimple_phi_arg_edge (phi, i) == e)
1296               {
1297                 tree res, arg = gimple_phi_arg_def (phi, i);
1298                 use_operand_p use_p;
1299                 gimple close_phi;
1300
1301                 if (TREE_CODE (arg) != SSA_NAME)
1302                   continue;
1303
1304                 close_phi = create_phi_node (arg, close);
1305                 res = create_new_def_for (gimple_phi_result (close_phi),
1306                                           close_phi,
1307                                           gimple_phi_result_ptr (close_phi));
1308                 add_phi_arg (close_phi, arg,
1309                              gimple_phi_arg_edge (close_phi, 0),
1310                              UNKNOWN_LOCATION);
1311                 use_p = gimple_phi_arg_imm_use_ptr (phi, i);
1312                 replace_exp (use_p, res);
1313                 update_stmt (phi);
1314               }
1315         }
1316
1317       make_close_phi_nodes_unique (close);
1318     }
1319
1320   /* The code above does not properly handle changes in the post dominance
1321      information (yet).  */
1322   free_dominance_info (CDI_POST_DOMINATORS);
1323 }
1324
1325 /* Converts the current loop closed SSA form to a canonical form
1326    expected by the Graphite code generation.
1327
1328    The loop closed SSA form has the following invariant: a variable
1329    defined in a loop that is used outside the loop appears only in the
1330    phi nodes in the destination of the loop exit.  These phi nodes are
1331    called close phi nodes.
1332
1333    The canonical loop closed SSA form contains the extra invariants:
1334
1335    - when the loop contains only one exit, the close phi nodes contain
1336    only one argument.  That implies that the basic block that contains
1337    the close phi nodes has only one predecessor, that is a basic block
1338    in the loop.
1339
1340    - the basic block containing the close phi nodes does not contain
1341    other statements.
1342
1343    - there exist only one phi node per definition in the loop.
1344 */
1345
1346 static void
1347 canonicalize_loop_closed_ssa_form (void)
1348 {
1349   loop_iterator li;
1350   loop_p loop;
1351
1352 #ifdef ENABLE_CHECKING
1353   verify_loop_closed_ssa (true);
1354 #endif
1355
1356   FOR_EACH_LOOP (li, loop, 0)
1357     canonicalize_loop_closed_ssa (loop);
1358
1359   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
1360   update_ssa (TODO_update_ssa);
1361
1362 #ifdef ENABLE_CHECKING
1363   verify_loop_closed_ssa (true);
1364 #endif
1365 }
1366
1367 /* Find Static Control Parts (SCoP) in the current function and pushes
1368    them to SCOPS.  */
1369
1370 void
1371 build_scops (VEC (scop_p, heap) **scops)
1372 {
1373   struct loop *loop = current_loops->tree_root;
1374   VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
1375
1376   canonicalize_loop_closed_ssa_form ();
1377   build_scops_1 (single_succ (ENTRY_BLOCK_PTR), ENTRY_BLOCK_PTR->loop_father,
1378                  &regions, loop);
1379   create_sese_edges (regions);
1380   build_graphite_scops (regions, scops);
1381
1382   if (dump_file && (dump_flags & TDF_DETAILS))
1383     print_graphite_statistics (dump_file, *scops);
1384
1385   limit_scops (scops);
1386   VEC_free (sd_region, heap, regions);
1387
1388   if (dump_file && (dump_flags & TDF_DETAILS))
1389     fprintf (dump_file, "\nnumber of SCoPs: %d\n",
1390              VEC_length (scop_p, *scops));
1391 }
1392
1393 /* Pretty print to FILE all the SCoPs in DOT format and mark them with
1394    different colors.  If there are not enough colors, paint the
1395    remaining SCoPs in gray.
1396
1397    Special nodes:
1398    - "*" after the node number denotes the entry of a SCoP,
1399    - "#" after the node number denotes the exit of a SCoP,
1400    - "()" around the node number denotes the entry or the
1401      exit nodes of the SCOP.  These are not part of SCoP.  */
1402
1403 static void
1404 dot_all_scops_1 (FILE *file, VEC (scop_p, heap) *scops)
1405 {
1406   basic_block bb;
1407   edge e;
1408   edge_iterator ei;
1409   scop_p scop;
1410   const char* color;
1411   int i;
1412
1413   /* Disable debugging while printing graph.  */
1414   int tmp_dump_flags = dump_flags;
1415   dump_flags = 0;
1416
1417   fprintf (file, "digraph all {\n");
1418
1419   FOR_ALL_BB (bb)
1420     {
1421       int part_of_scop = false;
1422
1423       /* Use HTML for every bb label.  So we are able to print bbs
1424          which are part of two different SCoPs, with two different
1425          background colors.  */
1426       fprintf (file, "%d [label=<\n  <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
1427                      bb->index);
1428       fprintf (file, "CELLSPACING=\"0\">\n");
1429
1430       /* Select color for SCoP.  */
1431       FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
1432         {
1433           sese region = SCOP_REGION (scop);
1434           if (bb_in_sese_p (bb, region)
1435               || (SESE_EXIT_BB (region) == bb)
1436               || (SESE_ENTRY_BB (region) == bb))
1437             {
1438               switch (i % 17)
1439                 {
1440                 case 0: /* red */
1441                   color = "#e41a1c";
1442                   break;
1443                 case 1: /* blue */
1444                   color = "#377eb8";
1445                   break;
1446                 case 2: /* green */
1447                   color = "#4daf4a";
1448                   break;
1449                 case 3: /* purple */
1450                   color = "#984ea3";
1451                   break;
1452                 case 4: /* orange */
1453                   color = "#ff7f00";
1454                   break;
1455                 case 5: /* yellow */
1456                   color = "#ffff33";
1457                   break;
1458                 case 6: /* brown */
1459                   color = "#a65628";
1460                   break;
1461                 case 7: /* rose */
1462                   color = "#f781bf";
1463                   break;
1464                 case 8:
1465                   color = "#8dd3c7";
1466                   break;
1467                 case 9:
1468                   color = "#ffffb3";
1469                   break;
1470                 case 10:
1471                   color = "#bebada";
1472                   break;
1473                 case 11:
1474                   color = "#fb8072";
1475                   break;
1476                 case 12:
1477                   color = "#80b1d3";
1478                   break;
1479                 case 13:
1480                   color = "#fdb462";
1481                   break;
1482                 case 14:
1483                   color = "#b3de69";
1484                   break;
1485                 case 15:
1486                   color = "#fccde5";
1487                   break;
1488                 case 16:
1489                   color = "#bc80bd";
1490                   break;
1491                 default: /* gray */
1492                   color = "#999999";
1493                 }
1494
1495               fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color);
1496
1497               if (!bb_in_sese_p (bb, region))
1498                 fprintf (file, " (");
1499
1500               if (bb == SESE_ENTRY_BB (region)
1501                   && bb == SESE_EXIT_BB (region))
1502                 fprintf (file, " %d*# ", bb->index);
1503               else if (bb == SESE_ENTRY_BB (region))
1504                 fprintf (file, " %d* ", bb->index);
1505               else if (bb == SESE_EXIT_BB (region))
1506                 fprintf (file, " %d# ", bb->index);
1507               else
1508                 fprintf (file, " %d ", bb->index);
1509
1510               if (!bb_in_sese_p (bb,region))
1511                 fprintf (file, ")");
1512
1513               fprintf (file, "</TD></TR>\n");
1514               part_of_scop  = true;
1515             }
1516         }
1517
1518       if (!part_of_scop)
1519         {
1520           fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
1521           fprintf (file, " %d </TD></TR>\n", bb->index);
1522         }
1523       fprintf (file, "  </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
1524     }
1525
1526   FOR_ALL_BB (bb)
1527     {
1528       FOR_EACH_EDGE (e, ei, bb->succs)
1529               fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
1530     }
1531
1532   fputs ("}\n\n", file);
1533
1534   /* Enable debugging again.  */
1535   dump_flags = tmp_dump_flags;
1536 }
1537
1538 /* Display all SCoPs using dotty.  */
1539
1540 DEBUG_FUNCTION void
1541 dot_all_scops (VEC (scop_p, heap) *scops)
1542 {
1543   /* When debugging, enable the following code.  This cannot be used
1544      in production compilers because it calls "system".  */
1545 #if 0
1546   int x;
1547   FILE *stream = fopen ("/tmp/allscops.dot", "w");
1548   gcc_assert (stream);
1549
1550   dot_all_scops_1 (stream, scops);
1551   fclose (stream);
1552
1553   x = system ("dotty /tmp/allscops.dot &");
1554 #else
1555   dot_all_scops_1 (stderr, scops);
1556 #endif
1557 }
1558
1559 /* Display all SCoPs using dotty.  */
1560
1561 DEBUG_FUNCTION void
1562 dot_scop (scop_p scop)
1563 {
1564   VEC (scop_p, heap) *scops = NULL;
1565
1566   if (scop)
1567     VEC_safe_push (scop_p, heap, scops, scop);
1568
1569   /* When debugging, enable the following code.  This cannot be used
1570      in production compilers because it calls "system".  */
1571 #if 0
1572   {
1573     int x;
1574     FILE *stream = fopen ("/tmp/allscops.dot", "w");
1575     gcc_assert (stream);
1576
1577     dot_all_scops_1 (stream, scops);
1578     fclose (stream);
1579     x = system ("dotty /tmp/allscops.dot &");
1580   }
1581 #else
1582   dot_all_scops_1 (stderr, scops);
1583 #endif
1584
1585   VEC_free (scop_p, heap, scops);
1586 }
1587
1588 #endif