graphite-scop-detection.c: Include tree-ssa-propagate,h.
[gcc.git] / gcc / graphite-sese-to-poly.c
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22
23 #ifdef HAVE_cloog
24 #include <isl/set.h>
25 #include <isl/map.h>
26 #include <isl/union_map.h>
27 #include <isl/constraint.h>
28 #include <isl/aff.h>
29 #include <cloog/cloog.h>
30 #include <cloog/cloog.h>
31 #include <cloog/isl/domain.h>
32 #endif
33
34 #include "system.h"
35 #include "coretypes.h"
36 #include "tree-ssa.h"
37 #include "tree-pass.h"
38 #include "cfgloop.h"
39 #include "tree-chrec.h"
40 #include "tree-data-ref.h"
41 #include "tree-scalar-evolution.h"
42 #include "domwalk.h"
43 #include "sese.h"
44 #include "tree-ssa-propagate.h"
45
46 #ifdef HAVE_cloog
47 #include "graphite-poly.h"
48 #include "graphite-sese-to-poly.h"
49
50
51 /* Assigns to RES the value of the INTEGER_CST T. */
52
53 static inline void
54 tree_int_to_gmp (tree t, mpz_t res)
55 {
56 double_int di = tree_to_double_int (t);
57 mpz_set_double_int (res, di, TYPE_UNSIGNED (TREE_TYPE (t)));
58 }
59
60 /* Returns the index of the PHI argument defined in the outermost
61 loop. */
62
63 static size_t
64 phi_arg_in_outermost_loop (gimple phi)
65 {
66 loop_p loop = gimple_bb (phi)->loop_father;
67 size_t i, res = 0;
68
69 for (i = 0; i < gimple_phi_num_args (phi); i++)
70 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
71 {
72 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
73 res = i;
74 }
75
76 return res;
77 }
78
79 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
80 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
81
82 static void
83 remove_simple_copy_phi (gimple_stmt_iterator *psi)
84 {
85 gimple phi = gsi_stmt (*psi);
86 tree res = gimple_phi_result (phi);
87 size_t entry = phi_arg_in_outermost_loop (phi);
88 tree init = gimple_phi_arg_def (phi, entry);
89 gimple stmt = gimple_build_assign (res, init);
90 edge e = gimple_phi_arg_edge (phi, entry);
91
92 remove_phi_node (psi, false);
93 gsi_insert_on_edge_immediate (e, stmt);
94 SSA_NAME_DEF_STMT (res) = stmt;
95 }
96
97 /* Removes an invariant phi node at position PSI by inserting on the
98 loop ENTRY edge the assignment RES = INIT. */
99
100 static void
101 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
102 {
103 gimple phi = gsi_stmt (*psi);
104 loop_p loop = loop_containing_stmt (phi);
105 tree res = gimple_phi_result (phi);
106 tree scev = scalar_evolution_in_region (region, loop, res);
107 size_t entry = phi_arg_in_outermost_loop (phi);
108 edge e = gimple_phi_arg_edge (phi, entry);
109 tree var;
110 gimple stmt;
111 gimple_seq stmts = NULL;
112
113 if (tree_contains_chrecs (scev, NULL))
114 scev = gimple_phi_arg_def (phi, entry);
115
116 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
117 stmt = gimple_build_assign (res, var);
118 remove_phi_node (psi, false);
119
120 gimple_seq_add_stmt (&stmts, stmt);
121 gsi_insert_seq_on_edge (e, stmts);
122 gsi_commit_edge_inserts ();
123 SSA_NAME_DEF_STMT (res) = stmt;
124 }
125
126 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
127
128 static inline bool
129 simple_copy_phi_p (gimple phi)
130 {
131 tree res;
132
133 if (gimple_phi_num_args (phi) != 2)
134 return false;
135
136 res = gimple_phi_result (phi);
137 return (res == gimple_phi_arg_def (phi, 0)
138 || res == gimple_phi_arg_def (phi, 1));
139 }
140
141 /* Returns true when the phi node at position PSI is a reduction phi
142 node in REGION. Otherwise moves the pointer PSI to the next phi to
143 be considered. */
144
145 static bool
146 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
147 {
148 loop_p loop;
149 gimple phi = gsi_stmt (*psi);
150 tree res = gimple_phi_result (phi);
151
152 loop = loop_containing_stmt (phi);
153
154 if (simple_copy_phi_p (phi))
155 {
156 /* PRE introduces phi nodes like these, for an example,
157 see id-5.f in the fortran graphite testsuite:
158
159 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
160 */
161 remove_simple_copy_phi (psi);
162 return false;
163 }
164
165 if (scev_analyzable_p (res, region))
166 {
167 tree scev = scalar_evolution_in_region (region, loop, res);
168
169 if (evolution_function_is_invariant_p (scev, loop->num))
170 remove_invariant_phi (region, psi);
171 else
172 gsi_next (psi);
173
174 return false;
175 }
176
177 /* All the other cases are considered reductions. */
178 return true;
179 }
180
181 /* Store the GRAPHITE representation of BB. */
182
183 static gimple_bb_p
184 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
185 {
186 struct gimple_bb *gbb;
187
188 gbb = XNEW (struct gimple_bb);
189 bb->aux = gbb;
190 GBB_BB (gbb) = bb;
191 GBB_DATA_REFS (gbb) = drs;
192 GBB_CONDITIONS (gbb).create (0);
193 GBB_CONDITION_CASES (gbb).create (0);
194
195 return gbb;
196 }
197
198 static void
199 free_data_refs_aux (vec<data_reference_p> datarefs)
200 {
201 unsigned int i;
202 struct data_reference *dr;
203
204 FOR_EACH_VEC_ELT (datarefs, i, dr)
205 if (dr->aux)
206 {
207 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
208
209 free (bap->alias_set);
210
211 free (bap);
212 dr->aux = NULL;
213 }
214 }
215 /* Frees GBB. */
216
217 static void
218 free_gimple_bb (struct gimple_bb *gbb)
219 {
220 free_data_refs_aux (GBB_DATA_REFS (gbb));
221 free_data_refs (GBB_DATA_REFS (gbb));
222
223 GBB_CONDITIONS (gbb).release ();
224 GBB_CONDITION_CASES (gbb).release ();
225 GBB_BB (gbb)->aux = 0;
226 XDELETE (gbb);
227 }
228
229 /* Deletes all gimple bbs in SCOP. */
230
231 static void
232 remove_gbbs_in_scop (scop_p scop)
233 {
234 int i;
235 poly_bb_p pbb;
236
237 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
238 free_gimple_bb (PBB_BLACK_BOX (pbb));
239 }
240
241 /* Deletes all scops in SCOPS. */
242
243 void
244 free_scops (vec<scop_p> scops)
245 {
246 int i;
247 scop_p scop;
248
249 FOR_EACH_VEC_ELT (scops, i, scop)
250 {
251 remove_gbbs_in_scop (scop);
252 free_sese (SCOP_REGION (scop));
253 free_scop (scop);
254 }
255
256 scops.release ();
257 }
258
259 /* Same as outermost_loop_in_sese, returns the outermost loop
260 containing BB in REGION, but makes sure that the returned loop
261 belongs to the REGION, and so this returns the first loop in the
262 REGION when the loop containing BB does not belong to REGION. */
263
264 static loop_p
265 outermost_loop_in_sese_1 (sese region, basic_block bb)
266 {
267 loop_p nest = outermost_loop_in_sese (region, bb);
268
269 if (loop_in_sese_p (nest, region))
270 return nest;
271
272 /* When the basic block BB does not belong to a loop in the region,
273 return the first loop in the region. */
274 nest = nest->inner;
275 while (nest)
276 if (loop_in_sese_p (nest, region))
277 break;
278 else
279 nest = nest->next;
280
281 gcc_assert (nest);
282 return nest;
283 }
284
285 /* Generates a polyhedral black box only if the bb contains interesting
286 information. */
287
288 static gimple_bb_p
289 try_generate_gimple_bb (scop_p scop, basic_block bb)
290 {
291 vec<data_reference_p> drs;
292 drs.create (5);
293 sese region = SCOP_REGION (scop);
294 loop_p nest = outermost_loop_in_sese_1 (region, bb);
295 gimple_stmt_iterator gsi;
296
297 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
298 {
299 gimple stmt = gsi_stmt (gsi);
300 loop_p loop;
301
302 if (is_gimple_debug (stmt))
303 continue;
304
305 loop = loop_containing_stmt (stmt);
306 if (!loop_in_sese_p (loop, region))
307 loop = nest;
308
309 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
310 }
311
312 return new_gimple_bb (bb, drs);
313 }
314
315 /* Returns true if all predecessors of BB, that are not dominated by BB, are
316 marked in MAP. The predecessors dominated by BB are loop latches and will
317 be handled after BB. */
318
319 static bool
320 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
321 {
322 edge e;
323 edge_iterator ei;
324
325 FOR_EACH_EDGE (e, ei, bb->preds)
326 if (!bitmap_bit_p (map, e->src->index)
327 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
328 return false;
329
330 return true;
331 }
332
333 /* Compare the depth of two basic_block's P1 and P2. */
334
335 static int
336 compare_bb_depths (const void *p1, const void *p2)
337 {
338 const_basic_block const bb1 = *(const_basic_block const*)p1;
339 const_basic_block const bb2 = *(const_basic_block const*)p2;
340 int d1 = loop_depth (bb1->loop_father);
341 int d2 = loop_depth (bb2->loop_father);
342
343 if (d1 < d2)
344 return 1;
345
346 if (d1 > d2)
347 return -1;
348
349 return 0;
350 }
351
352 /* Sort the basic blocks from DOM such that the first are the ones at
353 a deepest loop level. */
354
355 static void
356 graphite_sort_dominated_info (vec<basic_block> dom)
357 {
358 dom.qsort (compare_bb_depths);
359 }
360
361 /* Recursive helper function for build_scops_bbs. */
362
363 static void
364 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
365 {
366 sese region = SCOP_REGION (scop);
367 vec<basic_block> dom;
368 poly_bb_p pbb;
369
370 if (bitmap_bit_p (visited, bb->index)
371 || !bb_in_sese_p (bb, region))
372 return;
373
374 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
375 SCOP_BBS (scop).safe_push (pbb);
376 bitmap_set_bit (visited, bb->index);
377
378 dom = get_dominated_by (CDI_DOMINATORS, bb);
379
380 if (!dom.exists ())
381 return;
382
383 graphite_sort_dominated_info (dom);
384
385 while (!dom.is_empty ())
386 {
387 int i;
388 basic_block dom_bb;
389
390 FOR_EACH_VEC_ELT (dom, i, dom_bb)
391 if (all_non_dominated_preds_marked_p (dom_bb, visited))
392 {
393 build_scop_bbs_1 (scop, visited, dom_bb);
394 dom.unordered_remove (i);
395 break;
396 }
397 }
398
399 dom.release ();
400 }
401
402 /* Gather the basic blocks belonging to the SCOP. */
403
404 static void
405 build_scop_bbs (scop_p scop)
406 {
407 sbitmap visited = sbitmap_alloc (last_basic_block);
408 sese region = SCOP_REGION (scop);
409
410 bitmap_clear (visited);
411 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
412 sbitmap_free (visited);
413 }
414
415 /* Return an ISL identifier for the polyhedral basic block PBB. */
416
417 static isl_id *
418 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
419 {
420 char name[50];
421 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
422 return isl_id_alloc (s->ctx, name, pbb);
423 }
424
425 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
426 We generate SCATTERING_DIMENSIONS scattering dimensions.
427
428 CLooG 0.15.0 and previous versions require, that all
429 scattering functions of one CloogProgram have the same number of
430 scattering dimensions, therefore we allow to specify it. This
431 should be removed in future versions of CLooG.
432
433 The scattering polyhedron consists of these dimensions: scattering,
434 loop_iterators, parameters.
435
436 Example:
437
438 | scattering_dimensions = 5
439 | used_scattering_dimensions = 3
440 | nb_iterators = 1
441 | scop_nb_params = 2
442 |
443 | Schedule:
444 | i
445 | 4 5
446 |
447 | Scattering polyhedron:
448 |
449 | scattering: {s1, s2, s3, s4, s5}
450 | loop_iterators: {i}
451 | parameters: {p1, p2}
452 |
453 | s1 s2 s3 s4 s5 i p1 p2 1
454 | 1 0 0 0 0 0 0 0 -4 = 0
455 | 0 1 0 0 0 -1 0 0 0 = 0
456 | 0 0 1 0 0 0 0 0 -5 = 0 */
457
458 static void
459 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
460 poly_bb_p pbb, int scattering_dimensions)
461 {
462 int i;
463 int nb_iterators = pbb_dim_iter_domain (pbb);
464 int used_scattering_dimensions = nb_iterators * 2 + 1;
465 isl_int val;
466 isl_space *dc, *dm;
467
468 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
469
470 isl_int_init (val);
471
472 dc = isl_set_get_space (pbb->domain);
473 dm = isl_space_add_dims (isl_space_from_domain (dc),
474 isl_dim_out, scattering_dimensions);
475 pbb->schedule = isl_map_universe (dm);
476
477 for (i = 0; i < scattering_dimensions; i++)
478 {
479 /* Textual order inside this loop. */
480 if ((i % 2) == 0)
481 {
482 isl_constraint *c = isl_equality_alloc
483 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
484
485 if (0 != isl_aff_get_coefficient (static_sched, isl_dim_in,
486 i / 2, &val))
487 gcc_unreachable ();
488
489 isl_int_neg (val, val);
490 c = isl_constraint_set_constant (c, val);
491 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
492 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
493 }
494
495 /* Iterations of this loop. */
496 else /* if ((i % 2) == 1) */
497 {
498 int loop = (i - 1) / 2;
499 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
500 isl_dim_out, i);
501 }
502 }
503
504 isl_int_clear (val);
505
506 pbb->transformed = isl_map_copy (pbb->schedule);
507 }
508
509 /* Build for BB the static schedule.
510
511 The static schedule is a Dewey numbering of the abstract syntax
512 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
513
514 The following example informally defines the static schedule:
515
516 A
517 for (i: ...)
518 {
519 for (j: ...)
520 {
521 B
522 C
523 }
524
525 for (k: ...)
526 {
527 D
528 E
529 }
530 }
531 F
532
533 Static schedules for A to F:
534
535 DEPTH
536 0 1 2
537 A 0
538 B 1 0 0
539 C 1 0 1
540 D 1 1 0
541 E 1 1 1
542 F 2
543 */
544
545 static void
546 build_scop_scattering (scop_p scop)
547 {
548 int i;
549 poly_bb_p pbb;
550 gimple_bb_p previous_gbb = NULL;
551 isl_space *dc = isl_set_get_space (scop->context);
552 isl_aff *static_sched;
553
554 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
555 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
556
557 /* We have to start schedules at 0 on the first component and
558 because we cannot compare_prefix_loops against a previous loop,
559 prefix will be equal to zero, and that index will be
560 incremented before copying. */
561 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
562
563 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
564 {
565 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
566 int prefix;
567 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
568
569 if (previous_gbb)
570 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
571 else
572 prefix = 0;
573
574 previous_gbb = gbb;
575
576 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
577 prefix, 1);
578 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
579 }
580
581 isl_aff_free (static_sched);
582 }
583
584 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
585
586 /* Extract an affine expression from the chain of recurrence E. */
587
588 static isl_pw_aff *
589 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
590 {
591 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
592 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
593 isl_local_space *ls = isl_local_space_from_space (space);
594 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
595 isl_aff *loop = isl_aff_set_coefficient_si
596 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
597 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
598
599 /* Before multiplying, make sure that the result is affine. */
600 gcc_assert (isl_pw_aff_is_cst (rhs)
601 || isl_pw_aff_is_cst (l));
602
603 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
604 }
605
606 /* Extract an affine expression from the mult_expr E. */
607
608 static isl_pw_aff *
609 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
610 {
611 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
612 isl_space_copy (space));
613 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
614
615 if (!isl_pw_aff_is_cst (lhs)
616 && !isl_pw_aff_is_cst (rhs))
617 {
618 isl_pw_aff_free (lhs);
619 isl_pw_aff_free (rhs);
620 return NULL;
621 }
622
623 return isl_pw_aff_mul (lhs, rhs);
624 }
625
626 /* Return an ISL identifier from the name of the ssa_name E. */
627
628 static isl_id *
629 isl_id_for_ssa_name (scop_p s, tree e)
630 {
631 const char *name = get_name (e);
632 isl_id *id;
633
634 if (name)
635 id = isl_id_alloc (s->ctx, name, e);
636 else
637 {
638 char name1[50];
639 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
640 id = isl_id_alloc (s->ctx, name1, e);
641 }
642
643 return id;
644 }
645
646 /* Return an ISL identifier for the data reference DR. */
647
648 static isl_id *
649 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
650 {
651 /* Data references all get the same isl_id. They need to be comparable
652 and are distinguished through the first dimension, which contains the
653 alias set number. */
654 return isl_id_alloc (s->ctx, "", 0);
655 }
656
657 /* Extract an affine expression from the ssa_name E. */
658
659 static isl_pw_aff *
660 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
661 {
662 isl_aff *aff;
663 isl_set *dom;
664 isl_id *id;
665 int dimension;
666
667 id = isl_id_for_ssa_name (s, e);
668 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
669 isl_id_free (id);
670 dom = isl_set_universe (isl_space_copy (space));
671 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
672 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
673 return isl_pw_aff_alloc (dom, aff);
674 }
675
676 /* Extract an affine expression from the gmp constant G. */
677
678 static isl_pw_aff *
679 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
680 {
681 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
682 isl_aff *aff = isl_aff_zero_on_domain (ls);
683 isl_set *dom = isl_set_universe (space);
684 isl_int v;
685
686 isl_int_init (v);
687 isl_int_set_gmp (v, g);
688 aff = isl_aff_add_constant (aff, v);
689 isl_int_clear (v);
690
691 return isl_pw_aff_alloc (dom, aff);
692 }
693
694 /* Extract an affine expression from the integer_cst E. */
695
696 static isl_pw_aff *
697 extract_affine_int (tree e, __isl_take isl_space *space)
698 {
699 isl_pw_aff *res;
700 mpz_t g;
701
702 mpz_init (g);
703 tree_int_to_gmp (e, g);
704 res = extract_affine_gmp (g, space);
705 mpz_clear (g);
706
707 return res;
708 }
709
710 /* Compute pwaff mod 2^width. */
711
712 static isl_pw_aff *
713 wrap (isl_pw_aff *pwaff, unsigned width)
714 {
715 isl_int mod;
716
717 isl_int_init (mod);
718 isl_int_set_si (mod, 1);
719 isl_int_mul_2exp (mod, mod, width);
720
721 pwaff = isl_pw_aff_mod (pwaff, mod);
722
723 isl_int_clear (mod);
724
725 return pwaff;
726 }
727
728 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
729 Otherwise returns -1. */
730
731 static inline int
732 parameter_index_in_region_1 (tree name, sese region)
733 {
734 int i;
735 tree p;
736
737 gcc_assert (TREE_CODE (name) == SSA_NAME);
738
739 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
740 if (p == name)
741 return i;
742
743 return -1;
744 }
745
746 /* When the parameter NAME is in REGION, returns its index in
747 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
748 and returns the index of NAME. */
749
750 static int
751 parameter_index_in_region (tree name, sese region)
752 {
753 int i;
754
755 gcc_assert (TREE_CODE (name) == SSA_NAME);
756
757 i = parameter_index_in_region_1 (name, region);
758 if (i != -1)
759 return i;
760
761 gcc_assert (SESE_ADD_PARAMS (region));
762
763 i = SESE_PARAMS (region).length ();
764 SESE_PARAMS (region).safe_push (name);
765 return i;
766 }
767
768 /* Extract an affine expression from the tree E in the scop S. */
769
770 static isl_pw_aff *
771 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
772 {
773 isl_pw_aff *lhs, *rhs, *res;
774 tree type;
775
776 if (e == chrec_dont_know) {
777 isl_space_free (space);
778 return NULL;
779 }
780
781 switch (TREE_CODE (e))
782 {
783 case POLYNOMIAL_CHREC:
784 res = extract_affine_chrec (s, e, space);
785 break;
786
787 case MULT_EXPR:
788 res = extract_affine_mul (s, e, space);
789 break;
790
791 case PLUS_EXPR:
792 case POINTER_PLUS_EXPR:
793 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
794 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
795 res = isl_pw_aff_add (lhs, rhs);
796 break;
797
798 case MINUS_EXPR:
799 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
800 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
801 res = isl_pw_aff_sub (lhs, rhs);
802 break;
803
804 case NEGATE_EXPR:
805 case BIT_NOT_EXPR:
806 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
807 rhs = extract_affine (s, integer_minus_one_node, space);
808 res = isl_pw_aff_mul (lhs, rhs);
809 break;
810
811 case SSA_NAME:
812 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
813 res = extract_affine_name (s, e, space);
814 break;
815
816 case INTEGER_CST:
817 res = extract_affine_int (e, space);
818 /* No need to wrap a single integer. */
819 return res;
820
821 CASE_CONVERT:
822 case NON_LVALUE_EXPR:
823 res = extract_affine (s, TREE_OPERAND (e, 0), space);
824 break;
825
826 default:
827 gcc_unreachable ();
828 break;
829 }
830
831 type = TREE_TYPE (e);
832 if (TYPE_UNSIGNED (type))
833 res = wrap (res, TYPE_PRECISION (type));
834
835 return res;
836 }
837
838 /* In the context of sese S, scan the expression E and translate it to
839 a linear expression C. When parsing a symbolic multiplication, K
840 represents the constant multiplier of an expression containing
841 parameters. */
842
843 static void
844 scan_tree_for_params (sese s, tree e)
845 {
846 if (e == chrec_dont_know)
847 return;
848
849 switch (TREE_CODE (e))
850 {
851 case POLYNOMIAL_CHREC:
852 scan_tree_for_params (s, CHREC_LEFT (e));
853 break;
854
855 case MULT_EXPR:
856 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
857 scan_tree_for_params (s, TREE_OPERAND (e, 0));
858 else
859 scan_tree_for_params (s, TREE_OPERAND (e, 1));
860 break;
861
862 case PLUS_EXPR:
863 case POINTER_PLUS_EXPR:
864 case MINUS_EXPR:
865 scan_tree_for_params (s, TREE_OPERAND (e, 0));
866 scan_tree_for_params (s, TREE_OPERAND (e, 1));
867 break;
868
869 case NEGATE_EXPR:
870 case BIT_NOT_EXPR:
871 CASE_CONVERT:
872 case NON_LVALUE_EXPR:
873 scan_tree_for_params (s, TREE_OPERAND (e, 0));
874 break;
875
876 case SSA_NAME:
877 parameter_index_in_region (e, s);
878 break;
879
880 case INTEGER_CST:
881 case ADDR_EXPR:
882 break;
883
884 default:
885 gcc_unreachable ();
886 break;
887 }
888 }
889
890 /* Find parameters with respect to REGION in BB. We are looking in memory
891 access functions, conditions and loop bounds. */
892
893 static void
894 find_params_in_bb (sese region, gimple_bb_p gbb)
895 {
896 int i;
897 unsigned j;
898 data_reference_p dr;
899 gimple stmt;
900 loop_p loop = GBB_BB (gbb)->loop_father;
901
902 /* Find parameters in the access functions of data references. */
903 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
904 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
905 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
906
907 /* Find parameters in conditional statements. */
908 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
909 {
910 tree lhs = scalar_evolution_in_region (region, loop,
911 gimple_cond_lhs (stmt));
912 tree rhs = scalar_evolution_in_region (region, loop,
913 gimple_cond_rhs (stmt));
914
915 scan_tree_for_params (region, lhs);
916 scan_tree_for_params (region, rhs);
917 }
918 }
919
920 /* Record the parameters used in the SCOP. A variable is a parameter
921 in a scop if it does not vary during the execution of that scop. */
922
923 static void
924 find_scop_parameters (scop_p scop)
925 {
926 poly_bb_p pbb;
927 unsigned i;
928 sese region = SCOP_REGION (scop);
929 struct loop *loop;
930 int nbp;
931
932 /* Find the parameters used in the loop bounds. */
933 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
934 {
935 tree nb_iters = number_of_latch_executions (loop);
936
937 if (!chrec_contains_symbols (nb_iters))
938 continue;
939
940 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
941 scan_tree_for_params (region, nb_iters);
942 }
943
944 /* Find the parameters used in data accesses. */
945 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
946 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
947
948 nbp = sese_nb_params (region);
949 scop_set_nb_params (scop, nbp);
950 SESE_ADD_PARAMS (region) = false;
951
952 {
953 tree e;
954 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
955
956 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
957 space = isl_space_set_dim_id (space, isl_dim_param, i,
958 isl_id_for_ssa_name (scop, e));
959
960 scop->context = isl_set_universe (space);
961 }
962 }
963
964 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
965 the constraints for the surrounding loops. */
966
967 static void
968 build_loop_iteration_domains (scop_p scop, struct loop *loop,
969 int nb,
970 isl_set *outer, isl_set **doms)
971 {
972 tree nb_iters = number_of_latch_executions (loop);
973 sese region = SCOP_REGION (scop);
974
975 isl_set *inner = isl_set_copy (outer);
976 isl_space *space;
977 isl_constraint *c;
978 int pos = isl_set_dim (outer, isl_dim_set);
979 isl_int v;
980 mpz_t g;
981
982 mpz_init (g);
983 isl_int_init (v);
984
985 inner = isl_set_add_dims (inner, isl_dim_set, 1);
986 space = isl_set_get_space (inner);
987
988 /* 0 <= loop_i */
989 c = isl_inequality_alloc
990 (isl_local_space_from_space (isl_space_copy (space)));
991 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
992 inner = isl_set_add_constraint (inner, c);
993
994 /* loop_i <= cst_nb_iters */
995 if (TREE_CODE (nb_iters) == INTEGER_CST)
996 {
997 c = isl_inequality_alloc
998 (isl_local_space_from_space (isl_space_copy (space)));
999 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1000 tree_int_to_gmp (nb_iters, g);
1001 isl_int_set_gmp (v, g);
1002 c = isl_constraint_set_constant (c, v);
1003 inner = isl_set_add_constraint (inner, c);
1004 }
1005
1006 /* loop_i <= expr_nb_iters */
1007 else if (!chrec_contains_undetermined (nb_iters))
1008 {
1009 double_int nit;
1010 isl_pw_aff *aff;
1011 isl_set *valid;
1012 isl_local_space *ls;
1013 isl_aff *al;
1014 isl_set *le;
1015
1016 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1017
1018 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1019 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1020 valid = isl_set_project_out (valid, isl_dim_set, 0,
1021 isl_set_dim (valid, isl_dim_set));
1022 scop->context = isl_set_intersect (scop->context, valid);
1023
1024 ls = isl_local_space_from_space (isl_space_copy (space));
1025 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1026 isl_dim_in, pos, 1);
1027 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1028 isl_pw_aff_copy (aff));
1029 inner = isl_set_intersect (inner, le);
1030
1031 if (max_stmt_executions (loop, &nit))
1032 {
1033 /* Insert in the context the constraints from the
1034 estimation of the number of iterations NIT and the
1035 symbolic number of iterations (involving parameter
1036 names) NB_ITERS. First, build the affine expression
1037 "NIT - NB_ITERS" and then say that it is positive,
1038 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1039 isl_pw_aff *approx;
1040 mpz_t g;
1041 isl_set *x;
1042 isl_constraint *c;
1043
1044 mpz_init (g);
1045 mpz_set_double_int (g, nit, false);
1046 mpz_sub_ui (g, g, 1);
1047 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1048 x = isl_pw_aff_ge_set (approx, aff);
1049 x = isl_set_project_out (x, isl_dim_set, 0,
1050 isl_set_dim (x, isl_dim_set));
1051 scop->context = isl_set_intersect (scop->context, x);
1052
1053 c = isl_inequality_alloc
1054 (isl_local_space_from_space (isl_space_copy (space)));
1055 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1056 isl_int_set_gmp (v, g);
1057 mpz_clear (g);
1058 c = isl_constraint_set_constant (c, v);
1059 inner = isl_set_add_constraint (inner, c);
1060 }
1061 else
1062 isl_pw_aff_free (aff);
1063 }
1064 else
1065 gcc_unreachable ();
1066
1067 if (loop->inner && loop_in_sese_p (loop->inner, region))
1068 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1069 isl_set_copy (inner), doms);
1070
1071 if (nb != 0
1072 && loop->next
1073 && loop_in_sese_p (loop->next, region))
1074 build_loop_iteration_domains (scop, loop->next, nb,
1075 isl_set_copy (outer), doms);
1076
1077 doms[loop->num] = inner;
1078
1079 isl_set_free (outer);
1080 isl_space_free (space);
1081 isl_int_clear (v);
1082 mpz_clear (g);
1083 }
1084
1085 /* Returns a linear expression for tree T evaluated in PBB. */
1086
1087 static isl_pw_aff *
1088 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1089 {
1090 scop_p scop = PBB_SCOP (pbb);
1091
1092 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1093 gcc_assert (!automatically_generated_chrec_p (t));
1094
1095 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1096 }
1097
1098 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1099 operator. This allows us to invert the condition or to handle
1100 inequalities. */
1101
1102 static void
1103 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1104 {
1105 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1106 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1107 isl_set *cond;
1108
1109 switch (code)
1110 {
1111 case LT_EXPR:
1112 cond = isl_pw_aff_lt_set (lhs, rhs);
1113 break;
1114
1115 case GT_EXPR:
1116 cond = isl_pw_aff_gt_set (lhs, rhs);
1117 break;
1118
1119 case LE_EXPR:
1120 cond = isl_pw_aff_le_set (lhs, rhs);
1121 break;
1122
1123 case GE_EXPR:
1124 cond = isl_pw_aff_ge_set (lhs, rhs);
1125 break;
1126
1127 case EQ_EXPR:
1128 cond = isl_pw_aff_eq_set (lhs, rhs);
1129 break;
1130
1131 case NE_EXPR:
1132 cond = isl_pw_aff_ne_set (lhs, rhs);
1133 break;
1134
1135 default:
1136 isl_pw_aff_free (lhs);
1137 isl_pw_aff_free (rhs);
1138 return;
1139 }
1140
1141 cond = isl_set_coalesce (cond);
1142 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1143 pbb->domain = isl_set_intersect (pbb->domain, cond);
1144 }
1145
1146 /* Add conditions to the domain of PBB. */
1147
1148 static void
1149 add_conditions_to_domain (poly_bb_p pbb)
1150 {
1151 unsigned int i;
1152 gimple stmt;
1153 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1154
1155 if (GBB_CONDITIONS (gbb).is_empty ())
1156 return;
1157
1158 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1159 switch (gimple_code (stmt))
1160 {
1161 case GIMPLE_COND:
1162 {
1163 enum tree_code code = gimple_cond_code (stmt);
1164
1165 /* The conditions for ELSE-branches are inverted. */
1166 if (!GBB_CONDITION_CASES (gbb)[i])
1167 code = invert_tree_comparison (code, false);
1168
1169 add_condition_to_pbb (pbb, stmt, code);
1170 break;
1171 }
1172
1173 case GIMPLE_SWITCH:
1174 /* Switch statements are not supported right now - fall through. */
1175
1176 default:
1177 gcc_unreachable ();
1178 break;
1179 }
1180 }
1181
1182 /* Traverses all the GBBs of the SCOP and add their constraints to the
1183 iteration domains. */
1184
1185 static void
1186 add_conditions_to_constraints (scop_p scop)
1187 {
1188 int i;
1189 poly_bb_p pbb;
1190
1191 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1192 add_conditions_to_domain (pbb);
1193 }
1194
1195 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1196 edge between BB and its predecessor is not a loop exit edge, and
1197 the last statement of the single predecessor is a COND_EXPR. */
1198
1199 static gimple
1200 single_pred_cond_non_loop_exit (basic_block bb)
1201 {
1202 if (single_pred_p (bb))
1203 {
1204 edge e = single_pred_edge (bb);
1205 basic_block pred = e->src;
1206 gimple stmt;
1207
1208 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1209 return NULL;
1210
1211 stmt = last_stmt (pred);
1212
1213 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1214 return stmt;
1215 }
1216
1217 return NULL;
1218 }
1219
1220 class sese_dom_walker : public dom_walker
1221 {
1222 public:
1223 sese_dom_walker (cdi_direction, sese);
1224 ~sese_dom_walker ();
1225
1226 virtual void before_dom_children (basic_block);
1227 virtual void after_dom_children (basic_block);
1228
1229 private:
1230 vec<gimple> m_conditions, m_cases;
1231 sese m_region;
1232 };
1233
1234 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1235 : dom_walker (direction), m_region (region)
1236 {
1237 m_conditions.create (3);
1238 m_cases.create (3);
1239 }
1240
1241 sese_dom_walker::~sese_dom_walker ()
1242 {
1243 m_conditions.release ();
1244 m_cases.release ();
1245 }
1246
1247 /* Call-back for dom_walk executed before visiting the dominated
1248 blocks. */
1249
1250 void
1251 sese_dom_walker::before_dom_children (basic_block bb)
1252 {
1253 gimple_bb_p gbb;
1254 gimple stmt;
1255
1256 if (!bb_in_sese_p (bb, m_region))
1257 return;
1258
1259 stmt = single_pred_cond_non_loop_exit (bb);
1260
1261 if (stmt)
1262 {
1263 edge e = single_pred_edge (bb);
1264
1265 m_conditions.safe_push (stmt);
1266
1267 if (e->flags & EDGE_TRUE_VALUE)
1268 m_cases.safe_push (stmt);
1269 else
1270 m_cases.safe_push (NULL);
1271 }
1272
1273 gbb = gbb_from_bb (bb);
1274
1275 if (gbb)
1276 {
1277 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1278 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1279 }
1280 }
1281
1282 /* Call-back for dom_walk executed after visiting the dominated
1283 blocks. */
1284
1285 void
1286 sese_dom_walker::after_dom_children (basic_block bb)
1287 {
1288 if (!bb_in_sese_p (bb, m_region))
1289 return;
1290
1291 if (single_pred_cond_non_loop_exit (bb))
1292 {
1293 m_conditions.pop ();
1294 m_cases.pop ();
1295 }
1296 }
1297
1298 /* Add constraints on the possible values of parameter P from the type
1299 of P. */
1300
1301 static void
1302 add_param_constraints (scop_p scop, graphite_dim_t p)
1303 {
1304 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1305 tree type = TREE_TYPE (parameter);
1306 tree lb = NULL_TREE;
1307 tree ub = NULL_TREE;
1308
1309 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1310 lb = lower_bound_in_type (type, type);
1311 else
1312 lb = TYPE_MIN_VALUE (type);
1313
1314 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1315 ub = upper_bound_in_type (type, type);
1316 else
1317 ub = TYPE_MAX_VALUE (type);
1318
1319 if (lb)
1320 {
1321 isl_space *space = isl_set_get_space (scop->context);
1322 isl_constraint *c;
1323 mpz_t g;
1324 isl_int v;
1325
1326 c = isl_inequality_alloc (isl_local_space_from_space (space));
1327 mpz_init (g);
1328 isl_int_init (v);
1329 tree_int_to_gmp (lb, g);
1330 isl_int_set_gmp (v, g);
1331 isl_int_neg (v, v);
1332 mpz_clear (g);
1333 c = isl_constraint_set_constant (c, v);
1334 isl_int_clear (v);
1335 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1336
1337 scop->context = isl_set_add_constraint (scop->context, c);
1338 }
1339
1340 if (ub)
1341 {
1342 isl_space *space = isl_set_get_space (scop->context);
1343 isl_constraint *c;
1344 mpz_t g;
1345 isl_int v;
1346
1347 c = isl_inequality_alloc (isl_local_space_from_space (space));
1348
1349 mpz_init (g);
1350 isl_int_init (v);
1351 tree_int_to_gmp (ub, g);
1352 isl_int_set_gmp (v, g);
1353 mpz_clear (g);
1354 c = isl_constraint_set_constant (c, v);
1355 isl_int_clear (v);
1356 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1357
1358 scop->context = isl_set_add_constraint (scop->context, c);
1359 }
1360 }
1361
1362 /* Build the context of the SCOP. The context usually contains extra
1363 constraints that are added to the iteration domains that constrain
1364 some parameters. */
1365
1366 static void
1367 build_scop_context (scop_p scop)
1368 {
1369 graphite_dim_t p, n = scop_nb_params (scop);
1370
1371 for (p = 0; p < n; p++)
1372 add_param_constraints (scop, p);
1373 }
1374
1375 /* Build the iteration domains: the loops belonging to the current
1376 SCOP, and that vary for the execution of the current basic block.
1377 Returns false if there is no loop in SCOP. */
1378
1379 static void
1380 build_scop_iteration_domain (scop_p scop)
1381 {
1382 struct loop *loop;
1383 sese region = SCOP_REGION (scop);
1384 int i;
1385 poly_bb_p pbb;
1386 int nb_loops = number_of_loops (cfun);
1387 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1388
1389 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1390 if (!loop_in_sese_p (loop_outer (loop), region))
1391 build_loop_iteration_domains (scop, loop, 0,
1392 isl_set_copy (scop->context), doms);
1393
1394 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1395 {
1396 loop = pbb_loop (pbb);
1397
1398 if (doms[loop->num])
1399 pbb->domain = isl_set_copy (doms[loop->num]);
1400 else
1401 pbb->domain = isl_set_copy (scop->context);
1402
1403 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1404 isl_id_for_pbb (scop, pbb));
1405 }
1406
1407 for (i = 0; i < nb_loops; i++)
1408 if (doms[i])
1409 isl_set_free (doms[i]);
1410
1411 free (doms);
1412 }
1413
1414 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1415 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1416 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1417 domain. */
1418
1419 static isl_map *
1420 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1421 {
1422 isl_constraint *c;
1423 int alias_set_num = 0;
1424 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1425
1426 if (bap && bap->alias_set)
1427 alias_set_num = *(bap->alias_set);
1428
1429 c = isl_equality_alloc
1430 (isl_local_space_from_space (isl_map_get_space (acc)));
1431 c = isl_constraint_set_constant_si (c, -alias_set_num);
1432 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1433
1434 return isl_map_add_constraint (acc, c);
1435 }
1436
1437 /* Assign the affine expression INDEX to the output dimension POS of
1438 MAP and return the result. */
1439
1440 static isl_map *
1441 set_index (isl_map *map, int pos, isl_pw_aff *index)
1442 {
1443 isl_map *index_map;
1444 int len = isl_map_dim (map, isl_dim_out);
1445 isl_id *id;
1446
1447 index_map = isl_map_from_pw_aff (index);
1448 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1449 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1450
1451 id = isl_map_get_tuple_id (map, isl_dim_out);
1452 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1453 id = isl_map_get_tuple_id (map, isl_dim_in);
1454 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1455
1456 return isl_map_intersect (map, index_map);
1457 }
1458
1459 /* Add to ACCESSES polyhedron equalities defining the access functions
1460 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1461 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1462 PBB is the poly_bb_p that contains the data reference DR. */
1463
1464 static isl_map *
1465 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1466 {
1467 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1468 scop_p scop = PBB_SCOP (pbb);
1469
1470 for (i = 0; i < nb_subscripts; i++)
1471 {
1472 isl_pw_aff *aff;
1473 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1474
1475 aff = extract_affine (scop, afn,
1476 isl_space_domain (isl_map_get_space (acc)));
1477 acc = set_index (acc, i + 1, aff);
1478 }
1479
1480 return acc;
1481 }
1482
1483 /* Add constrains representing the size of the accessed data to the
1484 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1485 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1486 domain. */
1487
1488 static isl_set *
1489 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1490 {
1491 tree ref = DR_REF (dr);
1492 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1493
1494 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1495 {
1496 tree low, high;
1497
1498 if (TREE_CODE (ref) != ARRAY_REF)
1499 break;
1500
1501 low = array_ref_low_bound (ref);
1502 high = array_ref_up_bound (ref);
1503
1504 /* XXX The PPL code dealt separately with
1505 subscript - low >= 0 and high - subscript >= 0 in case one of
1506 the two bounds isn't known. Do the same here? */
1507
1508 if (host_integerp (low, 0)
1509 && high
1510 && host_integerp (high, 0)
1511 /* 1-element arrays at end of structures may extend over
1512 their declared size. */
1513 && !(array_at_struct_end_p (ref)
1514 && operand_equal_p (low, high, 0)))
1515 {
1516 isl_id *id;
1517 isl_aff *aff;
1518 isl_set *univ, *lbs, *ubs;
1519 isl_pw_aff *index;
1520 isl_space *space;
1521 isl_set *valid;
1522 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1523 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1524
1525 /* high >= 0 */
1526 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1527 valid = isl_set_project_out (valid, isl_dim_set, 0,
1528 isl_set_dim (valid, isl_dim_set));
1529 scop->context = isl_set_intersect (scop->context, valid);
1530
1531 space = isl_set_get_space (extent);
1532 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1533 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1534 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1535 index = isl_pw_aff_alloc (univ, aff);
1536
1537 id = isl_set_get_tuple_id (extent);
1538 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1539 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1540
1541 /* low <= sub_i <= high */
1542 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1543 ubs = isl_pw_aff_le_set (index, ub);
1544 extent = isl_set_intersect (extent, lbs);
1545 extent = isl_set_intersect (extent, ubs);
1546 }
1547 }
1548
1549 return extent;
1550 }
1551
1552 /* Build data accesses for DR in PBB. */
1553
1554 static void
1555 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1556 {
1557 int dr_base_object_set;
1558 isl_map *acc;
1559 isl_set *extent;
1560 scop_p scop = PBB_SCOP (pbb);
1561
1562 {
1563 isl_space *dc = isl_set_get_space (pbb->domain);
1564 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1565 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1566 isl_dim_out, nb_out);
1567
1568 acc = isl_map_universe (space);
1569 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1570 }
1571
1572 acc = pdr_add_alias_set (acc, dr);
1573 acc = pdr_add_memory_accesses (acc, dr, pbb);
1574
1575 {
1576 isl_id *id = isl_id_for_dr (scop, dr);
1577 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1578 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1579 int alias_set_num = 0;
1580 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1581
1582 if (bap && bap->alias_set)
1583 alias_set_num = *(bap->alias_set);
1584
1585 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1586 extent = isl_set_nat_universe (space);
1587 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1588 extent = pdr_add_data_dimensions (extent, scop, dr);
1589 }
1590
1591 gcc_assert (dr->aux);
1592 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1593
1594 new_poly_dr (pbb, dr_base_object_set,
1595 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1596 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1597 }
1598
1599 /* Write to FILE the alias graph of data references in DIMACS format. */
1600
1601 static inline bool
1602 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1603 vec<data_reference_p> drs)
1604 {
1605 int num_vertex = drs.length ();
1606 int edge_num = 0;
1607 data_reference_p dr1, dr2;
1608 int i, j;
1609
1610 if (num_vertex == 0)
1611 return true;
1612
1613 FOR_EACH_VEC_ELT (drs, i, dr1)
1614 for (j = i + 1; drs.iterate (j, &dr2); j++)
1615 if (dr_may_alias_p (dr1, dr2, true))
1616 edge_num++;
1617
1618 fprintf (file, "$\n");
1619
1620 if (comment)
1621 fprintf (file, "c %s\n", comment);
1622
1623 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1624
1625 FOR_EACH_VEC_ELT (drs, i, dr1)
1626 for (j = i + 1; drs.iterate (j, &dr2); j++)
1627 if (dr_may_alias_p (dr1, dr2, true))
1628 fprintf (file, "e %d %d\n", i + 1, j + 1);
1629
1630 return true;
1631 }
1632
1633 /* Write to FILE the alias graph of data references in DOT format. */
1634
1635 static inline bool
1636 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1637 vec<data_reference_p> drs)
1638 {
1639 int num_vertex = drs.length ();
1640 data_reference_p dr1, dr2;
1641 int i, j;
1642
1643 if (num_vertex == 0)
1644 return true;
1645
1646 fprintf (file, "$\n");
1647
1648 if (comment)
1649 fprintf (file, "c %s\n", comment);
1650
1651 /* First print all the vertices. */
1652 FOR_EACH_VEC_ELT (drs, i, dr1)
1653 fprintf (file, "n%d;\n", i);
1654
1655 FOR_EACH_VEC_ELT (drs, i, dr1)
1656 for (j = i + 1; drs.iterate (j, &dr2); j++)
1657 if (dr_may_alias_p (dr1, dr2, true))
1658 fprintf (file, "n%d n%d\n", i, j);
1659
1660 return true;
1661 }
1662
1663 /* Write to FILE the alias graph of data references in ECC format. */
1664
1665 static inline bool
1666 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1667 vec<data_reference_p> drs)
1668 {
1669 int num_vertex = drs.length ();
1670 data_reference_p dr1, dr2;
1671 int i, j;
1672
1673 if (num_vertex == 0)
1674 return true;
1675
1676 fprintf (file, "$\n");
1677
1678 if (comment)
1679 fprintf (file, "c %s\n", comment);
1680
1681 FOR_EACH_VEC_ELT (drs, i, dr1)
1682 for (j = i + 1; drs.iterate (j, &dr2); j++)
1683 if (dr_may_alias_p (dr1, dr2, true))
1684 fprintf (file, "%d %d\n", i, j);
1685
1686 return true;
1687 }
1688
1689 /* Check if DR1 and DR2 are in the same object set. */
1690
1691 static bool
1692 dr_same_base_object_p (const struct data_reference *dr1,
1693 const struct data_reference *dr2)
1694 {
1695 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1696 }
1697
1698 /* Uses DFS component number as representative of alias-sets. Also tests for
1699 optimality by verifying if every connected component is a clique. Returns
1700 true (1) if the above test is true, and false (0) otherwise. */
1701
1702 static int
1703 build_alias_set_optimal_p (vec<data_reference_p> drs)
1704 {
1705 int num_vertices = drs.length ();
1706 struct graph *g = new_graph (num_vertices);
1707 data_reference_p dr1, dr2;
1708 int i, j;
1709 int num_connected_components;
1710 int v_indx1, v_indx2, num_vertices_in_component;
1711 int *all_vertices;
1712 int *vertices;
1713 struct graph_edge *e;
1714 int this_component_is_clique;
1715 int all_components_are_cliques = 1;
1716
1717 FOR_EACH_VEC_ELT (drs, i, dr1)
1718 for (j = i+1; drs.iterate (j, &dr2); j++)
1719 if (dr_may_alias_p (dr1, dr2, true))
1720 {
1721 add_edge (g, i, j);
1722 add_edge (g, j, i);
1723 }
1724
1725 all_vertices = XNEWVEC (int, num_vertices);
1726 vertices = XNEWVEC (int, num_vertices);
1727 for (i = 0; i < num_vertices; i++)
1728 all_vertices[i] = i;
1729
1730 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1731 NULL, true, NULL);
1732 for (i = 0; i < g->n_vertices; i++)
1733 {
1734 data_reference_p dr = drs[i];
1735 base_alias_pair *bap;
1736
1737 gcc_assert (dr->aux);
1738 bap = (base_alias_pair *)(dr->aux);
1739
1740 bap->alias_set = XNEW (int);
1741 *(bap->alias_set) = g->vertices[i].component + 1;
1742 }
1743
1744 /* Verify if the DFS numbering results in optimal solution. */
1745 for (i = 0; i < num_connected_components; i++)
1746 {
1747 num_vertices_in_component = 0;
1748 /* Get all vertices whose DFS component number is the same as i. */
1749 for (j = 0; j < num_vertices; j++)
1750 if (g->vertices[j].component == i)
1751 vertices[num_vertices_in_component++] = j;
1752
1753 /* Now test if the vertices in 'vertices' form a clique, by testing
1754 for edges among each pair. */
1755 this_component_is_clique = 1;
1756 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1757 {
1758 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1759 {
1760 /* Check if the two vertices are connected by iterating
1761 through all the edges which have one of these are source. */
1762 e = g->vertices[vertices[v_indx2]].pred;
1763 while (e)
1764 {
1765 if (e->src == vertices[v_indx1])
1766 break;
1767 e = e->pred_next;
1768 }
1769 if (!e)
1770 {
1771 this_component_is_clique = 0;
1772 break;
1773 }
1774 }
1775 if (!this_component_is_clique)
1776 all_components_are_cliques = 0;
1777 }
1778 }
1779
1780 free (all_vertices);
1781 free (vertices);
1782 free_graph (g);
1783 return all_components_are_cliques;
1784 }
1785
1786 /* Group each data reference in DRS with its base object set num. */
1787
1788 static void
1789 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1790 {
1791 int num_vertex = drs.length ();
1792 struct graph *g = new_graph (num_vertex);
1793 data_reference_p dr1, dr2;
1794 int i, j;
1795 int *queue;
1796
1797 FOR_EACH_VEC_ELT (drs, i, dr1)
1798 for (j = i + 1; drs.iterate (j, &dr2); j++)
1799 if (dr_same_base_object_p (dr1, dr2))
1800 {
1801 add_edge (g, i, j);
1802 add_edge (g, j, i);
1803 }
1804
1805 queue = XNEWVEC (int, num_vertex);
1806 for (i = 0; i < num_vertex; i++)
1807 queue[i] = i;
1808
1809 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1810
1811 for (i = 0; i < g->n_vertices; i++)
1812 {
1813 data_reference_p dr = drs[i];
1814 base_alias_pair *bap;
1815
1816 gcc_assert (dr->aux);
1817 bap = (base_alias_pair *)(dr->aux);
1818
1819 bap->base_obj_set = g->vertices[i].component + 1;
1820 }
1821
1822 free (queue);
1823 free_graph (g);
1824 }
1825
1826 /* Build the data references for PBB. */
1827
1828 static void
1829 build_pbb_drs (poly_bb_p pbb)
1830 {
1831 int j;
1832 data_reference_p dr;
1833 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1834
1835 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1836 build_poly_dr (dr, pbb);
1837 }
1838
1839 /* Dump to file the alias graphs for the data references in DRS. */
1840
1841 static void
1842 dump_alias_graphs (vec<data_reference_p> drs)
1843 {
1844 char comment[100];
1845 FILE *file_dimacs, *file_ecc, *file_dot;
1846
1847 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1848 if (file_dimacs)
1849 {
1850 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1851 current_function_name ());
1852 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1853 fclose (file_dimacs);
1854 }
1855
1856 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1857 if (file_ecc)
1858 {
1859 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1860 current_function_name ());
1861 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1862 fclose (file_ecc);
1863 }
1864
1865 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1866 if (file_dot)
1867 {
1868 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1869 current_function_name ());
1870 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1871 fclose (file_dot);
1872 }
1873 }
1874
1875 /* Build data references in SCOP. */
1876
1877 static void
1878 build_scop_drs (scop_p scop)
1879 {
1880 int i, j;
1881 poly_bb_p pbb;
1882 data_reference_p dr;
1883 vec<data_reference_p> drs;
1884 drs.create (3);
1885
1886 /* Remove all the PBBs that do not have data references: these basic
1887 blocks are not handled in the polyhedral representation. */
1888 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1889 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1890 {
1891 free_gimple_bb (PBB_BLACK_BOX (pbb));
1892 free_poly_bb (pbb);
1893 SCOP_BBS (scop).ordered_remove (i);
1894 i--;
1895 }
1896
1897 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1898 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1899 drs.safe_push (dr);
1900
1901 FOR_EACH_VEC_ELT (drs, i, dr)
1902 dr->aux = XNEW (base_alias_pair);
1903
1904 if (!build_alias_set_optimal_p (drs))
1905 {
1906 /* TODO: Add support when building alias set is not optimal. */
1907 ;
1908 }
1909
1910 build_base_obj_set_for_drs (drs);
1911
1912 /* When debugging, enable the following code. This cannot be used
1913 in production compilers. */
1914 if (0)
1915 dump_alias_graphs (drs);
1916
1917 drs.release ();
1918
1919 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1920 build_pbb_drs (pbb);
1921 }
1922
1923 /* Return a gsi at the position of the phi node STMT. */
1924
1925 static gimple_stmt_iterator
1926 gsi_for_phi_node (gimple stmt)
1927 {
1928 gimple_stmt_iterator psi;
1929 basic_block bb = gimple_bb (stmt);
1930
1931 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1932 if (stmt == gsi_stmt (psi))
1933 return psi;
1934
1935 gcc_unreachable ();
1936 return psi;
1937 }
1938
1939 /* Analyze all the data references of STMTS and add them to the
1940 GBB_DATA_REFS vector of BB. */
1941
1942 static void
1943 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1944 {
1945 loop_p nest;
1946 gimple_bb_p gbb;
1947 gimple stmt;
1948 int i;
1949 sese region = SCOP_REGION (scop);
1950
1951 if (!bb_in_sese_p (bb, region))
1952 return;
1953
1954 nest = outermost_loop_in_sese_1 (region, bb);
1955 gbb = gbb_from_bb (bb);
1956
1957 FOR_EACH_VEC_ELT (stmts, i, stmt)
1958 {
1959 loop_p loop;
1960
1961 if (is_gimple_debug (stmt))
1962 continue;
1963
1964 loop = loop_containing_stmt (stmt);
1965 if (!loop_in_sese_p (loop, region))
1966 loop = nest;
1967
1968 graphite_find_data_references_in_stmt (nest, loop, stmt,
1969 &GBB_DATA_REFS (gbb));
1970 }
1971 }
1972
1973 /* Insert STMT at the end of the STMTS sequence and then insert the
1974 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1975 on STMTS. */
1976
1977 static void
1978 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
1979 gimple_stmt_iterator insert_gsi)
1980 {
1981 gimple_stmt_iterator gsi;
1982 vec<gimple> x;
1983 x.create (3);
1984
1985 gimple_seq_add_stmt (&stmts, stmt);
1986 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1987 x.safe_push (gsi_stmt (gsi));
1988
1989 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
1990 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1991 x.release ();
1992 }
1993
1994 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
1995
1996 static void
1997 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
1998 {
1999 gimple_seq stmts;
2000 gimple_stmt_iterator gsi;
2001 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2002 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2003 vec<gimple> x;
2004 x.create (3);
2005
2006 gimple_seq_add_stmt (&stmts, stmt);
2007 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2008 x.safe_push (gsi_stmt (gsi));
2009
2010 if (gimple_code (after_stmt) == GIMPLE_PHI)
2011 {
2012 gsi = gsi_after_labels (gimple_bb (after_stmt));
2013 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2014 }
2015 else
2016 {
2017 gsi = gsi_for_stmt (after_stmt);
2018 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2019 }
2020
2021 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2022 x.release ();
2023 }
2024
2025 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2026
2027 static void
2028 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2029 {
2030 vec<data_reference_p> drs;
2031 drs.create (3);
2032 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2033 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2034 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2035 int index, n = SCOP_BBS (scop).length ();
2036
2037 /* The INDEX of PBB in SCOP_BBS. */
2038 for (index = 0; index < n; index++)
2039 if (SCOP_BBS (scop)[index] == pbb)
2040 break;
2041
2042 pbb1->domain = isl_set_copy (pbb->domain);
2043
2044 GBB_PBB (gbb1) = pbb1;
2045 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2046 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2047 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2048 }
2049
2050 /* Insert on edge E the assignment "RES := EXPR". */
2051
2052 static void
2053 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2054 {
2055 gimple_stmt_iterator gsi;
2056 gimple_seq stmts = NULL;
2057 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2058 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2059 basic_block bb;
2060 vec<gimple> x;
2061 x.create (3);
2062
2063 gimple_seq_add_stmt (&stmts, stmt);
2064 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2065 x.safe_push (gsi_stmt (gsi));
2066
2067 gsi_insert_seq_on_edge (e, stmts);
2068 gsi_commit_edge_inserts ();
2069 bb = gimple_bb (stmt);
2070
2071 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2072 return;
2073
2074 if (!gbb_from_bb (bb))
2075 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2076
2077 analyze_drs_in_stmts (scop, bb, x);
2078 x.release ();
2079 }
2080
2081 /* Creates a zero dimension array of the same type as VAR. */
2082
2083 static tree
2084 create_zero_dim_array (tree var, const char *base_name)
2085 {
2086 tree index_type = build_index_type (integer_zero_node);
2087 tree elt_type = TREE_TYPE (var);
2088 tree array_type = build_array_type (elt_type, index_type);
2089 tree base = create_tmp_var (array_type, base_name);
2090
2091 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2092 NULL_TREE);
2093 }
2094
2095 /* Returns true when PHI is a loop close phi node. */
2096
2097 static bool
2098 scalar_close_phi_node_p (gimple phi)
2099 {
2100 if (gimple_code (phi) != GIMPLE_PHI
2101 || virtual_operand_p (gimple_phi_result (phi)))
2102 return false;
2103
2104 /* Note that loop close phi nodes should have a single argument
2105 because we translated the representation into a canonical form
2106 before Graphite: see canonicalize_loop_closed_ssa_form. */
2107 return (gimple_phi_num_args (phi) == 1);
2108 }
2109
2110 /* For a definition DEF in REGION, propagates the expression EXPR in
2111 all the uses of DEF outside REGION. */
2112
2113 static void
2114 propagate_expr_outside_region (tree def, tree expr, sese region)
2115 {
2116 imm_use_iterator imm_iter;
2117 gimple use_stmt;
2118 gimple_seq stmts;
2119 bool replaced_once = false;
2120
2121 gcc_assert (TREE_CODE (def) == SSA_NAME);
2122
2123 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2124 NULL_TREE);
2125
2126 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2127 if (!is_gimple_debug (use_stmt)
2128 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2129 {
2130 ssa_op_iter iter;
2131 use_operand_p use_p;
2132
2133 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2134 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2135 && (replaced_once = true))
2136 replace_exp (use_p, expr);
2137
2138 update_stmt (use_stmt);
2139 }
2140
2141 if (replaced_once)
2142 {
2143 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2144 gsi_commit_edge_inserts ();
2145 }
2146 }
2147
2148 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2149 dimension array for it. */
2150
2151 static void
2152 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2153 {
2154 sese region = SCOP_REGION (scop);
2155 gimple phi = gsi_stmt (*psi);
2156 tree res = gimple_phi_result (phi);
2157 basic_block bb = gimple_bb (phi);
2158 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2159 tree arg = gimple_phi_arg_def (phi, 0);
2160 gimple stmt;
2161
2162 /* Note that loop close phi nodes should have a single argument
2163 because we translated the representation into a canonical form
2164 before Graphite: see canonicalize_loop_closed_ssa_form. */
2165 gcc_assert (gimple_phi_num_args (phi) == 1);
2166
2167 /* The phi node can be a non close phi node, when its argument is
2168 invariant, or a default definition. */
2169 if (is_gimple_min_invariant (arg)
2170 || SSA_NAME_IS_DEFAULT_DEF (arg))
2171 {
2172 propagate_expr_outside_region (res, arg, region);
2173 gsi_next (psi);
2174 return;
2175 }
2176
2177 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2178 {
2179 propagate_expr_outside_region (res, arg, region);
2180 stmt = gimple_build_assign (res, arg);
2181 remove_phi_node (psi, false);
2182 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2183 SSA_NAME_DEF_STMT (res) = stmt;
2184 return;
2185 }
2186
2187 /* If res is scev analyzable and is not a scalar value, it is safe
2188 to ignore the close phi node: it will be code generated in the
2189 out of Graphite pass. */
2190 else if (scev_analyzable_p (res, region))
2191 {
2192 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2193 tree scev;
2194
2195 if (!loop_in_sese_p (loop, region))
2196 {
2197 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2198 scev = scalar_evolution_in_region (region, loop, arg);
2199 scev = compute_overall_effect_of_inner_loop (loop, scev);
2200 }
2201 else
2202 scev = scalar_evolution_in_region (region, loop, res);
2203
2204 if (tree_does_not_contain_chrecs (scev))
2205 propagate_expr_outside_region (res, scev, region);
2206
2207 gsi_next (psi);
2208 return;
2209 }
2210 else
2211 {
2212 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2213
2214 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2215
2216 if (TREE_CODE (arg) == SSA_NAME)
2217 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2218 SSA_NAME_DEF_STMT (arg));
2219 else
2220 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2221 zero_dim_array, arg);
2222 }
2223
2224 remove_phi_node (psi, false);
2225 SSA_NAME_DEF_STMT (res) = stmt;
2226
2227 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2228 }
2229
2230 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2231 dimension array for it. */
2232
2233 static void
2234 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2235 {
2236 size_t i;
2237 gimple phi = gsi_stmt (*psi);
2238 basic_block bb = gimple_bb (phi);
2239 tree res = gimple_phi_result (phi);
2240 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2241 gimple stmt;
2242
2243 for (i = 0; i < gimple_phi_num_args (phi); i++)
2244 {
2245 tree arg = gimple_phi_arg_def (phi, i);
2246 edge e = gimple_phi_arg_edge (phi, i);
2247
2248 /* Avoid the insertion of code in the loop latch to please the
2249 pattern matching of the vectorizer. */
2250 if (TREE_CODE (arg) == SSA_NAME
2251 && e->src == bb->loop_father->latch)
2252 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2253 SSA_NAME_DEF_STMT (arg));
2254 else
2255 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2256 }
2257
2258 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2259 remove_phi_node (psi, false);
2260 SSA_NAME_DEF_STMT (res) = stmt;
2261 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2262 }
2263
2264 /* Rewrite the degenerate phi node at position PSI from the degenerate
2265 form "x = phi (y, y, ..., y)" to "x = y". */
2266
2267 static void
2268 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2269 {
2270 tree rhs;
2271 gimple stmt;
2272 gimple_stmt_iterator gsi;
2273 gimple phi = gsi_stmt (*psi);
2274 tree res = gimple_phi_result (phi);
2275 basic_block bb;
2276
2277 bb = gimple_bb (phi);
2278 rhs = degenerate_phi_result (phi);
2279 gcc_assert (rhs);
2280
2281 stmt = gimple_build_assign (res, rhs);
2282 remove_phi_node (psi, false);
2283 SSA_NAME_DEF_STMT (res) = stmt;
2284
2285 gsi = gsi_after_labels (bb);
2286 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2287 }
2288
2289 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2290
2291 static void
2292 rewrite_reductions_out_of_ssa (scop_p scop)
2293 {
2294 basic_block bb;
2295 gimple_stmt_iterator psi;
2296 sese region = SCOP_REGION (scop);
2297
2298 FOR_EACH_BB (bb)
2299 if (bb_in_sese_p (bb, region))
2300 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2301 {
2302 gimple phi = gsi_stmt (psi);
2303
2304 if (virtual_operand_p (gimple_phi_result (phi)))
2305 {
2306 gsi_next (&psi);
2307 continue;
2308 }
2309
2310 if (gimple_phi_num_args (phi) > 1
2311 && degenerate_phi_result (phi))
2312 rewrite_degenerate_phi (&psi);
2313
2314 else if (scalar_close_phi_node_p (phi))
2315 rewrite_close_phi_out_of_ssa (scop, &psi);
2316
2317 else if (reduction_phi_p (region, &psi))
2318 rewrite_phi_out_of_ssa (scop, &psi);
2319 }
2320
2321 update_ssa (TODO_update_ssa);
2322 #ifdef ENABLE_CHECKING
2323 verify_loop_closed_ssa (true);
2324 #endif
2325 }
2326
2327 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2328 read from ZERO_DIM_ARRAY. */
2329
2330 static void
2331 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2332 tree def, gimple use_stmt)
2333 {
2334 gimple name_stmt;
2335 tree name;
2336 ssa_op_iter iter;
2337 use_operand_p use_p;
2338
2339 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2340
2341 name = copy_ssa_name (def, NULL);
2342 name_stmt = gimple_build_assign (name, zero_dim_array);
2343
2344 gimple_assign_set_lhs (name_stmt, name);
2345 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2346
2347 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2348 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2349 replace_exp (use_p, name);
2350
2351 update_stmt (use_stmt);
2352 }
2353
2354 /* For every definition DEF in the SCOP that is used outside the scop,
2355 insert a closing-scop definition in the basic block just after this
2356 SCOP. */
2357
2358 static void
2359 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2360 {
2361 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2362 tree new_name = make_ssa_name (var, stmt);
2363 bool needs_copy = false;
2364 use_operand_p use_p;
2365 imm_use_iterator imm_iter;
2366 gimple use_stmt;
2367 sese region = SCOP_REGION (scop);
2368
2369 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2370 {
2371 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2372 {
2373 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2374 {
2375 SET_USE (use_p, new_name);
2376 }
2377 update_stmt (use_stmt);
2378 needs_copy = true;
2379 }
2380 }
2381
2382 /* Insert in the empty BB just after the scop a use of DEF such
2383 that the rewrite of cross_bb_scalar_dependences won't insert
2384 arrays everywhere else. */
2385 if (needs_copy)
2386 {
2387 gimple assign = gimple_build_assign (new_name, def);
2388 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2389
2390 SSA_NAME_DEF_STMT (new_name) = assign;
2391 update_stmt (assign);
2392 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2393 }
2394 }
2395
2396 /* Rewrite the scalar dependences crossing the boundary of the BB
2397 containing STMT with an array. Return true when something has been
2398 changed. */
2399
2400 static bool
2401 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2402 {
2403 sese region = SCOP_REGION (scop);
2404 gimple stmt = gsi_stmt (*gsi);
2405 imm_use_iterator imm_iter;
2406 tree def;
2407 basic_block def_bb;
2408 tree zero_dim_array = NULL_TREE;
2409 gimple use_stmt;
2410 bool res = false;
2411
2412 switch (gimple_code (stmt))
2413 {
2414 case GIMPLE_ASSIGN:
2415 def = gimple_assign_lhs (stmt);
2416 break;
2417
2418 case GIMPLE_CALL:
2419 def = gimple_call_lhs (stmt);
2420 break;
2421
2422 default:
2423 return false;
2424 }
2425
2426 if (!def
2427 || !is_gimple_reg (def))
2428 return false;
2429
2430 if (scev_analyzable_p (def, region))
2431 {
2432 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2433 tree scev = scalar_evolution_in_region (region, loop, def);
2434
2435 if (tree_contains_chrecs (scev, NULL))
2436 return false;
2437
2438 propagate_expr_outside_region (def, scev, region);
2439 return true;
2440 }
2441
2442 def_bb = gimple_bb (stmt);
2443
2444 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2445
2446 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2447 if (gimple_code (use_stmt) == GIMPLE_PHI
2448 && (res = true))
2449 {
2450 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2451
2452 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2453 rewrite_close_phi_out_of_ssa (scop, &psi);
2454 else
2455 rewrite_phi_out_of_ssa (scop, &psi);
2456 }
2457
2458 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2459 if (gimple_code (use_stmt) != GIMPLE_PHI
2460 && def_bb != gimple_bb (use_stmt)
2461 && !is_gimple_debug (use_stmt)
2462 && (res = true))
2463 {
2464 if (!zero_dim_array)
2465 {
2466 zero_dim_array = create_zero_dim_array
2467 (def, "Cross_BB_scalar_dependence");
2468 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2469 SSA_NAME_DEF_STMT (def));
2470 gsi_next (gsi);
2471 }
2472
2473 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2474 def, use_stmt);
2475 }
2476
2477 return res;
2478 }
2479
2480 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2481
2482 static void
2483 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2484 {
2485 basic_block bb;
2486 gimple_stmt_iterator psi;
2487 sese region = SCOP_REGION (scop);
2488 bool changed = false;
2489
2490 /* Create an extra empty BB after the scop. */
2491 split_edge (SESE_EXIT (region));
2492
2493 FOR_EACH_BB (bb)
2494 if (bb_in_sese_p (bb, region))
2495 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2496 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2497
2498 if (changed)
2499 {
2500 scev_reset_htab ();
2501 update_ssa (TODO_update_ssa);
2502 #ifdef ENABLE_CHECKING
2503 verify_loop_closed_ssa (true);
2504 #endif
2505 }
2506 }
2507
2508 /* Returns the number of pbbs that are in loops contained in SCOP. */
2509
2510 static int
2511 nb_pbbs_in_loops (scop_p scop)
2512 {
2513 int i;
2514 poly_bb_p pbb;
2515 int res = 0;
2516
2517 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2518 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2519 res++;
2520
2521 return res;
2522 }
2523
2524 /* Return the number of data references in BB that write in
2525 memory. */
2526
2527 static int
2528 nb_data_writes_in_bb (basic_block bb)
2529 {
2530 int res = 0;
2531 gimple_stmt_iterator gsi;
2532
2533 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2534 if (gimple_vdef (gsi_stmt (gsi)))
2535 res++;
2536
2537 return res;
2538 }
2539
2540 /* Splits at STMT the basic block BB represented as PBB in the
2541 polyhedral form. */
2542
2543 static edge
2544 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2545 {
2546 edge e1 = split_block (bb, stmt);
2547 new_pbb_from_pbb (scop, pbb, e1->dest);
2548 return e1;
2549 }
2550
2551 /* Splits STMT out of its current BB. This is done for reduction
2552 statements for which we want to ignore data dependences. */
2553
2554 static basic_block
2555 split_reduction_stmt (scop_p scop, gimple stmt)
2556 {
2557 basic_block bb = gimple_bb (stmt);
2558 poly_bb_p pbb = pbb_from_bb (bb);
2559 gimple_bb_p gbb = gbb_from_bb (bb);
2560 edge e1;
2561 int i;
2562 data_reference_p dr;
2563
2564 /* Do not split basic blocks with no writes to memory: the reduction
2565 will be the only write to memory. */
2566 if (nb_data_writes_in_bb (bb) == 0
2567 /* Or if we have already marked BB as a reduction. */
2568 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2569 return bb;
2570
2571 e1 = split_pbb (scop, pbb, bb, stmt);
2572
2573 /* Split once more only when the reduction stmt is not the only one
2574 left in the original BB. */
2575 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2576 {
2577 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2578 gsi_prev (&gsi);
2579 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2580 }
2581
2582 /* A part of the data references will end in a different basic block
2583 after the split: move the DRs from the original GBB to the newly
2584 created GBB1. */
2585 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2586 {
2587 basic_block bb1 = gimple_bb (DR_STMT (dr));
2588
2589 if (bb1 != bb)
2590 {
2591 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2592 GBB_DATA_REFS (gbb1).safe_push (dr);
2593 GBB_DATA_REFS (gbb).ordered_remove (i);
2594 i--;
2595 }
2596 }
2597
2598 return e1->dest;
2599 }
2600
2601 /* Return true when stmt is a reduction operation. */
2602
2603 static inline bool
2604 is_reduction_operation_p (gimple stmt)
2605 {
2606 enum tree_code code;
2607
2608 gcc_assert (is_gimple_assign (stmt));
2609 code = gimple_assign_rhs_code (stmt);
2610
2611 return flag_associative_math
2612 && commutative_tree_code (code)
2613 && associative_tree_code (code);
2614 }
2615
2616 /* Returns true when PHI contains an argument ARG. */
2617
2618 static bool
2619 phi_contains_arg (gimple phi, tree arg)
2620 {
2621 size_t i;
2622
2623 for (i = 0; i < gimple_phi_num_args (phi); i++)
2624 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2625 return true;
2626
2627 return false;
2628 }
2629
2630 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2631
2632 static gimple
2633 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2634 {
2635 gimple stmt;
2636
2637 if (TREE_CODE (arg) != SSA_NAME)
2638 return NULL;
2639
2640 stmt = SSA_NAME_DEF_STMT (arg);
2641
2642 if (gimple_code (stmt) == GIMPLE_NOP
2643 || gimple_code (stmt) == GIMPLE_CALL)
2644 return NULL;
2645
2646 if (gimple_code (stmt) == GIMPLE_PHI)
2647 {
2648 if (phi_contains_arg (stmt, lhs))
2649 return stmt;
2650 return NULL;
2651 }
2652
2653 if (!is_gimple_assign (stmt))
2654 return NULL;
2655
2656 if (gimple_num_ops (stmt) == 2)
2657 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2658
2659 if (is_reduction_operation_p (stmt))
2660 {
2661 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2662
2663 return res ? res :
2664 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2665 }
2666
2667 return NULL;
2668 }
2669
2670 /* Detect commutative and associative scalar reductions starting at
2671 the STMT. Return the phi node of the reduction cycle, or NULL. */
2672
2673 static gimple
2674 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2675 vec<gimple> *in,
2676 vec<gimple> *out)
2677 {
2678 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2679
2680 if (!phi)
2681 return NULL;
2682
2683 in->safe_push (stmt);
2684 out->safe_push (stmt);
2685 return phi;
2686 }
2687
2688 /* Detect commutative and associative scalar reductions starting at
2689 STMT. Return the phi node of the reduction cycle, or NULL. */
2690
2691 static gimple
2692 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2693 vec<gimple> *out)
2694 {
2695 tree lhs = gimple_assign_lhs (stmt);
2696
2697 if (gimple_num_ops (stmt) == 2)
2698 return detect_commutative_reduction_arg (lhs, stmt,
2699 gimple_assign_rhs1 (stmt),
2700 in, out);
2701
2702 if (is_reduction_operation_p (stmt))
2703 {
2704 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2705 gimple_assign_rhs1 (stmt),
2706 in, out);
2707 return res ? res
2708 : detect_commutative_reduction_arg (lhs, stmt,
2709 gimple_assign_rhs2 (stmt),
2710 in, out);
2711 }
2712
2713 return NULL;
2714 }
2715
2716 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2717
2718 static gimple
2719 follow_inital_value_to_phi (tree arg, tree lhs)
2720 {
2721 gimple stmt;
2722
2723 if (!arg || TREE_CODE (arg) != SSA_NAME)
2724 return NULL;
2725
2726 stmt = SSA_NAME_DEF_STMT (arg);
2727
2728 if (gimple_code (stmt) == GIMPLE_PHI
2729 && phi_contains_arg (stmt, lhs))
2730 return stmt;
2731
2732 return NULL;
2733 }
2734
2735
2736 /* Return the argument of the loop PHI that is the initial value coming
2737 from outside the loop. */
2738
2739 static edge
2740 edge_initial_value_for_loop_phi (gimple phi)
2741 {
2742 size_t i;
2743
2744 for (i = 0; i < gimple_phi_num_args (phi); i++)
2745 {
2746 edge e = gimple_phi_arg_edge (phi, i);
2747
2748 if (loop_depth (e->src->loop_father)
2749 < loop_depth (e->dest->loop_father))
2750 return e;
2751 }
2752
2753 return NULL;
2754 }
2755
2756 /* Return the argument of the loop PHI that is the initial value coming
2757 from outside the loop. */
2758
2759 static tree
2760 initial_value_for_loop_phi (gimple phi)
2761 {
2762 size_t i;
2763
2764 for (i = 0; i < gimple_phi_num_args (phi); i++)
2765 {
2766 edge e = gimple_phi_arg_edge (phi, i);
2767
2768 if (loop_depth (e->src->loop_father)
2769 < loop_depth (e->dest->loop_father))
2770 return gimple_phi_arg_def (phi, i);
2771 }
2772
2773 return NULL_TREE;
2774 }
2775
2776 /* Returns true when DEF is used outside the reduction cycle of
2777 LOOP_PHI. */
2778
2779 static bool
2780 used_outside_reduction (tree def, gimple loop_phi)
2781 {
2782 use_operand_p use_p;
2783 imm_use_iterator imm_iter;
2784 loop_p loop = loop_containing_stmt (loop_phi);
2785
2786 /* In LOOP, DEF should be used only in LOOP_PHI. */
2787 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2788 {
2789 gimple stmt = USE_STMT (use_p);
2790
2791 if (stmt != loop_phi
2792 && !is_gimple_debug (stmt)
2793 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2794 return true;
2795 }
2796
2797 return false;
2798 }
2799
2800 /* Detect commutative and associative scalar reductions belonging to
2801 the SCOP starting at the loop closed phi node STMT. Return the phi
2802 node of the reduction cycle, or NULL. */
2803
2804 static gimple
2805 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2806 vec<gimple> *out)
2807 {
2808 if (scalar_close_phi_node_p (stmt))
2809 {
2810 gimple def, loop_phi, phi, close_phi = stmt;
2811 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2812
2813 if (TREE_CODE (arg) != SSA_NAME)
2814 return NULL;
2815
2816 /* Note that loop close phi nodes should have a single argument
2817 because we translated the representation into a canonical form
2818 before Graphite: see canonicalize_loop_closed_ssa_form. */
2819 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2820
2821 def = SSA_NAME_DEF_STMT (arg);
2822 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2823 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2824 return NULL;
2825
2826 lhs = gimple_phi_result (close_phi);
2827 init = initial_value_for_loop_phi (loop_phi);
2828 phi = follow_inital_value_to_phi (init, lhs);
2829
2830 if (phi && (used_outside_reduction (lhs, phi)
2831 || !has_single_use (gimple_phi_result (phi))))
2832 return NULL;
2833
2834 in->safe_push (loop_phi);
2835 out->safe_push (close_phi);
2836 return phi;
2837 }
2838
2839 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2840 return detect_commutative_reduction_assign (stmt, in, out);
2841
2842 return NULL;
2843 }
2844
2845 /* Translate the scalar reduction statement STMT to an array RED
2846 knowing that its recursive phi node is LOOP_PHI. */
2847
2848 static void
2849 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2850 gimple stmt, gimple loop_phi)
2851 {
2852 tree res = gimple_phi_result (loop_phi);
2853 gimple assign = gimple_build_assign (res, unshare_expr (red));
2854 gimple_stmt_iterator gsi;
2855
2856 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2857
2858 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2859 gsi = gsi_for_stmt (stmt);
2860 gsi_next (&gsi);
2861 insert_stmts (scop, assign, NULL, gsi);
2862 }
2863
2864 /* Removes the PHI node and resets all the debug stmts that are using
2865 the PHI_RESULT. */
2866
2867 static void
2868 remove_phi (gimple phi)
2869 {
2870 imm_use_iterator imm_iter;
2871 tree def;
2872 use_operand_p use_p;
2873 gimple_stmt_iterator gsi;
2874 vec<gimple> update;
2875 update.create (3);
2876 unsigned int i;
2877 gimple stmt;
2878
2879 def = PHI_RESULT (phi);
2880 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2881 {
2882 stmt = USE_STMT (use_p);
2883
2884 if (is_gimple_debug (stmt))
2885 {
2886 gimple_debug_bind_reset_value (stmt);
2887 update.safe_push (stmt);
2888 }
2889 }
2890
2891 FOR_EACH_VEC_ELT (update, i, stmt)
2892 update_stmt (stmt);
2893
2894 update.release ();
2895
2896 gsi = gsi_for_phi_node (phi);
2897 remove_phi_node (&gsi, false);
2898 }
2899
2900 /* Helper function for for_each_index. For each INDEX of the data
2901 reference REF, returns true when its indices are valid in the loop
2902 nest LOOP passed in as DATA. */
2903
2904 static bool
2905 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2906 {
2907 loop_p loop;
2908 basic_block header, def_bb;
2909 gimple stmt;
2910
2911 if (TREE_CODE (*index) != SSA_NAME)
2912 return true;
2913
2914 loop = *((loop_p *) data);
2915 header = loop->header;
2916 stmt = SSA_NAME_DEF_STMT (*index);
2917
2918 if (!stmt)
2919 return true;
2920
2921 def_bb = gimple_bb (stmt);
2922
2923 if (!def_bb)
2924 return true;
2925
2926 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2927 }
2928
2929 /* When the result of a CLOSE_PHI is written to a memory location,
2930 return a pointer to that memory reference, otherwise return
2931 NULL_TREE. */
2932
2933 static tree
2934 close_phi_written_to_memory (gimple close_phi)
2935 {
2936 imm_use_iterator imm_iter;
2937 use_operand_p use_p;
2938 gimple stmt;
2939 tree res, def = gimple_phi_result (close_phi);
2940
2941 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2942 if ((stmt = USE_STMT (use_p))
2943 && gimple_code (stmt) == GIMPLE_ASSIGN
2944 && (res = gimple_assign_lhs (stmt)))
2945 {
2946 switch (TREE_CODE (res))
2947 {
2948 case VAR_DECL:
2949 case PARM_DECL:
2950 case RESULT_DECL:
2951 return res;
2952
2953 case ARRAY_REF:
2954 case MEM_REF:
2955 {
2956 tree arg = gimple_phi_arg_def (close_phi, 0);
2957 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2958
2959 /* FIXME: this restriction is for id-{24,25}.f and
2960 could be handled by duplicating the computation of
2961 array indices before the loop of the close_phi. */
2962 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2963 return res;
2964 }
2965 /* Fallthru. */
2966
2967 default:
2968 continue;
2969 }
2970 }
2971 return NULL_TREE;
2972 }
2973
2974 /* Rewrite out of SSA the reduction described by the loop phi nodes
2975 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2976 levels like this:
2977
2978 IN: stmt, loop_n, ..., loop_0
2979 OUT: stmt, close_n, ..., close_0
2980
2981 the first element is the reduction statement, and the next elements
2982 are the loop and close phi nodes of each of the outer loops. */
2983
2984 static void
2985 translate_scalar_reduction_to_array (scop_p scop,
2986 vec<gimple> in,
2987 vec<gimple> out)
2988 {
2989 gimple loop_phi;
2990 unsigned int i = out.length () - 1;
2991 tree red = close_phi_written_to_memory (out[i]);
2992
2993 FOR_EACH_VEC_ELT (in, i, loop_phi)
2994 {
2995 gimple close_phi = out[i];
2996
2997 if (i == 0)
2998 {
2999 gimple stmt = loop_phi;
3000 basic_block bb = split_reduction_stmt (scop, stmt);
3001 poly_bb_p pbb = pbb_from_bb (bb);
3002 PBB_IS_REDUCTION (pbb) = true;
3003 gcc_assert (close_phi == loop_phi);
3004
3005 if (!red)
3006 red = create_zero_dim_array
3007 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3008
3009 translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
3010 continue;
3011 }
3012
3013 if (i == in.length () - 1)
3014 {
3015 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3016 unshare_expr (red), close_phi);
3017 insert_out_of_ssa_copy_on_edge
3018 (scop, edge_initial_value_for_loop_phi (loop_phi),
3019 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3020 }
3021
3022 remove_phi (loop_phi);
3023 remove_phi (close_phi);
3024 }
3025 }
3026
3027 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3028 true when something has been changed. */
3029
3030 static bool
3031 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3032 gimple close_phi)
3033 {
3034 bool res;
3035 vec<gimple> in;
3036 in.create (10);
3037 vec<gimple> out;
3038 out.create (10);
3039
3040 detect_commutative_reduction (scop, close_phi, &in, &out);
3041 res = in.length () > 1;
3042 if (res)
3043 translate_scalar_reduction_to_array (scop, in, out);
3044
3045 in.release ();
3046 out.release ();
3047 return res;
3048 }
3049
3050 /* Rewrites all the commutative reductions from LOOP out of SSA.
3051 Returns true when something has been changed. */
3052
3053 static bool
3054 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3055 loop_p loop)
3056 {
3057 gimple_stmt_iterator gsi;
3058 edge exit = single_exit (loop);
3059 tree res;
3060 bool changed = false;
3061
3062 if (!exit)
3063 return false;
3064
3065 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3066 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3067 && !virtual_operand_p (res)
3068 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3069 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3070 (scop, gsi_stmt (gsi));
3071
3072 return changed;
3073 }
3074
3075 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3076
3077 static void
3078 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3079 {
3080 loop_iterator li;
3081 loop_p loop;
3082 bool changed = false;
3083 sese region = SCOP_REGION (scop);
3084
3085 FOR_EACH_LOOP (li, loop, 0)
3086 if (loop_in_sese_p (loop, region))
3087 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3088
3089 if (changed)
3090 {
3091 scev_reset_htab ();
3092 gsi_commit_edge_inserts ();
3093 update_ssa (TODO_update_ssa);
3094 #ifdef ENABLE_CHECKING
3095 verify_loop_closed_ssa (true);
3096 #endif
3097 }
3098 }
3099
3100 /* Can all ivs be represented by a signed integer?
3101 As CLooG might generate negative values in its expressions, signed loop ivs
3102 are required in the backend. */
3103
3104 static bool
3105 scop_ivs_can_be_represented (scop_p scop)
3106 {
3107 loop_iterator li;
3108 loop_p loop;
3109 gimple_stmt_iterator psi;
3110 bool result = true;
3111
3112 FOR_EACH_LOOP (li, loop, 0)
3113 {
3114 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3115 continue;
3116
3117 for (psi = gsi_start_phis (loop->header);
3118 !gsi_end_p (psi); gsi_next (&psi))
3119 {
3120 gimple phi = gsi_stmt (psi);
3121 tree res = PHI_RESULT (phi);
3122 tree type = TREE_TYPE (res);
3123
3124 if (TYPE_UNSIGNED (type)
3125 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3126 {
3127 result = false;
3128 break;
3129 }
3130 }
3131 if (!result)
3132 FOR_EACH_LOOP_BREAK (li);
3133 }
3134
3135 return result;
3136 }
3137
3138 /* Builds the polyhedral representation for a SESE region. */
3139
3140 void
3141 build_poly_scop (scop_p scop)
3142 {
3143 sese region = SCOP_REGION (scop);
3144 graphite_dim_t max_dim;
3145
3146 build_scop_bbs (scop);
3147
3148 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3149 Once CLooG is fixed, remove this guard. Anyways, it makes no
3150 sense to optimize a scop containing only PBBs that do not belong
3151 to any loops. */
3152 if (nb_pbbs_in_loops (scop) == 0)
3153 return;
3154
3155 if (!scop_ivs_can_be_represented (scop))
3156 return;
3157
3158 if (flag_associative_math)
3159 rewrite_commutative_reductions_out_of_ssa (scop);
3160
3161 build_sese_loop_nests (region);
3162 /* Record all conditions in REGION. */
3163 sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
3164 find_scop_parameters (scop);
3165
3166 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3167 if (scop_nb_params (scop) > max_dim)
3168 return;
3169
3170 build_scop_iteration_domain (scop);
3171 build_scop_context (scop);
3172 add_conditions_to_constraints (scop);
3173
3174 /* Rewrite out of SSA only after having translated the
3175 representation to the polyhedral representation to avoid scev
3176 analysis failures. That means that these functions will insert
3177 new data references that they create in the right place. */
3178 rewrite_reductions_out_of_ssa (scop);
3179 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3180
3181 build_scop_drs (scop);
3182 scop_to_lst (scop);
3183 build_scop_scattering (scop);
3184
3185 /* This SCoP has been translated to the polyhedral
3186 representation. */
3187 POLY_SCOP_P (scop) = true;
3188 }
3189 #endif