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