OSDN Git Service

* dwarf2out.c (loc_list_from_tree): Don't call rtl_for_decl_location
[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 (is_gimple_debug (stmt))
376     return true;
377
378   if (!stmt_has_simple_data_refs_p (outermost_loop, stmt))
379     return false;
380
381   switch (gimple_code (stmt))
382     {
383     case GIMPLE_RETURN:
384     case GIMPLE_LABEL:
385       return true;
386
387     case GIMPLE_COND:
388       {
389         tree op;
390         ssa_op_iter op_iter;
391         enum tree_code code = gimple_cond_code (stmt);
392
393         /* We can handle all binary comparisons.  Inequalities are
394            also supported as they can be represented with union of
395            polyhedra.  */
396         if (!(code == LT_EXPR
397               || code == GT_EXPR
398               || code == LE_EXPR
399               || code == GE_EXPR
400               || code == EQ_EXPR
401               || code == NE_EXPR))
402           return false;
403
404         FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
405           if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop,
406                                             op)
407               /* We can not handle REAL_TYPE. Failed for pr39260.  */
408               || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
409             return false;
410
411         return true;
412       }
413
414     case GIMPLE_ASSIGN:
415       {
416         enum tree_code code = gimple_assign_rhs_code (stmt);
417
418         switch (get_gimple_rhs_class (code))
419           {
420           case GIMPLE_UNARY_RHS:
421           case GIMPLE_SINGLE_RHS:
422             return (is_simple_operand (outermost_loop, stmt,
423                                        gimple_assign_lhs (stmt))
424                     && is_simple_operand (outermost_loop, stmt,
425                                           gimple_assign_rhs1 (stmt)));
426
427           case GIMPLE_BINARY_RHS:
428             return (is_simple_operand (outermost_loop, stmt,
429                                        gimple_assign_lhs (stmt))
430                     && is_simple_operand (outermost_loop, stmt,
431                                           gimple_assign_rhs1 (stmt))
432                     && is_simple_operand (outermost_loop, stmt,
433                                           gimple_assign_rhs2 (stmt)));
434
435           case GIMPLE_INVALID_RHS:
436           default:
437             gcc_unreachable ();
438           }
439       }
440
441     case GIMPLE_CALL:
442       {
443         size_t i;
444         size_t n = gimple_call_num_args (stmt);
445         tree lhs = gimple_call_lhs (stmt);
446
447         if (lhs && !is_simple_operand (outermost_loop, stmt, lhs))
448           return false;
449
450         for (i = 0; i < n; i++)
451           if (!is_simple_operand (outermost_loop, stmt,
452                                   gimple_call_arg (stmt, i)))
453             return false;
454
455         return true;
456       }
457
458     default:
459       /* These nodes cut a new scope.  */
460       return false;
461     }
462
463   return false;
464 }
465
466 /* Returns the statement of BB that contains a harmful operation: that
467    can be a function call with side effects, the induction variables
468    are not linear with respect to SCOP_ENTRY, etc.  The current open
469    scop should end before this statement.  The evaluation is limited using
470    OUTERMOST_LOOP as outermost loop that may change.  */
471
472 static gimple
473 harmful_stmt_in_bb (basic_block scop_entry, loop_p outer_loop, basic_block bb)
474 {
475   gimple_stmt_iterator gsi;
476
477   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
478     if (!stmt_simple_for_scop_p (scop_entry, outer_loop, gsi_stmt (gsi), bb))
479       return gsi_stmt (gsi);
480
481   return NULL;
482 }
483
484 /* Return true when it is not possible to represent LOOP in the
485    polyhedral representation.  This is evaluated taking SCOP_ENTRY and
486    OUTERMOST_LOOP in mind.  */
487
488 static bool
489 graphite_can_represent_loop (basic_block scop_entry, loop_p outermost_loop,
490                              loop_p loop)
491 {
492   tree niter = number_of_latch_executions (loop);
493
494   /* Number of iterations unknown.  */
495   if (chrec_contains_undetermined (niter))
496     return false;
497
498   /* Number of iterations not affine.  */
499   if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop, niter))
500     return false;
501
502   return true;
503 }
504
505 /* Store information needed by scopdet_* functions.  */
506
507 struct scopdet_info
508 {
509   /* Exit of the open scop would stop if the current BB is harmful.  */
510   basic_block exit;
511
512   /* Where the next scop would start if the current BB is harmful.  */
513   basic_block next;
514
515   /* The bb or one of its children contains open loop exits.  That means
516      loop exit nodes that are not surrounded by a loop dominated by bb.  */
517   bool exits;
518
519   /* The bb or one of its children contains only structures we can handle.  */
520   bool difficult;
521 };
522
523 static struct scopdet_info build_scops_1 (basic_block, loop_p,
524                                           VEC (sd_region, heap) **, loop_p);
525
526 /* Calculates BB infos. If bb is difficult we add valid SCoPs dominated by BB
527    to SCOPS.  TYPE is the gbb_type of BB.  */
528
529 static struct scopdet_info
530 scopdet_basic_block_info (basic_block bb, loop_p outermost_loop,
531                           VEC (sd_region, heap) **scops, gbb_type type)
532 {
533   loop_p loop = bb->loop_father;
534   struct scopdet_info result;
535   gimple stmt;
536
537   /* XXX: ENTRY_BLOCK_PTR could be optimized in later steps.  */
538   basic_block entry_block = ENTRY_BLOCK_PTR;
539   stmt = harmful_stmt_in_bb (entry_block, outermost_loop, bb);
540   result.difficult = (stmt != NULL);
541   result.exit = NULL;
542
543   switch (type)
544     {
545     case GBB_LAST:
546       result.next = NULL;
547       result.exits = false;
548
549       /* Mark bbs terminating a SESE region difficult, if they start
550          a condition.  */
551       if (!single_succ_p (bb))
552         result.difficult = true;
553       else
554         result.exit = single_succ (bb);
555
556       break;
557
558     case GBB_SIMPLE:
559       result.next = single_succ (bb);
560       result.exits = false;
561       result.exit = single_succ (bb);
562       break;
563
564     case GBB_LOOP_SING_EXIT_HEADER:
565       {
566         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
567         struct scopdet_info sinfo;
568         edge exit_e = single_exit (loop);
569
570         sinfo = build_scops_1 (bb, outermost_loop, &regions, loop);
571
572         if (!graphite_can_represent_loop (entry_block, outermost_loop, loop))
573           result.difficult = true;
574
575         result.difficult |= sinfo.difficult;
576
577         /* Try again with another loop level.  */
578         if (result.difficult
579             && loop_depth (outermost_loop) + 1 == loop_depth (loop))
580           {
581             outermost_loop = loop;
582
583             VEC_free (sd_region, heap, regions);
584             regions = VEC_alloc (sd_region, heap, 3);
585
586             sinfo = scopdet_basic_block_info (bb, outermost_loop, scops, type);
587
588             result = sinfo;
589             result.difficult = true;
590
591             if (sinfo.difficult)
592               move_sd_regions (&regions, scops);
593             else
594               {
595                 sd_region open_scop;
596                 open_scop.entry = bb;
597                 open_scop.exit = exit_e->dest;
598                 VEC_safe_push (sd_region, heap, *scops, &open_scop);
599                 VEC_free (sd_region, heap, regions);
600               }
601           }
602         else
603           {
604             result.exit = exit_e->dest;
605             result.next = exit_e->dest;
606
607             /* If we do not dominate result.next, remove it.  It's either
608                the EXIT_BLOCK_PTR, or another bb dominates it and will
609                call the scop detection for this bb.  */
610             if (!dominated_by_p (CDI_DOMINATORS, result.next, bb))
611               result.next = NULL;
612
613             if (exit_e->src->loop_father != loop)
614               result.next = NULL;
615
616             result.exits = false;
617
618             if (result.difficult)
619               move_sd_regions (&regions, scops);
620             else
621               VEC_free (sd_region, heap, regions);
622           }
623
624         break;
625       }
626
627     case GBB_LOOP_MULT_EXIT_HEADER:
628       {
629         /* XXX: For now we just do not join loops with multiple exits.  If the
630            exits lead to the same bb it may be possible to join the loop.  */
631         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
632         VEC (edge, heap) *exits = get_loop_exit_edges (loop);
633         edge e;
634         int i;
635         build_scops_1 (bb, loop, &regions, loop);
636
637         /* Scan the code dominated by this loop.  This means all bbs, that are
638            are dominated by a bb in this loop, but are not part of this loop.
639
640            The easiest case:
641              - The loop exit destination is dominated by the exit sources.
642
643            TODO: We miss here the more complex cases:
644                   - The exit destinations are dominated by another bb inside
645                     the loop.
646                   - The loop dominates bbs, that are not exit destinations.  */
647         for (i = 0; VEC_iterate (edge, exits, i, e); i++)
648           if (e->src->loop_father == loop
649               && dominated_by_p (CDI_DOMINATORS, e->dest, e->src))
650             {
651               if (loop_outer (outermost_loop))
652                 outermost_loop = loop_outer (outermost_loop);
653
654               /* Pass loop_outer to recognize e->dest as loop header in
655                  build_scops_1.  */
656               if (e->dest->loop_father->header == e->dest)
657                 build_scops_1 (e->dest, outermost_loop, &regions,
658                                loop_outer (e->dest->loop_father));
659               else
660                 build_scops_1 (e->dest, outermost_loop, &regions,
661                                e->dest->loop_father);
662             }
663
664         result.next = NULL;
665         result.exit = NULL;
666         result.difficult = true;
667         result.exits = false;
668         move_sd_regions (&regions, scops);
669         VEC_free (edge, heap, exits);
670         break;
671       }
672     case GBB_COND_HEADER:
673       {
674         VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
675         struct scopdet_info sinfo;
676         VEC (basic_block, heap) *dominated;
677         int i;
678         basic_block dom_bb;
679         basic_block last_exit = NULL;
680         edge e;
681         result.exits = false;
682
683         /* First check the successors of BB, and check if it is
684            possible to join the different branches.  */
685         for (i = 0; VEC_iterate (edge, bb->succs, i, e); i++)
686           {
687             /* Ignore loop exits.  They will be handled after the loop
688                body.  */
689             if (is_loop_exit (loop, e->dest))
690               {
691                 result.exits = true;
692                 continue;
693               }
694
695             /* Do not follow edges that lead to the end of the
696                conditions block.  For example, in
697
698                |   0
699                |  /|\
700                | 1 2 |
701                | | | |
702                | 3 4 |
703                |  \|/
704                |   6
705
706                the edge from 0 => 6.  Only check if all paths lead to
707                the same node 6.  */
708
709             if (!single_pred_p (e->dest))
710               {
711                 /* Check, if edge leads directly to the end of this
712                    condition.  */
713                 if (!last_exit)
714                   last_exit = e->dest;
715
716                 if (e->dest != last_exit)
717                   result.difficult = true;
718
719                 continue;
720               }
721
722             if (!dominated_by_p (CDI_DOMINATORS, e->dest, bb))
723               {
724                 result.difficult = true;
725                 continue;
726               }
727
728             sinfo = build_scops_1 (e->dest, outermost_loop, &regions, loop);
729
730             result.exits |= sinfo.exits;
731             result.difficult |= sinfo.difficult;
732
733             /* Checks, if all branches end at the same point.
734                If that is true, the condition stays joinable.
735                Have a look at the example above.  */
736             if (sinfo.exit)
737               {
738                 if (!last_exit)
739                   last_exit = sinfo.exit;
740
741                 if (sinfo.exit != last_exit)
742                   result.difficult = true;
743               }
744             else
745               result.difficult = true;
746           }
747
748         if (!last_exit)
749           result.difficult = true;
750
751         /* Join the branches of the condition if possible.  */
752         if (!result.exits && !result.difficult)
753           {
754             /* Only return a next pointer if we dominate this pointer.
755                Otherwise it will be handled by the bb dominating it.  */
756             if (dominated_by_p (CDI_DOMINATORS, last_exit, bb)
757                 && last_exit != bb)
758               result.next = last_exit;
759             else
760               result.next = NULL;
761
762             result.exit = last_exit;
763
764             VEC_free (sd_region, heap, regions);
765             break;
766           }
767
768         /* Scan remaining bbs dominated by BB.  */
769         dominated = get_dominated_by (CDI_DOMINATORS, bb);
770
771         for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
772           {
773             /* Ignore loop exits: they will be handled after the loop body.  */
774             if (loop_depth (find_common_loop (loop, dom_bb->loop_father))
775                 < loop_depth (loop))
776               {
777                 result.exits = true;
778                 continue;
779               }
780
781             /* Ignore the bbs processed above.  */
782             if (single_pred_p (dom_bb) && single_pred (dom_bb) == bb)
783               continue;
784
785             if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
786               sinfo = build_scops_1 (dom_bb, outermost_loop, &regions,
787                                      loop_outer (loop));
788             else
789               sinfo = build_scops_1 (dom_bb, outermost_loop, &regions, loop);
790
791             result.exits |= sinfo.exits;
792             result.difficult = true;
793             result.exit = NULL;
794           }
795
796         VEC_free (basic_block, heap, dominated);
797
798         result.next = NULL;
799         move_sd_regions (&regions, scops);
800
801         break;
802       }
803
804     default:
805       gcc_unreachable ();
806     }
807
808   return result;
809 }
810
811 /* Starting from CURRENT we walk the dominance tree and add new sd_regions to
812    SCOPS. The analyse if a sd_region can be handled is based on the value
813    of OUTERMOST_LOOP. Only loops inside OUTERMOST loops may change.  LOOP
814    is the loop in which CURRENT is handled.
815
816    TODO: These functions got a little bit big. They definitely should be cleaned
817          up.  */
818
819 static struct scopdet_info
820 build_scops_1 (basic_block current, loop_p outermost_loop,
821                VEC (sd_region, heap) **scops, loop_p loop)
822 {
823   bool in_scop = false;
824   sd_region open_scop;
825   struct scopdet_info sinfo;
826
827   /* Initialize result.  */
828   struct scopdet_info result;
829   result.exits = false;
830   result.difficult = false;
831   result.next = NULL;
832   result.exit = NULL;
833   open_scop.entry = NULL;
834   open_scop.exit = NULL;
835   sinfo.exit = NULL;
836
837   /* Loop over the dominance tree.  If we meet a difficult bb, close
838      the current SCoP.  Loop and condition header start a new layer,
839      and can only be added if all bbs in deeper layers are simple.  */
840   while (current != NULL)
841     {
842       sinfo = scopdet_basic_block_info (current, outermost_loop, scops,
843                                         get_bb_type (current, loop));
844
845       if (!in_scop && !(sinfo.exits || sinfo.difficult))
846         {
847           open_scop.entry = current;
848           open_scop.exit = NULL;
849           in_scop = true;
850         }
851       else if (in_scop && (sinfo.exits || sinfo.difficult))
852         {
853           open_scop.exit = current;
854           VEC_safe_push (sd_region, heap, *scops, &open_scop);
855           in_scop = false;
856         }
857
858       result.difficult |= sinfo.difficult;
859       result.exits |= sinfo.exits;
860
861       current = sinfo.next;
862     }
863
864   /* Try to close open_scop, if we are still in an open SCoP.  */
865   if (in_scop)
866     {
867       open_scop.exit = sinfo.exit;
868       gcc_assert (open_scop.exit);
869       VEC_safe_push (sd_region, heap, *scops, &open_scop);
870     }
871
872   result.exit = sinfo.exit;
873   return result;
874 }
875
876 /* Checks if a bb is contained in REGION.  */
877
878 static bool
879 bb_in_sd_region (basic_block bb, sd_region *region)
880 {
881   return bb_in_region (bb, region->entry, region->exit);
882 }
883
884 /* Returns the single entry edge of REGION, if it does not exits NULL.  */
885
886 static edge
887 find_single_entry_edge (sd_region *region)
888 {
889   edge e;
890   edge_iterator ei;
891   edge entry = NULL;
892
893   FOR_EACH_EDGE (e, ei, region->entry->preds)
894     if (!bb_in_sd_region (e->src, region))
895       {
896         if (entry)
897           {
898             entry = NULL;
899             break;
900           }
901
902         else
903           entry = e;
904       }
905
906   return entry;
907 }
908
909 /* Returns the single exit edge of REGION, if it does not exits NULL.  */
910
911 static edge
912 find_single_exit_edge (sd_region *region)
913 {
914   edge e;
915   edge_iterator ei;
916   edge exit = NULL;
917
918   FOR_EACH_EDGE (e, ei, region->exit->preds)
919     if (bb_in_sd_region (e->src, region))
920       {
921         if (exit)
922           {
923             exit = NULL;
924             break;
925           }
926
927         else
928           exit = e;
929       }
930
931   return exit;
932 }
933
934 /* Create a single entry edge for REGION.  */
935
936 static void
937 create_single_entry_edge (sd_region *region)
938 {
939   if (find_single_entry_edge (region))
940     return;
941
942   /* There are multiple predecessors for bb_3
943
944   |  1  2
945   |  | /
946   |  |/
947   |  3  <- entry
948   |  |\
949   |  | |
950   |  4 ^
951   |  | |
952   |  |/
953   |  5
954
955   There are two edges (1->3, 2->3), that point from outside into the region,
956   and another one (5->3), a loop latch, lead to bb_3.
957
958   We split bb_3.
959
960   |  1  2
961   |  | /
962   |  |/
963   |3.0
964   |  |\     (3.0 -> 3.1) = single entry edge
965   |3.1 |        <- entry
966   |  | |
967   |  | |
968   |  4 ^
969   |  | |
970   |  |/
971   |  5
972
973   If the loop is part of the SCoP, we have to redirect the loop latches.
974
975   |  1  2
976   |  | /
977   |  |/
978   |3.0
979   |  |      (3.0 -> 3.1) = entry edge
980   |3.1          <- entry
981   |  |\
982   |  | |
983   |  4 ^
984   |  | |
985   |  |/
986   |  5  */
987
988   if (region->entry->loop_father->header != region->entry
989       || dominated_by_p (CDI_DOMINATORS,
990                          loop_latch_edge (region->entry->loop_father)->src,
991                          region->exit))
992     {
993       edge forwarder = split_block_after_labels (region->entry);
994       region->entry = forwarder->dest;
995     }
996   else
997     /* This case is never executed, as the loop headers seem always to have a
998        single edge pointing from outside into the loop.  */
999     gcc_unreachable ();
1000
1001 #ifdef ENABLE_CHECKING
1002   gcc_assert (find_single_entry_edge (region));
1003 #endif
1004 }
1005
1006 /* Check if the sd_region, mentioned in EDGE, has no exit bb.  */
1007
1008 static bool
1009 sd_region_without_exit (edge e)
1010 {
1011   sd_region *r = (sd_region *) e->aux;
1012
1013   if (r)
1014     return r->exit == NULL;
1015   else
1016     return false;
1017 }
1018
1019 /* Create a single exit edge for REGION.  */
1020
1021 static void
1022 create_single_exit_edge (sd_region *region)
1023 {
1024   edge e;
1025   edge_iterator ei;
1026   edge forwarder = NULL;
1027   basic_block exit;
1028
1029   if (find_single_exit_edge (region))
1030     return;
1031
1032   /* We create a forwarder bb (5) for all edges leaving this region
1033      (3->5, 4->5).  All other edges leading to the same bb, are moved
1034      to a new bb (6).  If these edges where part of another region (2->5)
1035      we update the region->exit pointer, of this region.
1036
1037      To identify which edge belongs to which region we depend on the e->aux
1038      pointer in every edge.  It points to the region of the edge or to NULL,
1039      if the edge is not part of any region.
1040
1041      1 2 3 4    1->5 no region,                 2->5 region->exit = 5,
1042       \| |/     3->5 region->exit = NULL,       4->5 region->exit = NULL
1043         5       <- exit
1044
1045      changes to
1046
1047      1 2 3 4    1->6 no region,                         2->6 region->exit = 6,
1048      | | \/     3->5 no region,                         4->5 no region,
1049      | |  5
1050       \| /      5->6 region->exit = 6
1051         6
1052
1053      Now there is only a single exit edge (5->6).  */
1054   exit = region->exit;
1055   region->exit = NULL;
1056   forwarder = make_forwarder_block (exit, &sd_region_without_exit, NULL);
1057
1058   /* Unmark the edges, that are no longer exit edges.  */
1059   FOR_EACH_EDGE (e, ei, forwarder->src->preds)
1060     if (e->aux)
1061       e->aux = NULL;
1062
1063   /* Mark the new exit edge.  */
1064   single_succ_edge (forwarder->src)->aux = region;
1065
1066   /* Update the exit bb of all regions, where exit edges lead to
1067      forwarder->dest.  */
1068   FOR_EACH_EDGE (e, ei, forwarder->dest->preds)
1069     if (e->aux)
1070       ((sd_region *) e->aux)->exit = forwarder->dest;
1071
1072 #ifdef ENABLE_CHECKING
1073   gcc_assert (find_single_exit_edge (region));
1074 #endif
1075 }
1076
1077 /* Unmark the exit edges of all REGIONS.
1078    See comment in "create_single_exit_edge". */
1079
1080 static void
1081 unmark_exit_edges (VEC (sd_region, heap) *regions)
1082 {
1083   int i;
1084   sd_region *s;
1085   edge e;
1086   edge_iterator ei;
1087
1088   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1089     FOR_EACH_EDGE (e, ei, s->exit->preds)
1090       e->aux = NULL;
1091 }
1092
1093
1094 /* Mark the exit edges of all REGIONS.
1095    See comment in "create_single_exit_edge". */
1096
1097 static void
1098 mark_exit_edges (VEC (sd_region, heap) *regions)
1099 {
1100   int i;
1101   sd_region *s;
1102   edge e;
1103   edge_iterator ei;
1104
1105   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1106     FOR_EACH_EDGE (e, ei, s->exit->preds)
1107       if (bb_in_sd_region (e->src, s))
1108         e->aux = s;
1109 }
1110
1111 /* Create for all scop regions a single entry and a single exit edge.  */
1112
1113 static void
1114 create_sese_edges (VEC (sd_region, heap) *regions)
1115 {
1116   int i;
1117   sd_region *s;
1118
1119   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1120     create_single_entry_edge (s);
1121
1122   mark_exit_edges (regions);
1123
1124   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1125     create_single_exit_edge (s);
1126
1127   unmark_exit_edges (regions);
1128
1129   fix_loop_structure (NULL);
1130
1131 #ifdef ENABLE_CHECKING
1132   verify_loop_structure ();
1133   verify_dominators (CDI_DOMINATORS);
1134   verify_ssa (false);
1135 #endif
1136 }
1137
1138 /* Create graphite SCoPs from an array of scop detection REGIONS.  */
1139
1140 static void
1141 build_graphite_scops (VEC (sd_region, heap) *regions,
1142                       VEC (scop_p, heap) **scops)
1143 {
1144   int i;
1145   sd_region *s;
1146
1147   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
1148     {
1149       edge entry = find_single_entry_edge (s);
1150       edge exit = find_single_exit_edge (s);
1151       scop_p scop = new_scop (new_sese (entry, exit));
1152       VEC_safe_push (scop_p, heap, *scops, scop);
1153
1154       /* Are there overlapping SCoPs?  */
1155 #ifdef ENABLE_CHECKING
1156         {
1157           int j;
1158           sd_region *s2;
1159
1160           for (j = 0; VEC_iterate (sd_region, regions, j, s2); j++)
1161             if (s != s2)
1162               gcc_assert (!bb_in_sd_region (s->entry, s2));
1163         }
1164 #endif
1165     }
1166 }
1167
1168 /* Returns true when BB contains only close phi nodes.  */
1169
1170 static bool
1171 contains_only_close_phi_nodes (basic_block bb)
1172 {
1173   gimple_stmt_iterator gsi;
1174
1175   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1176     if (gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
1177       return false;
1178
1179   return true;
1180 }
1181
1182 /* Print statistics for SCOP to FILE.  */
1183
1184 static void
1185 print_graphite_scop_statistics (FILE* file, scop_p scop)
1186 {
1187   long n_bbs = 0;
1188   long n_loops = 0;
1189   long n_stmts = 0;
1190   long n_conditions = 0;
1191   long n_p_bbs = 0;
1192   long n_p_loops = 0;
1193   long n_p_stmts = 0;
1194   long n_p_conditions = 0;
1195
1196   basic_block bb;
1197
1198   FOR_ALL_BB (bb)
1199     {
1200       gimple_stmt_iterator psi;
1201       loop_p loop = bb->loop_father;
1202
1203       if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
1204         continue;
1205
1206       n_bbs++;
1207       n_p_bbs += bb->count;
1208
1209       if (VEC_length (edge, bb->succs) > 1)
1210         {
1211           n_conditions++;
1212           n_p_conditions += bb->count;
1213         }
1214
1215       for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
1216         {
1217           n_stmts++;
1218           n_p_stmts += bb->count;
1219         }
1220
1221       if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
1222         {
1223           n_loops++;
1224           n_p_loops += bb->count;
1225         }
1226
1227     }
1228
1229   fprintf (file, "\nBefore limit_scops SCoP statistics (");
1230   fprintf (file, "BBS:%ld, ", n_bbs);
1231   fprintf (file, "LOOPS:%ld, ", n_loops);
1232   fprintf (file, "CONDITIONS:%ld, ", n_conditions);
1233   fprintf (file, "STMTS:%ld)\n", n_stmts);
1234   fprintf (file, "\nBefore limit_scops SCoP profiling statistics (");
1235   fprintf (file, "BBS:%ld, ", n_p_bbs);
1236   fprintf (file, "LOOPS:%ld, ", n_p_loops);
1237   fprintf (file, "CONDITIONS:%ld, ", n_p_conditions);
1238   fprintf (file, "STMTS:%ld)\n", n_p_stmts);
1239 }
1240
1241 /* Print statistics for SCOPS to FILE.  */
1242
1243 static void
1244 print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
1245 {
1246   int i;
1247   scop_p scop;
1248
1249   for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
1250     print_graphite_scop_statistics (file, scop);
1251 }
1252
1253 /* Version of free_scops special cased for limit_scops.  */
1254
1255 static void
1256 free_scops_1 (VEC (scop_p, heap) **scops)
1257 {
1258   int i;
1259   scop_p scop;
1260
1261   for (i = 0; VEC_iterate (scop_p, *scops, i, scop); i++)
1262     {
1263       sese region = SCOP_REGION (scop);
1264       free (SESE_PARAMS_NAMES (region));
1265       SESE_PARAMS_NAMES (region) = 0;
1266     }
1267
1268   free_scops (*scops);
1269 }
1270
1271 /* We limit all SCoPs to SCoPs, that are completely surrounded by a loop.
1272
1273    Example:
1274
1275    for (i      |
1276      {         |
1277        for (j  |  SCoP 1
1278        for (k  |
1279      }         |
1280
1281    * SCoP frontier, as this line is not surrounded by any loop. *
1282
1283    for (l      |  SCoP 2
1284
1285    This is necessary as scalar evolution and parameter detection need a
1286    outermost loop to initialize parameters correctly.
1287
1288    TODO: FIX scalar evolution and parameter detection to allow more flexible
1289          SCoP frontiers.  */
1290
1291 static void
1292 limit_scops (VEC (scop_p, heap) **scops)
1293 {
1294   VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
1295
1296   int i;
1297   scop_p scop;
1298
1299   for (i = 0; VEC_iterate (scop_p, *scops, i, scop); i++)
1300     {
1301       int j;
1302       loop_p loop;
1303       sese region = SCOP_REGION (scop);
1304       build_scop_bbs (scop);
1305       build_sese_loop_nests (region);
1306
1307       for (j = 0; VEC_iterate (loop_p, SESE_LOOP_NEST (region), j, loop); j++)
1308         if (!loop_in_sese_p (loop_outer (loop), region)
1309             && single_exit (loop))
1310           {
1311             sd_region open_scop;
1312             open_scop.entry = loop->header;
1313             open_scop.exit = single_exit (loop)->dest;
1314
1315             /* This is a hack on top of the limit_scops hack.  The
1316                limit_scops hack should disappear all together.  */
1317             if (single_succ_p (open_scop.exit)
1318                 && contains_only_close_phi_nodes (open_scop.exit))
1319               open_scop.exit = single_succ_edge (open_scop.exit)->dest;
1320
1321             VEC_safe_push (sd_region, heap, regions, &open_scop);
1322           }
1323     }
1324
1325   free_scops_1 (scops);
1326   *scops = VEC_alloc (scop_p, heap, 3);
1327
1328   create_sese_edges (regions);
1329   build_graphite_scops (regions, scops);
1330   VEC_free (sd_region, heap, regions);
1331 }
1332
1333 /* Transforms LOOP to the canonical loop closed SSA form.  */
1334
1335 static void
1336 canonicalize_loop_closed_ssa (loop_p loop)
1337 {
1338   edge e = single_exit (loop);
1339   basic_block bb;
1340
1341   if (!e || e->flags & EDGE_ABNORMAL)
1342     return;
1343
1344   bb = e->dest;
1345
1346   if (VEC_length (edge, bb->preds) == 1)
1347     split_block_after_labels (bb);
1348   else
1349     {
1350       gimple_stmt_iterator psi;
1351       basic_block close = split_edge (e);
1352
1353       e = single_succ_edge (close);
1354
1355       for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1356         {
1357           gimple phi = gsi_stmt (psi);
1358           unsigned i;
1359
1360           for (i = 0; i < gimple_phi_num_args (phi); i++)
1361             if (gimple_phi_arg_edge (phi, i) == e)
1362               {
1363                 tree res, arg = gimple_phi_arg_def (phi, i);
1364                 use_operand_p use_p;
1365                 gimple close_phi;
1366
1367                 if (TREE_CODE (arg) != SSA_NAME)
1368                   continue;
1369
1370                 close_phi = create_phi_node (arg, close);
1371                 res = create_new_def_for (gimple_phi_result (close_phi),
1372                                           close_phi,
1373                                           gimple_phi_result_ptr (close_phi));
1374                 add_phi_arg (close_phi, arg,
1375                              gimple_phi_arg_edge (close_phi, 0),
1376                              UNKNOWN_LOCATION);
1377                 use_p = gimple_phi_arg_imm_use_ptr (phi, i);
1378                 replace_exp (use_p, res);
1379                 update_stmt (phi);
1380               }
1381         }
1382     }
1383 }
1384
1385 /* Converts the current loop closed SSA form to a canonical form
1386    expected by the Graphite code generation.
1387
1388    The loop closed SSA form has the following invariant: a variable
1389    defined in a loop that is used outside the loop appears only in the
1390    phi nodes in the destination of the loop exit.  These phi nodes are
1391    called close phi nodes.
1392
1393    The canonical loop closed SSA form contains the extra invariants:
1394
1395    - when the loop contains only one exit, the close phi nodes contain
1396    only one argument.  That implies that the basic block that contains
1397    the close phi nodes has only one predecessor, that is a basic block
1398    in the loop.
1399
1400    - the basic block containing the close phi nodes does not contain
1401    other statements.
1402 */
1403
1404 static void
1405 canonicalize_loop_closed_ssa_form (void)
1406 {
1407   loop_iterator li;
1408   loop_p loop;
1409
1410 #ifdef ENABLE_CHECKING
1411   verify_loop_closed_ssa ();
1412 #endif
1413
1414   FOR_EACH_LOOP (li, loop, 0)
1415     canonicalize_loop_closed_ssa (loop);
1416
1417   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
1418   update_ssa (TODO_update_ssa);
1419
1420 #ifdef ENABLE_CHECKING
1421   verify_loop_closed_ssa ();
1422 #endif
1423 }
1424
1425 /* Find Static Control Parts (SCoP) in the current function and pushes
1426    them to SCOPS.  */
1427
1428 void
1429 build_scops (VEC (scop_p, heap) **scops)
1430 {
1431   struct loop *loop = current_loops->tree_root;
1432   VEC (sd_region, heap) *regions = VEC_alloc (sd_region, heap, 3);
1433
1434   canonicalize_loop_closed_ssa_form ();
1435   build_scops_1 (single_succ (ENTRY_BLOCK_PTR), ENTRY_BLOCK_PTR->loop_father,
1436                               &regions, loop);
1437   create_sese_edges (regions);
1438   build_graphite_scops (regions, scops);
1439
1440   if (dump_file && (dump_flags & TDF_DETAILS))
1441     print_graphite_statistics (dump_file, *scops);
1442
1443   limit_scops (scops);
1444   VEC_free (sd_region, heap, regions);
1445
1446   if (dump_file && (dump_flags & TDF_DETAILS))
1447     fprintf (dump_file, "\nnumber of SCoPs: %d\n",
1448              VEC_length (scop_p, *scops));
1449 }
1450
1451 /* Pretty print to FILE all the SCoPs in DOT format and mark them with
1452    different colors.  If there are not enough colors, paint the
1453    remaining SCoPs in gray.
1454
1455    Special nodes:
1456    - "*" after the node number denotes the entry of a SCoP,
1457    - "#" after the node number denotes the exit of a SCoP,
1458    - "()" around the node number denotes the entry or the
1459      exit nodes of the SCOP.  These are not part of SCoP.  */
1460
1461 static void
1462 dot_all_scops_1 (FILE *file, VEC (scop_p, heap) *scops)
1463 {
1464   basic_block bb;
1465   edge e;
1466   edge_iterator ei;
1467   scop_p scop;
1468   const char* color;
1469   int i;
1470
1471   /* Disable debugging while printing graph.  */
1472   int tmp_dump_flags = dump_flags;
1473   dump_flags = 0;
1474
1475   fprintf (file, "digraph all {\n");
1476
1477   FOR_ALL_BB (bb)
1478     {
1479       int part_of_scop = false;
1480
1481       /* Use HTML for every bb label.  So we are able to print bbs
1482          which are part of two different SCoPs, with two different
1483          background colors.  */
1484       fprintf (file, "%d [label=<\n  <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
1485                      bb->index);
1486       fprintf (file, "CELLSPACING=\"0\">\n");
1487
1488       /* Select color for SCoP.  */
1489       for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
1490         {
1491           sese region = SCOP_REGION (scop);
1492           if (bb_in_sese_p (bb, region)
1493               || (SESE_EXIT_BB (region) == bb)
1494               || (SESE_ENTRY_BB (region) == bb))
1495             {
1496               switch (i % 17)
1497                 {
1498                 case 0: /* red */
1499                   color = "#e41a1c";
1500                   break;
1501                 case 1: /* blue */
1502                   color = "#377eb8";
1503                   break;
1504                 case 2: /* green */
1505                   color = "#4daf4a";
1506                   break;
1507                 case 3: /* purple */
1508                   color = "#984ea3";
1509                   break;
1510                 case 4: /* orange */
1511                   color = "#ff7f00";
1512                   break;
1513                 case 5: /* yellow */
1514                   color = "#ffff33";
1515                   break;
1516                 case 6: /* brown */
1517                   color = "#a65628";
1518                   break;
1519                 case 7: /* rose */
1520                   color = "#f781bf";
1521                   break;
1522                 case 8:
1523                   color = "#8dd3c7";
1524                   break;
1525                 case 9:
1526                   color = "#ffffb3";
1527                   break;
1528                 case 10:
1529                   color = "#bebada";
1530                   break;
1531                 case 11:
1532                   color = "#fb8072";
1533                   break;
1534                 case 12:
1535                   color = "#80b1d3";
1536                   break;
1537                 case 13:
1538                   color = "#fdb462";
1539                   break;
1540                 case 14:
1541                   color = "#b3de69";
1542                   break;
1543                 case 15:
1544                   color = "#fccde5";
1545                   break;
1546                 case 16:
1547                   color = "#bc80bd";
1548                   break;
1549                 default: /* gray */
1550                   color = "#999999";
1551                 }
1552
1553               fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color);
1554
1555               if (!bb_in_sese_p (bb, region))
1556                 fprintf (file, " (");
1557
1558               if (bb == SESE_ENTRY_BB (region)
1559                   && bb == SESE_EXIT_BB (region))
1560                 fprintf (file, " %d*# ", bb->index);
1561               else if (bb == SESE_ENTRY_BB (region))
1562                 fprintf (file, " %d* ", bb->index);
1563               else if (bb == SESE_EXIT_BB (region))
1564                 fprintf (file, " %d# ", bb->index);
1565               else
1566                 fprintf (file, " %d ", bb->index);
1567
1568               if (!bb_in_sese_p (bb,region))
1569                 fprintf (file, ")");
1570
1571               fprintf (file, "</TD></TR>\n");
1572               part_of_scop  = true;
1573             }
1574         }
1575
1576       if (!part_of_scop)
1577         {
1578           fprintf (file, "    <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
1579           fprintf (file, " %d </TD></TR>\n", bb->index);
1580         }
1581       fprintf (file, "  </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
1582     }
1583
1584   FOR_ALL_BB (bb)
1585     {
1586       FOR_EACH_EDGE (e, ei, bb->succs)
1587               fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
1588     }
1589
1590   fputs ("}\n\n", file);
1591
1592   /* Enable debugging again.  */
1593   dump_flags = tmp_dump_flags;
1594 }
1595
1596 /* Display all SCoPs using dotty.  */
1597
1598 void
1599 dot_all_scops (VEC (scop_p, heap) *scops)
1600 {
1601   /* When debugging, enable the following code.  This cannot be used
1602      in production compilers because it calls "system".  */
1603 #if 0
1604   int x;
1605   FILE *stream = fopen ("/tmp/allscops.dot", "w");
1606   gcc_assert (stream);
1607
1608   dot_all_scops_1 (stream, scops);
1609   fclose (stream);
1610
1611   x = system ("dotty /tmp/allscops.dot");
1612 #else
1613   dot_all_scops_1 (stderr, scops);
1614 #endif
1615 }
1616
1617 /* Display all SCoPs using dotty.  */
1618
1619 void
1620 dot_scop (scop_p scop)
1621 {
1622   VEC (scop_p, heap) *scops = NULL;
1623
1624   if (scop)
1625     VEC_safe_push (scop_p, heap, scops, scop);
1626
1627   /* When debugging, enable the following code.  This cannot be used
1628      in production compilers because it calls "system".  */
1629 #if 0
1630   {
1631     int x;
1632     FILE *stream = fopen ("/tmp/allscops.dot", "w");
1633     gcc_assert (stream);
1634
1635     dot_all_scops_1 (stream, scops);
1636     fclose (stream);
1637     x = system ("dotty /tmp/allscops.dot");
1638   }
1639 #else
1640   dot_all_scops_1 (stderr, scops);
1641 #endif
1642
1643   VEC_free (scop_p, heap, scops);
1644 }
1645
1646 #endif