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