OSDN Git Service

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