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