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