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