sched-rgn.c (add_branch_dependences): Keep insns in a SCHED_GROUP at the end of BB...
[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-ssa.h"
39 #include "tree-cfg.h"
40 #include "tree-phinodes.h"
41 #include "ssa-iterators.h"
42 #include "tree-ssanames.h"
43 #include "tree-ssa-loop-manip.h"
44 #include "tree-ssa-loop-niter.h"
45 #include "tree-ssa-loop.h"
46 #include "tree-into-ssa.h"
47 #include "tree-pass.h"
48 #include "cfgloop.h"
49 #include "tree-chrec.h"
50 #include "tree-data-ref.h"
51 #include "tree-scalar-evolution.h"
52 #include "domwalk.h"
53 #include "sese.h"
54 #include "tree-ssa-propagate.h"
55
56 #ifdef HAVE_cloog
57 #include "graphite-poly.h"
58 #include "graphite-sese-to-poly.h"
59
60
61 /* Assigns to RES the value of the INTEGER_CST T. */
62
63 static inline void
64 tree_int_to_gmp (tree t, mpz_t res)
65 {
66 double_int di = tree_to_double_int (t);
67 mpz_set_double_int (res, di, TYPE_UNSIGNED (TREE_TYPE (t)));
68 }
69
70 /* Returns the index of the PHI argument defined in the outermost
71 loop. */
72
73 static size_t
74 phi_arg_in_outermost_loop (gimple phi)
75 {
76 loop_p loop = gimple_bb (phi)->loop_father;
77 size_t i, res = 0;
78
79 for (i = 0; i < gimple_phi_num_args (phi); i++)
80 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
81 {
82 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
83 res = i;
84 }
85
86 return res;
87 }
88
89 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
90 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
91
92 static void
93 remove_simple_copy_phi (gimple_stmt_iterator *psi)
94 {
95 gimple phi = gsi_stmt (*psi);
96 tree res = gimple_phi_result (phi);
97 size_t entry = phi_arg_in_outermost_loop (phi);
98 tree init = gimple_phi_arg_def (phi, entry);
99 gimple stmt = gimple_build_assign (res, init);
100 edge e = gimple_phi_arg_edge (phi, entry);
101
102 remove_phi_node (psi, false);
103 gsi_insert_on_edge_immediate (e, stmt);
104 SSA_NAME_DEF_STMT (res) = stmt;
105 }
106
107 /* Removes an invariant phi node at position PSI by inserting on the
108 loop ENTRY edge the assignment RES = INIT. */
109
110 static void
111 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
112 {
113 gimple phi = gsi_stmt (*psi);
114 loop_p loop = loop_containing_stmt (phi);
115 tree res = gimple_phi_result (phi);
116 tree scev = scalar_evolution_in_region (region, loop, res);
117 size_t entry = phi_arg_in_outermost_loop (phi);
118 edge e = gimple_phi_arg_edge (phi, entry);
119 tree var;
120 gimple stmt;
121 gimple_seq stmts = NULL;
122
123 if (tree_contains_chrecs (scev, NULL))
124 scev = gimple_phi_arg_def (phi, entry);
125
126 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
127 stmt = gimple_build_assign (res, var);
128 remove_phi_node (psi, false);
129
130 gimple_seq_add_stmt (&stmts, stmt);
131 gsi_insert_seq_on_edge (e, stmts);
132 gsi_commit_edge_inserts ();
133 SSA_NAME_DEF_STMT (res) = stmt;
134 }
135
136 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
137
138 static inline bool
139 simple_copy_phi_p (gimple phi)
140 {
141 tree res;
142
143 if (gimple_phi_num_args (phi) != 2)
144 return false;
145
146 res = gimple_phi_result (phi);
147 return (res == gimple_phi_arg_def (phi, 0)
148 || res == gimple_phi_arg_def (phi, 1));
149 }
150
151 /* Returns true when the phi node at position PSI is a reduction phi
152 node in REGION. Otherwise moves the pointer PSI to the next phi to
153 be considered. */
154
155 static bool
156 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
157 {
158 loop_p loop;
159 gimple phi = gsi_stmt (*psi);
160 tree res = gimple_phi_result (phi);
161
162 loop = loop_containing_stmt (phi);
163
164 if (simple_copy_phi_p (phi))
165 {
166 /* PRE introduces phi nodes like these, for an example,
167 see id-5.f in the fortran graphite testsuite:
168
169 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
170 */
171 remove_simple_copy_phi (psi);
172 return false;
173 }
174
175 if (scev_analyzable_p (res, region))
176 {
177 tree scev = scalar_evolution_in_region (region, loop, res);
178
179 if (evolution_function_is_invariant_p (scev, loop->num))
180 remove_invariant_phi (region, psi);
181 else
182 gsi_next (psi);
183
184 return false;
185 }
186
187 /* All the other cases are considered reductions. */
188 return true;
189 }
190
191 /* Store the GRAPHITE representation of BB. */
192
193 static gimple_bb_p
194 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
195 {
196 struct gimple_bb *gbb;
197
198 gbb = XNEW (struct gimple_bb);
199 bb->aux = gbb;
200 GBB_BB (gbb) = bb;
201 GBB_DATA_REFS (gbb) = drs;
202 GBB_CONDITIONS (gbb).create (0);
203 GBB_CONDITION_CASES (gbb).create (0);
204
205 return gbb;
206 }
207
208 static void
209 free_data_refs_aux (vec<data_reference_p> datarefs)
210 {
211 unsigned int i;
212 struct data_reference *dr;
213
214 FOR_EACH_VEC_ELT (datarefs, i, dr)
215 if (dr->aux)
216 {
217 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
218
219 free (bap->alias_set);
220
221 free (bap);
222 dr->aux = NULL;
223 }
224 }
225 /* Frees GBB. */
226
227 static void
228 free_gimple_bb (struct gimple_bb *gbb)
229 {
230 free_data_refs_aux (GBB_DATA_REFS (gbb));
231 free_data_refs (GBB_DATA_REFS (gbb));
232
233 GBB_CONDITIONS (gbb).release ();
234 GBB_CONDITION_CASES (gbb).release ();
235 GBB_BB (gbb)->aux = 0;
236 XDELETE (gbb);
237 }
238
239 /* Deletes all gimple bbs in SCOP. */
240
241 static void
242 remove_gbbs_in_scop (scop_p scop)
243 {
244 int i;
245 poly_bb_p pbb;
246
247 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
248 free_gimple_bb (PBB_BLACK_BOX (pbb));
249 }
250
251 /* Deletes all scops in SCOPS. */
252
253 void
254 free_scops (vec<scop_p> scops)
255 {
256 int i;
257 scop_p scop;
258
259 FOR_EACH_VEC_ELT (scops, i, scop)
260 {
261 remove_gbbs_in_scop (scop);
262 free_sese (SCOP_REGION (scop));
263 free_scop (scop);
264 }
265
266 scops.release ();
267 }
268
269 /* Same as outermost_loop_in_sese, returns the outermost loop
270 containing BB in REGION, but makes sure that the returned loop
271 belongs to the REGION, and so this returns the first loop in the
272 REGION when the loop containing BB does not belong to REGION. */
273
274 static loop_p
275 outermost_loop_in_sese_1 (sese region, basic_block bb)
276 {
277 loop_p nest = outermost_loop_in_sese (region, bb);
278
279 if (loop_in_sese_p (nest, region))
280 return nest;
281
282 /* When the basic block BB does not belong to a loop in the region,
283 return the first loop in the region. */
284 nest = nest->inner;
285 while (nest)
286 if (loop_in_sese_p (nest, region))
287 break;
288 else
289 nest = nest->next;
290
291 gcc_assert (nest);
292 return nest;
293 }
294
295 /* Generates a polyhedral black box only if the bb contains interesting
296 information. */
297
298 static gimple_bb_p
299 try_generate_gimple_bb (scop_p scop, basic_block bb)
300 {
301 vec<data_reference_p> drs;
302 drs.create (5);
303 sese region = SCOP_REGION (scop);
304 loop_p nest = outermost_loop_in_sese_1 (region, bb);
305 gimple_stmt_iterator gsi;
306
307 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
308 {
309 gimple stmt = gsi_stmt (gsi);
310 loop_p loop;
311
312 if (is_gimple_debug (stmt))
313 continue;
314
315 loop = loop_containing_stmt (stmt);
316 if (!loop_in_sese_p (loop, region))
317 loop = nest;
318
319 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
320 }
321
322 return new_gimple_bb (bb, drs);
323 }
324
325 /* Returns true if all predecessors of BB, that are not dominated by BB, are
326 marked in MAP. The predecessors dominated by BB are loop latches and will
327 be handled after BB. */
328
329 static bool
330 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
331 {
332 edge e;
333 edge_iterator ei;
334
335 FOR_EACH_EDGE (e, ei, bb->preds)
336 if (!bitmap_bit_p (map, e->src->index)
337 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
338 return false;
339
340 return true;
341 }
342
343 /* Compare the depth of two basic_block's P1 and P2. */
344
345 static int
346 compare_bb_depths (const void *p1, const void *p2)
347 {
348 const_basic_block const bb1 = *(const_basic_block const*)p1;
349 const_basic_block const bb2 = *(const_basic_block const*)p2;
350 int d1 = loop_depth (bb1->loop_father);
351 int d2 = loop_depth (bb2->loop_father);
352
353 if (d1 < d2)
354 return 1;
355
356 if (d1 > d2)
357 return -1;
358
359 return 0;
360 }
361
362 /* Sort the basic blocks from DOM such that the first are the ones at
363 a deepest loop level. */
364
365 static void
366 graphite_sort_dominated_info (vec<basic_block> dom)
367 {
368 dom.qsort (compare_bb_depths);
369 }
370
371 /* Recursive helper function for build_scops_bbs. */
372
373 static void
374 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
375 {
376 sese region = SCOP_REGION (scop);
377 vec<basic_block> dom;
378 poly_bb_p pbb;
379
380 if (bitmap_bit_p (visited, bb->index)
381 || !bb_in_sese_p (bb, region))
382 return;
383
384 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
385 SCOP_BBS (scop).safe_push (pbb);
386 bitmap_set_bit (visited, bb->index);
387
388 dom = get_dominated_by (CDI_DOMINATORS, bb);
389
390 if (!dom.exists ())
391 return;
392
393 graphite_sort_dominated_info (dom);
394
395 while (!dom.is_empty ())
396 {
397 int i;
398 basic_block dom_bb;
399
400 FOR_EACH_VEC_ELT (dom, i, dom_bb)
401 if (all_non_dominated_preds_marked_p (dom_bb, visited))
402 {
403 build_scop_bbs_1 (scop, visited, dom_bb);
404 dom.unordered_remove (i);
405 break;
406 }
407 }
408
409 dom.release ();
410 }
411
412 /* Gather the basic blocks belonging to the SCOP. */
413
414 static void
415 build_scop_bbs (scop_p scop)
416 {
417 sbitmap visited = sbitmap_alloc (last_basic_block);
418 sese region = SCOP_REGION (scop);
419
420 bitmap_clear (visited);
421 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
422 sbitmap_free (visited);
423 }
424
425 /* Return an ISL identifier for the polyhedral basic block PBB. */
426
427 static isl_id *
428 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
429 {
430 char name[50];
431 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
432 return isl_id_alloc (s->ctx, name, pbb);
433 }
434
435 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
436 We generate SCATTERING_DIMENSIONS scattering dimensions.
437
438 CLooG 0.15.0 and previous versions require, that all
439 scattering functions of one CloogProgram have the same number of
440 scattering dimensions, therefore we allow to specify it. This
441 should be removed in future versions of CLooG.
442
443 The scattering polyhedron consists of these dimensions: scattering,
444 loop_iterators, parameters.
445
446 Example:
447
448 | scattering_dimensions = 5
449 | used_scattering_dimensions = 3
450 | nb_iterators = 1
451 | scop_nb_params = 2
452 |
453 | Schedule:
454 | i
455 | 4 5
456 |
457 | Scattering polyhedron:
458 |
459 | scattering: {s1, s2, s3, s4, s5}
460 | loop_iterators: {i}
461 | parameters: {p1, p2}
462 |
463 | s1 s2 s3 s4 s5 i p1 p2 1
464 | 1 0 0 0 0 0 0 0 -4 = 0
465 | 0 1 0 0 0 -1 0 0 0 = 0
466 | 0 0 1 0 0 0 0 0 -5 = 0 */
467
468 static void
469 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
470 poly_bb_p pbb, int scattering_dimensions)
471 {
472 int i;
473 int nb_iterators = pbb_dim_iter_domain (pbb);
474 int used_scattering_dimensions = nb_iterators * 2 + 1;
475 isl_int val;
476 isl_space *dc, *dm;
477
478 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
479
480 isl_int_init (val);
481
482 dc = isl_set_get_space (pbb->domain);
483 dm = isl_space_add_dims (isl_space_from_domain (dc),
484 isl_dim_out, scattering_dimensions);
485 pbb->schedule = isl_map_universe (dm);
486
487 for (i = 0; i < scattering_dimensions; i++)
488 {
489 /* Textual order inside this loop. */
490 if ((i % 2) == 0)
491 {
492 isl_constraint *c = isl_equality_alloc
493 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
494
495 if (0 != isl_aff_get_coefficient (static_sched, isl_dim_in,
496 i / 2, &val))
497 gcc_unreachable ();
498
499 isl_int_neg (val, val);
500 c = isl_constraint_set_constant (c, val);
501 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
502 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
503 }
504
505 /* Iterations of this loop. */
506 else /* if ((i % 2) == 1) */
507 {
508 int loop = (i - 1) / 2;
509 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
510 isl_dim_out, i);
511 }
512 }
513
514 isl_int_clear (val);
515
516 pbb->transformed = isl_map_copy (pbb->schedule);
517 }
518
519 /* Build for BB the static schedule.
520
521 The static schedule is a Dewey numbering of the abstract syntax
522 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
523
524 The following example informally defines the static schedule:
525
526 A
527 for (i: ...)
528 {
529 for (j: ...)
530 {
531 B
532 C
533 }
534
535 for (k: ...)
536 {
537 D
538 E
539 }
540 }
541 F
542
543 Static schedules for A to F:
544
545 DEPTH
546 0 1 2
547 A 0
548 B 1 0 0
549 C 1 0 1
550 D 1 1 0
551 E 1 1 1
552 F 2
553 */
554
555 static void
556 build_scop_scattering (scop_p scop)
557 {
558 int i;
559 poly_bb_p pbb;
560 gimple_bb_p previous_gbb = NULL;
561 isl_space *dc = isl_set_get_space (scop->context);
562 isl_aff *static_sched;
563
564 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
565 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
566
567 /* We have to start schedules at 0 on the first component and
568 because we cannot compare_prefix_loops against a previous loop,
569 prefix will be equal to zero, and that index will be
570 incremented before copying. */
571 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
572
573 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
574 {
575 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
576 int prefix;
577 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
578
579 if (previous_gbb)
580 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
581 else
582 prefix = 0;
583
584 previous_gbb = gbb;
585
586 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
587 prefix, 1);
588 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
589 }
590
591 isl_aff_free (static_sched);
592 }
593
594 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
595
596 /* Extract an affine expression from the chain of recurrence E. */
597
598 static isl_pw_aff *
599 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
600 {
601 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
602 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
603 isl_local_space *ls = isl_local_space_from_space (space);
604 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
605 isl_aff *loop = isl_aff_set_coefficient_si
606 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
607 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
608
609 /* Before multiplying, make sure that the result is affine. */
610 gcc_assert (isl_pw_aff_is_cst (rhs)
611 || isl_pw_aff_is_cst (l));
612
613 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
614 }
615
616 /* Extract an affine expression from the mult_expr E. */
617
618 static isl_pw_aff *
619 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
620 {
621 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
622 isl_space_copy (space));
623 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
624
625 if (!isl_pw_aff_is_cst (lhs)
626 && !isl_pw_aff_is_cst (rhs))
627 {
628 isl_pw_aff_free (lhs);
629 isl_pw_aff_free (rhs);
630 return NULL;
631 }
632
633 return isl_pw_aff_mul (lhs, rhs);
634 }
635
636 /* Return an ISL identifier from the name of the ssa_name E. */
637
638 static isl_id *
639 isl_id_for_ssa_name (scop_p s, tree e)
640 {
641 const char *name = get_name (e);
642 isl_id *id;
643
644 if (name)
645 id = isl_id_alloc (s->ctx, name, e);
646 else
647 {
648 char name1[50];
649 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
650 id = isl_id_alloc (s->ctx, name1, e);
651 }
652
653 return id;
654 }
655
656 /* Return an ISL identifier for the data reference DR. */
657
658 static isl_id *
659 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
660 {
661 /* Data references all get the same isl_id. They need to be comparable
662 and are distinguished through the first dimension, which contains the
663 alias set number. */
664 return isl_id_alloc (s->ctx, "", 0);
665 }
666
667 /* Extract an affine expression from the ssa_name E. */
668
669 static isl_pw_aff *
670 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
671 {
672 isl_aff *aff;
673 isl_set *dom;
674 isl_id *id;
675 int dimension;
676
677 id = isl_id_for_ssa_name (s, e);
678 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
679 isl_id_free (id);
680 dom = isl_set_universe (isl_space_copy (space));
681 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
682 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
683 return isl_pw_aff_alloc (dom, aff);
684 }
685
686 /* Extract an affine expression from the gmp constant G. */
687
688 static isl_pw_aff *
689 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
690 {
691 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
692 isl_aff *aff = isl_aff_zero_on_domain (ls);
693 isl_set *dom = isl_set_universe (space);
694 isl_int v;
695
696 isl_int_init (v);
697 isl_int_set_gmp (v, g);
698 aff = isl_aff_add_constant (aff, v);
699 isl_int_clear (v);
700
701 return isl_pw_aff_alloc (dom, aff);
702 }
703
704 /* Extract an affine expression from the integer_cst E. */
705
706 static isl_pw_aff *
707 extract_affine_int (tree e, __isl_take isl_space *space)
708 {
709 isl_pw_aff *res;
710 mpz_t g;
711
712 mpz_init (g);
713 tree_int_to_gmp (e, g);
714 res = extract_affine_gmp (g, space);
715 mpz_clear (g);
716
717 return res;
718 }
719
720 /* Compute pwaff mod 2^width. */
721
722 static isl_pw_aff *
723 wrap (isl_pw_aff *pwaff, unsigned width)
724 {
725 isl_int mod;
726
727 isl_int_init (mod);
728 isl_int_set_si (mod, 1);
729 isl_int_mul_2exp (mod, mod, width);
730
731 pwaff = isl_pw_aff_mod (pwaff, mod);
732
733 isl_int_clear (mod);
734
735 return pwaff;
736 }
737
738 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
739 Otherwise returns -1. */
740
741 static inline int
742 parameter_index_in_region_1 (tree name, sese region)
743 {
744 int i;
745 tree p;
746
747 gcc_assert (TREE_CODE (name) == SSA_NAME);
748
749 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
750 if (p == name)
751 return i;
752
753 return -1;
754 }
755
756 /* When the parameter NAME is in REGION, returns its index in
757 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
758 and returns the index of NAME. */
759
760 static int
761 parameter_index_in_region (tree name, sese region)
762 {
763 int i;
764
765 gcc_assert (TREE_CODE (name) == SSA_NAME);
766
767 i = parameter_index_in_region_1 (name, region);
768 if (i != -1)
769 return i;
770
771 gcc_assert (SESE_ADD_PARAMS (region));
772
773 i = SESE_PARAMS (region).length ();
774 SESE_PARAMS (region).safe_push (name);
775 return i;
776 }
777
778 /* Extract an affine expression from the tree E in the scop S. */
779
780 static isl_pw_aff *
781 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
782 {
783 isl_pw_aff *lhs, *rhs, *res;
784 tree type;
785
786 if (e == chrec_dont_know) {
787 isl_space_free (space);
788 return NULL;
789 }
790
791 switch (TREE_CODE (e))
792 {
793 case POLYNOMIAL_CHREC:
794 res = extract_affine_chrec (s, e, space);
795 break;
796
797 case MULT_EXPR:
798 res = extract_affine_mul (s, e, space);
799 break;
800
801 case PLUS_EXPR:
802 case POINTER_PLUS_EXPR:
803 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
804 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
805 res = isl_pw_aff_add (lhs, rhs);
806 break;
807
808 case MINUS_EXPR:
809 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
810 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
811 res = isl_pw_aff_sub (lhs, rhs);
812 break;
813
814 case NEGATE_EXPR:
815 case BIT_NOT_EXPR:
816 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
817 rhs = extract_affine (s, integer_minus_one_node, space);
818 res = isl_pw_aff_mul (lhs, rhs);
819 break;
820
821 case SSA_NAME:
822 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
823 res = extract_affine_name (s, e, space);
824 break;
825
826 case INTEGER_CST:
827 res = extract_affine_int (e, space);
828 /* No need to wrap a single integer. */
829 return res;
830
831 CASE_CONVERT:
832 case NON_LVALUE_EXPR:
833 res = extract_affine (s, TREE_OPERAND (e, 0), space);
834 break;
835
836 default:
837 gcc_unreachable ();
838 break;
839 }
840
841 type = TREE_TYPE (e);
842 if (TYPE_UNSIGNED (type))
843 res = wrap (res, TYPE_PRECISION (type));
844
845 return res;
846 }
847
848 /* In the context of sese S, scan the expression E and translate it to
849 a linear expression C. When parsing a symbolic multiplication, K
850 represents the constant multiplier of an expression containing
851 parameters. */
852
853 static void
854 scan_tree_for_params (sese s, tree e)
855 {
856 if (e == chrec_dont_know)
857 return;
858
859 switch (TREE_CODE (e))
860 {
861 case POLYNOMIAL_CHREC:
862 scan_tree_for_params (s, CHREC_LEFT (e));
863 break;
864
865 case MULT_EXPR:
866 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
867 scan_tree_for_params (s, TREE_OPERAND (e, 0));
868 else
869 scan_tree_for_params (s, TREE_OPERAND (e, 1));
870 break;
871
872 case PLUS_EXPR:
873 case POINTER_PLUS_EXPR:
874 case MINUS_EXPR:
875 scan_tree_for_params (s, TREE_OPERAND (e, 0));
876 scan_tree_for_params (s, TREE_OPERAND (e, 1));
877 break;
878
879 case NEGATE_EXPR:
880 case BIT_NOT_EXPR:
881 CASE_CONVERT:
882 case NON_LVALUE_EXPR:
883 scan_tree_for_params (s, TREE_OPERAND (e, 0));
884 break;
885
886 case SSA_NAME:
887 parameter_index_in_region (e, s);
888 break;
889
890 case INTEGER_CST:
891 case ADDR_EXPR:
892 break;
893
894 default:
895 gcc_unreachable ();
896 break;
897 }
898 }
899
900 /* Find parameters with respect to REGION in BB. We are looking in memory
901 access functions, conditions and loop bounds. */
902
903 static void
904 find_params_in_bb (sese region, gimple_bb_p gbb)
905 {
906 int i;
907 unsigned j;
908 data_reference_p dr;
909 gimple stmt;
910 loop_p loop = GBB_BB (gbb)->loop_father;
911
912 /* Find parameters in the access functions of data references. */
913 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
914 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
915 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
916
917 /* Find parameters in conditional statements. */
918 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
919 {
920 tree lhs = scalar_evolution_in_region (region, loop,
921 gimple_cond_lhs (stmt));
922 tree rhs = scalar_evolution_in_region (region, loop,
923 gimple_cond_rhs (stmt));
924
925 scan_tree_for_params (region, lhs);
926 scan_tree_for_params (region, rhs);
927 }
928 }
929
930 /* Record the parameters used in the SCOP. A variable is a parameter
931 in a scop if it does not vary during the execution of that scop. */
932
933 static void
934 find_scop_parameters (scop_p scop)
935 {
936 poly_bb_p pbb;
937 unsigned i;
938 sese region = SCOP_REGION (scop);
939 struct loop *loop;
940 int nbp;
941
942 /* Find the parameters used in the loop bounds. */
943 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
944 {
945 tree nb_iters = number_of_latch_executions (loop);
946
947 if (!chrec_contains_symbols (nb_iters))
948 continue;
949
950 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
951 scan_tree_for_params (region, nb_iters);
952 }
953
954 /* Find the parameters used in data accesses. */
955 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
956 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
957
958 nbp = sese_nb_params (region);
959 scop_set_nb_params (scop, nbp);
960 SESE_ADD_PARAMS (region) = false;
961
962 {
963 tree e;
964 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
965
966 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
967 space = isl_space_set_dim_id (space, isl_dim_param, i,
968 isl_id_for_ssa_name (scop, e));
969
970 scop->context = isl_set_universe (space);
971 }
972 }
973
974 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
975 the constraints for the surrounding loops. */
976
977 static void
978 build_loop_iteration_domains (scop_p scop, struct loop *loop,
979 int nb,
980 isl_set *outer, isl_set **doms)
981 {
982 tree nb_iters = number_of_latch_executions (loop);
983 sese region = SCOP_REGION (scop);
984
985 isl_set *inner = isl_set_copy (outer);
986 isl_space *space;
987 isl_constraint *c;
988 int pos = isl_set_dim (outer, isl_dim_set);
989 isl_int v;
990 mpz_t g;
991
992 mpz_init (g);
993 isl_int_init (v);
994
995 inner = isl_set_add_dims (inner, isl_dim_set, 1);
996 space = isl_set_get_space (inner);
997
998 /* 0 <= loop_i */
999 c = isl_inequality_alloc
1000 (isl_local_space_from_space (isl_space_copy (space)));
1001 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
1002 inner = isl_set_add_constraint (inner, c);
1003
1004 /* loop_i <= cst_nb_iters */
1005 if (TREE_CODE (nb_iters) == INTEGER_CST)
1006 {
1007 c = isl_inequality_alloc
1008 (isl_local_space_from_space (isl_space_copy (space)));
1009 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1010 tree_int_to_gmp (nb_iters, g);
1011 isl_int_set_gmp (v, g);
1012 c = isl_constraint_set_constant (c, v);
1013 inner = isl_set_add_constraint (inner, c);
1014 }
1015
1016 /* loop_i <= expr_nb_iters */
1017 else if (!chrec_contains_undetermined (nb_iters))
1018 {
1019 double_int nit;
1020 isl_pw_aff *aff;
1021 isl_set *valid;
1022 isl_local_space *ls;
1023 isl_aff *al;
1024 isl_set *le;
1025
1026 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1027
1028 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1029 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1030 valid = isl_set_project_out (valid, isl_dim_set, 0,
1031 isl_set_dim (valid, isl_dim_set));
1032 scop->context = isl_set_intersect (scop->context, valid);
1033
1034 ls = isl_local_space_from_space (isl_space_copy (space));
1035 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1036 isl_dim_in, pos, 1);
1037 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1038 isl_pw_aff_copy (aff));
1039 inner = isl_set_intersect (inner, le);
1040
1041 if (max_stmt_executions (loop, &nit))
1042 {
1043 /* Insert in the context the constraints from the
1044 estimation of the number of iterations NIT and the
1045 symbolic number of iterations (involving parameter
1046 names) NB_ITERS. First, build the affine expression
1047 "NIT - NB_ITERS" and then say that it is positive,
1048 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1049 isl_pw_aff *approx;
1050 mpz_t g;
1051 isl_set *x;
1052 isl_constraint *c;
1053
1054 mpz_init (g);
1055 mpz_set_double_int (g, nit, false);
1056 mpz_sub_ui (g, g, 1);
1057 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1058 x = isl_pw_aff_ge_set (approx, aff);
1059 x = isl_set_project_out (x, isl_dim_set, 0,
1060 isl_set_dim (x, isl_dim_set));
1061 scop->context = isl_set_intersect (scop->context, x);
1062
1063 c = isl_inequality_alloc
1064 (isl_local_space_from_space (isl_space_copy (space)));
1065 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1066 isl_int_set_gmp (v, g);
1067 mpz_clear (g);
1068 c = isl_constraint_set_constant (c, v);
1069 inner = isl_set_add_constraint (inner, c);
1070 }
1071 else
1072 isl_pw_aff_free (aff);
1073 }
1074 else
1075 gcc_unreachable ();
1076
1077 if (loop->inner && loop_in_sese_p (loop->inner, region))
1078 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1079 isl_set_copy (inner), doms);
1080
1081 if (nb != 0
1082 && loop->next
1083 && loop_in_sese_p (loop->next, region))
1084 build_loop_iteration_domains (scop, loop->next, nb,
1085 isl_set_copy (outer), doms);
1086
1087 doms[loop->num] = inner;
1088
1089 isl_set_free (outer);
1090 isl_space_free (space);
1091 isl_int_clear (v);
1092 mpz_clear (g);
1093 }
1094
1095 /* Returns a linear expression for tree T evaluated in PBB. */
1096
1097 static isl_pw_aff *
1098 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1099 {
1100 scop_p scop = PBB_SCOP (pbb);
1101
1102 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1103 gcc_assert (!automatically_generated_chrec_p (t));
1104
1105 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1106 }
1107
1108 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1109 operator. This allows us to invert the condition or to handle
1110 inequalities. */
1111
1112 static void
1113 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1114 {
1115 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1116 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1117 isl_set *cond;
1118
1119 switch (code)
1120 {
1121 case LT_EXPR:
1122 cond = isl_pw_aff_lt_set (lhs, rhs);
1123 break;
1124
1125 case GT_EXPR:
1126 cond = isl_pw_aff_gt_set (lhs, rhs);
1127 break;
1128
1129 case LE_EXPR:
1130 cond = isl_pw_aff_le_set (lhs, rhs);
1131 break;
1132
1133 case GE_EXPR:
1134 cond = isl_pw_aff_ge_set (lhs, rhs);
1135 break;
1136
1137 case EQ_EXPR:
1138 cond = isl_pw_aff_eq_set (lhs, rhs);
1139 break;
1140
1141 case NE_EXPR:
1142 cond = isl_pw_aff_ne_set (lhs, rhs);
1143 break;
1144
1145 default:
1146 isl_pw_aff_free (lhs);
1147 isl_pw_aff_free (rhs);
1148 return;
1149 }
1150
1151 cond = isl_set_coalesce (cond);
1152 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1153 pbb->domain = isl_set_intersect (pbb->domain, cond);
1154 }
1155
1156 /* Add conditions to the domain of PBB. */
1157
1158 static void
1159 add_conditions_to_domain (poly_bb_p pbb)
1160 {
1161 unsigned int i;
1162 gimple stmt;
1163 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1164
1165 if (GBB_CONDITIONS (gbb).is_empty ())
1166 return;
1167
1168 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1169 switch (gimple_code (stmt))
1170 {
1171 case GIMPLE_COND:
1172 {
1173 enum tree_code code = gimple_cond_code (stmt);
1174
1175 /* The conditions for ELSE-branches are inverted. */
1176 if (!GBB_CONDITION_CASES (gbb)[i])
1177 code = invert_tree_comparison (code, false);
1178
1179 add_condition_to_pbb (pbb, stmt, code);
1180 break;
1181 }
1182
1183 case GIMPLE_SWITCH:
1184 /* Switch statements are not supported right now - fall through. */
1185
1186 default:
1187 gcc_unreachable ();
1188 break;
1189 }
1190 }
1191
1192 /* Traverses all the GBBs of the SCOP and add their constraints to the
1193 iteration domains. */
1194
1195 static void
1196 add_conditions_to_constraints (scop_p scop)
1197 {
1198 int i;
1199 poly_bb_p pbb;
1200
1201 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1202 add_conditions_to_domain (pbb);
1203 }
1204
1205 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1206 edge between BB and its predecessor is not a loop exit edge, and
1207 the last statement of the single predecessor is a COND_EXPR. */
1208
1209 static gimple
1210 single_pred_cond_non_loop_exit (basic_block bb)
1211 {
1212 if (single_pred_p (bb))
1213 {
1214 edge e = single_pred_edge (bb);
1215 basic_block pred = e->src;
1216 gimple stmt;
1217
1218 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1219 return NULL;
1220
1221 stmt = last_stmt (pred);
1222
1223 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1224 return stmt;
1225 }
1226
1227 return NULL;
1228 }
1229
1230 class sese_dom_walker : public dom_walker
1231 {
1232 public:
1233 sese_dom_walker (cdi_direction, sese);
1234
1235 virtual void before_dom_children (basic_block);
1236 virtual void after_dom_children (basic_block);
1237
1238 private:
1239 stack_vec<gimple, 3> m_conditions, m_cases;
1240 sese m_region;
1241 };
1242
1243 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1244 : dom_walker (direction), m_region (region)
1245 {
1246 }
1247
1248 /* Call-back for dom_walk executed before visiting the dominated
1249 blocks. */
1250
1251 void
1252 sese_dom_walker::before_dom_children (basic_block bb)
1253 {
1254 gimple_bb_p gbb;
1255 gimple stmt;
1256
1257 if (!bb_in_sese_p (bb, m_region))
1258 return;
1259
1260 stmt = single_pred_cond_non_loop_exit (bb);
1261
1262 if (stmt)
1263 {
1264 edge e = single_pred_edge (bb);
1265
1266 m_conditions.safe_push (stmt);
1267
1268 if (e->flags & EDGE_TRUE_VALUE)
1269 m_cases.safe_push (stmt);
1270 else
1271 m_cases.safe_push (NULL);
1272 }
1273
1274 gbb = gbb_from_bb (bb);
1275
1276 if (gbb)
1277 {
1278 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1279 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1280 }
1281 }
1282
1283 /* Call-back for dom_walk executed after visiting the dominated
1284 blocks. */
1285
1286 void
1287 sese_dom_walker::after_dom_children (basic_block bb)
1288 {
1289 if (!bb_in_sese_p (bb, m_region))
1290 return;
1291
1292 if (single_pred_cond_non_loop_exit (bb))
1293 {
1294 m_conditions.pop ();
1295 m_cases.pop ();
1296 }
1297 }
1298
1299 /* Add constraints on the possible values of parameter P from the type
1300 of P. */
1301
1302 static void
1303 add_param_constraints (scop_p scop, graphite_dim_t p)
1304 {
1305 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1306 tree type = TREE_TYPE (parameter);
1307 tree lb = NULL_TREE;
1308 tree ub = NULL_TREE;
1309
1310 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1311 lb = lower_bound_in_type (type, type);
1312 else
1313 lb = TYPE_MIN_VALUE (type);
1314
1315 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1316 ub = upper_bound_in_type (type, type);
1317 else
1318 ub = TYPE_MAX_VALUE (type);
1319
1320 if (lb)
1321 {
1322 isl_space *space = isl_set_get_space (scop->context);
1323 isl_constraint *c;
1324 mpz_t g;
1325 isl_int v;
1326
1327 c = isl_inequality_alloc (isl_local_space_from_space (space));
1328 mpz_init (g);
1329 isl_int_init (v);
1330 tree_int_to_gmp (lb, g);
1331 isl_int_set_gmp (v, g);
1332 isl_int_neg (v, v);
1333 mpz_clear (g);
1334 c = isl_constraint_set_constant (c, v);
1335 isl_int_clear (v);
1336 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1337
1338 scop->context = isl_set_add_constraint (scop->context, c);
1339 }
1340
1341 if (ub)
1342 {
1343 isl_space *space = isl_set_get_space (scop->context);
1344 isl_constraint *c;
1345 mpz_t g;
1346 isl_int v;
1347
1348 c = isl_inequality_alloc (isl_local_space_from_space (space));
1349
1350 mpz_init (g);
1351 isl_int_init (v);
1352 tree_int_to_gmp (ub, g);
1353 isl_int_set_gmp (v, g);
1354 mpz_clear (g);
1355 c = isl_constraint_set_constant (c, v);
1356 isl_int_clear (v);
1357 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1358
1359 scop->context = isl_set_add_constraint (scop->context, c);
1360 }
1361 }
1362
1363 /* Build the context of the SCOP. The context usually contains extra
1364 constraints that are added to the iteration domains that constrain
1365 some parameters. */
1366
1367 static void
1368 build_scop_context (scop_p scop)
1369 {
1370 graphite_dim_t p, n = scop_nb_params (scop);
1371
1372 for (p = 0; p < n; p++)
1373 add_param_constraints (scop, p);
1374 }
1375
1376 /* Build the iteration domains: the loops belonging to the current
1377 SCOP, and that vary for the execution of the current basic block.
1378 Returns false if there is no loop in SCOP. */
1379
1380 static void
1381 build_scop_iteration_domain (scop_p scop)
1382 {
1383 struct loop *loop;
1384 sese region = SCOP_REGION (scop);
1385 int i;
1386 poly_bb_p pbb;
1387 int nb_loops = number_of_loops (cfun);
1388 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1389
1390 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1391 if (!loop_in_sese_p (loop_outer (loop), region))
1392 build_loop_iteration_domains (scop, loop, 0,
1393 isl_set_copy (scop->context), doms);
1394
1395 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1396 {
1397 loop = pbb_loop (pbb);
1398
1399 if (doms[loop->num])
1400 pbb->domain = isl_set_copy (doms[loop->num]);
1401 else
1402 pbb->domain = isl_set_copy (scop->context);
1403
1404 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1405 isl_id_for_pbb (scop, pbb));
1406 }
1407
1408 for (i = 0; i < nb_loops; i++)
1409 if (doms[i])
1410 isl_set_free (doms[i]);
1411
1412 free (doms);
1413 }
1414
1415 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1416 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1417 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1418 domain. */
1419
1420 static isl_map *
1421 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1422 {
1423 isl_constraint *c;
1424 int alias_set_num = 0;
1425 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1426
1427 if (bap && bap->alias_set)
1428 alias_set_num = *(bap->alias_set);
1429
1430 c = isl_equality_alloc
1431 (isl_local_space_from_space (isl_map_get_space (acc)));
1432 c = isl_constraint_set_constant_si (c, -alias_set_num);
1433 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1434
1435 return isl_map_add_constraint (acc, c);
1436 }
1437
1438 /* Assign the affine expression INDEX to the output dimension POS of
1439 MAP and return the result. */
1440
1441 static isl_map *
1442 set_index (isl_map *map, int pos, isl_pw_aff *index)
1443 {
1444 isl_map *index_map;
1445 int len = isl_map_dim (map, isl_dim_out);
1446 isl_id *id;
1447
1448 index_map = isl_map_from_pw_aff (index);
1449 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1450 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1451
1452 id = isl_map_get_tuple_id (map, isl_dim_out);
1453 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1454 id = isl_map_get_tuple_id (map, isl_dim_in);
1455 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1456
1457 return isl_map_intersect (map, index_map);
1458 }
1459
1460 /* Add to ACCESSES polyhedron equalities defining the access functions
1461 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1462 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1463 PBB is the poly_bb_p that contains the data reference DR. */
1464
1465 static isl_map *
1466 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1467 {
1468 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1469 scop_p scop = PBB_SCOP (pbb);
1470
1471 for (i = 0; i < nb_subscripts; i++)
1472 {
1473 isl_pw_aff *aff;
1474 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1475
1476 aff = extract_affine (scop, afn,
1477 isl_space_domain (isl_map_get_space (acc)));
1478 acc = set_index (acc, i + 1, aff);
1479 }
1480
1481 return acc;
1482 }
1483
1484 /* Add constrains representing the size of the accessed data to the
1485 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1486 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1487 domain. */
1488
1489 static isl_set *
1490 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1491 {
1492 tree ref = DR_REF (dr);
1493 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1494
1495 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1496 {
1497 tree low, high;
1498
1499 if (TREE_CODE (ref) != ARRAY_REF)
1500 break;
1501
1502 low = array_ref_low_bound (ref);
1503 high = array_ref_up_bound (ref);
1504
1505 /* XXX The PPL code dealt separately with
1506 subscript - low >= 0 and high - subscript >= 0 in case one of
1507 the two bounds isn't known. Do the same here? */
1508
1509 if (host_integerp (low, 0)
1510 && high
1511 && host_integerp (high, 0)
1512 /* 1-element arrays at end of structures may extend over
1513 their declared size. */
1514 && !(array_at_struct_end_p (ref)
1515 && operand_equal_p (low, high, 0)))
1516 {
1517 isl_id *id;
1518 isl_aff *aff;
1519 isl_set *univ, *lbs, *ubs;
1520 isl_pw_aff *index;
1521 isl_space *space;
1522 isl_set *valid;
1523 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1524 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1525
1526 /* high >= 0 */
1527 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1528 valid = isl_set_project_out (valid, isl_dim_set, 0,
1529 isl_set_dim (valid, isl_dim_set));
1530 scop->context = isl_set_intersect (scop->context, valid);
1531
1532 space = isl_set_get_space (extent);
1533 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1534 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1535 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1536 index = isl_pw_aff_alloc (univ, aff);
1537
1538 id = isl_set_get_tuple_id (extent);
1539 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1540 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1541
1542 /* low <= sub_i <= high */
1543 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1544 ubs = isl_pw_aff_le_set (index, ub);
1545 extent = isl_set_intersect (extent, lbs);
1546 extent = isl_set_intersect (extent, ubs);
1547 }
1548 }
1549
1550 return extent;
1551 }
1552
1553 /* Build data accesses for DR in PBB. */
1554
1555 static void
1556 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1557 {
1558 int dr_base_object_set;
1559 isl_map *acc;
1560 isl_set *extent;
1561 scop_p scop = PBB_SCOP (pbb);
1562
1563 {
1564 isl_space *dc = isl_set_get_space (pbb->domain);
1565 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1566 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1567 isl_dim_out, nb_out);
1568
1569 acc = isl_map_universe (space);
1570 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1571 }
1572
1573 acc = pdr_add_alias_set (acc, dr);
1574 acc = pdr_add_memory_accesses (acc, dr, pbb);
1575
1576 {
1577 isl_id *id = isl_id_for_dr (scop, dr);
1578 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1579 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1580 int alias_set_num = 0;
1581 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1582
1583 if (bap && bap->alias_set)
1584 alias_set_num = *(bap->alias_set);
1585
1586 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1587 extent = isl_set_nat_universe (space);
1588 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1589 extent = pdr_add_data_dimensions (extent, scop, dr);
1590 }
1591
1592 gcc_assert (dr->aux);
1593 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1594
1595 new_poly_dr (pbb, dr_base_object_set,
1596 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1597 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1598 }
1599
1600 /* Write to FILE the alias graph of data references in DIMACS format. */
1601
1602 static inline bool
1603 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1604 vec<data_reference_p> drs)
1605 {
1606 int num_vertex = drs.length ();
1607 int edge_num = 0;
1608 data_reference_p dr1, dr2;
1609 int i, j;
1610
1611 if (num_vertex == 0)
1612 return true;
1613
1614 FOR_EACH_VEC_ELT (drs, i, dr1)
1615 for (j = i + 1; drs.iterate (j, &dr2); j++)
1616 if (dr_may_alias_p (dr1, dr2, true))
1617 edge_num++;
1618
1619 fprintf (file, "$\n");
1620
1621 if (comment)
1622 fprintf (file, "c %s\n", comment);
1623
1624 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1625
1626 FOR_EACH_VEC_ELT (drs, i, dr1)
1627 for (j = i + 1; drs.iterate (j, &dr2); j++)
1628 if (dr_may_alias_p (dr1, dr2, true))
1629 fprintf (file, "e %d %d\n", i + 1, j + 1);
1630
1631 return true;
1632 }
1633
1634 /* Write to FILE the alias graph of data references in DOT format. */
1635
1636 static inline bool
1637 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1638 vec<data_reference_p> drs)
1639 {
1640 int num_vertex = drs.length ();
1641 data_reference_p dr1, dr2;
1642 int i, j;
1643
1644 if (num_vertex == 0)
1645 return true;
1646
1647 fprintf (file, "$\n");
1648
1649 if (comment)
1650 fprintf (file, "c %s\n", comment);
1651
1652 /* First print all the vertices. */
1653 FOR_EACH_VEC_ELT (drs, i, dr1)
1654 fprintf (file, "n%d;\n", i);
1655
1656 FOR_EACH_VEC_ELT (drs, i, dr1)
1657 for (j = i + 1; drs.iterate (j, &dr2); j++)
1658 if (dr_may_alias_p (dr1, dr2, true))
1659 fprintf (file, "n%d n%d\n", i, j);
1660
1661 return true;
1662 }
1663
1664 /* Write to FILE the alias graph of data references in ECC format. */
1665
1666 static inline bool
1667 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1668 vec<data_reference_p> drs)
1669 {
1670 int num_vertex = drs.length ();
1671 data_reference_p dr1, dr2;
1672 int i, j;
1673
1674 if (num_vertex == 0)
1675 return true;
1676
1677 fprintf (file, "$\n");
1678
1679 if (comment)
1680 fprintf (file, "c %s\n", comment);
1681
1682 FOR_EACH_VEC_ELT (drs, i, dr1)
1683 for (j = i + 1; drs.iterate (j, &dr2); j++)
1684 if (dr_may_alias_p (dr1, dr2, true))
1685 fprintf (file, "%d %d\n", i, j);
1686
1687 return true;
1688 }
1689
1690 /* Check if DR1 and DR2 are in the same object set. */
1691
1692 static bool
1693 dr_same_base_object_p (const struct data_reference *dr1,
1694 const struct data_reference *dr2)
1695 {
1696 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1697 }
1698
1699 /* Uses DFS component number as representative of alias-sets. Also tests for
1700 optimality by verifying if every connected component is a clique. Returns
1701 true (1) if the above test is true, and false (0) otherwise. */
1702
1703 static int
1704 build_alias_set_optimal_p (vec<data_reference_p> drs)
1705 {
1706 int num_vertices = drs.length ();
1707 struct graph *g = new_graph (num_vertices);
1708 data_reference_p dr1, dr2;
1709 int i, j;
1710 int num_connected_components;
1711 int v_indx1, v_indx2, num_vertices_in_component;
1712 int *all_vertices;
1713 int *vertices;
1714 struct graph_edge *e;
1715 int this_component_is_clique;
1716 int all_components_are_cliques = 1;
1717
1718 FOR_EACH_VEC_ELT (drs, i, dr1)
1719 for (j = i+1; drs.iterate (j, &dr2); j++)
1720 if (dr_may_alias_p (dr1, dr2, true))
1721 {
1722 add_edge (g, i, j);
1723 add_edge (g, j, i);
1724 }
1725
1726 all_vertices = XNEWVEC (int, num_vertices);
1727 vertices = XNEWVEC (int, num_vertices);
1728 for (i = 0; i < num_vertices; i++)
1729 all_vertices[i] = i;
1730
1731 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1732 NULL, true, NULL);
1733 for (i = 0; i < g->n_vertices; i++)
1734 {
1735 data_reference_p dr = drs[i];
1736 base_alias_pair *bap;
1737
1738 gcc_assert (dr->aux);
1739 bap = (base_alias_pair *)(dr->aux);
1740
1741 bap->alias_set = XNEW (int);
1742 *(bap->alias_set) = g->vertices[i].component + 1;
1743 }
1744
1745 /* Verify if the DFS numbering results in optimal solution. */
1746 for (i = 0; i < num_connected_components; i++)
1747 {
1748 num_vertices_in_component = 0;
1749 /* Get all vertices whose DFS component number is the same as i. */
1750 for (j = 0; j < num_vertices; j++)
1751 if (g->vertices[j].component == i)
1752 vertices[num_vertices_in_component++] = j;
1753
1754 /* Now test if the vertices in 'vertices' form a clique, by testing
1755 for edges among each pair. */
1756 this_component_is_clique = 1;
1757 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1758 {
1759 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1760 {
1761 /* Check if the two vertices are connected by iterating
1762 through all the edges which have one of these are source. */
1763 e = g->vertices[vertices[v_indx2]].pred;
1764 while (e)
1765 {
1766 if (e->src == vertices[v_indx1])
1767 break;
1768 e = e->pred_next;
1769 }
1770 if (!e)
1771 {
1772 this_component_is_clique = 0;
1773 break;
1774 }
1775 }
1776 if (!this_component_is_clique)
1777 all_components_are_cliques = 0;
1778 }
1779 }
1780
1781 free (all_vertices);
1782 free (vertices);
1783 free_graph (g);
1784 return all_components_are_cliques;
1785 }
1786
1787 /* Group each data reference in DRS with its base object set num. */
1788
1789 static void
1790 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1791 {
1792 int num_vertex = drs.length ();
1793 struct graph *g = new_graph (num_vertex);
1794 data_reference_p dr1, dr2;
1795 int i, j;
1796 int *queue;
1797
1798 FOR_EACH_VEC_ELT (drs, i, dr1)
1799 for (j = i + 1; drs.iterate (j, &dr2); j++)
1800 if (dr_same_base_object_p (dr1, dr2))
1801 {
1802 add_edge (g, i, j);
1803 add_edge (g, j, i);
1804 }
1805
1806 queue = XNEWVEC (int, num_vertex);
1807 for (i = 0; i < num_vertex; i++)
1808 queue[i] = i;
1809
1810 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1811
1812 for (i = 0; i < g->n_vertices; i++)
1813 {
1814 data_reference_p dr = drs[i];
1815 base_alias_pair *bap;
1816
1817 gcc_assert (dr->aux);
1818 bap = (base_alias_pair *)(dr->aux);
1819
1820 bap->base_obj_set = g->vertices[i].component + 1;
1821 }
1822
1823 free (queue);
1824 free_graph (g);
1825 }
1826
1827 /* Build the data references for PBB. */
1828
1829 static void
1830 build_pbb_drs (poly_bb_p pbb)
1831 {
1832 int j;
1833 data_reference_p dr;
1834 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1835
1836 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1837 build_poly_dr (dr, pbb);
1838 }
1839
1840 /* Dump to file the alias graphs for the data references in DRS. */
1841
1842 static void
1843 dump_alias_graphs (vec<data_reference_p> drs)
1844 {
1845 char comment[100];
1846 FILE *file_dimacs, *file_ecc, *file_dot;
1847
1848 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1849 if (file_dimacs)
1850 {
1851 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1852 current_function_name ());
1853 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1854 fclose (file_dimacs);
1855 }
1856
1857 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1858 if (file_ecc)
1859 {
1860 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1861 current_function_name ());
1862 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1863 fclose (file_ecc);
1864 }
1865
1866 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1867 if (file_dot)
1868 {
1869 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1870 current_function_name ());
1871 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1872 fclose (file_dot);
1873 }
1874 }
1875
1876 /* Build data references in SCOP. */
1877
1878 static void
1879 build_scop_drs (scop_p scop)
1880 {
1881 int i, j;
1882 poly_bb_p pbb;
1883 data_reference_p dr;
1884 stack_vec<data_reference_p, 3> drs;
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 stack_vec<gimple, 3> x;
1983
1984 gimple_seq_add_stmt (&stmts, stmt);
1985 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1986 x.safe_push (gsi_stmt (gsi));
1987
1988 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
1989 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1990 }
1991
1992 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
1993
1994 static void
1995 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
1996 {
1997 gimple_seq stmts;
1998 gimple_stmt_iterator gsi;
1999 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2000 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2001 stack_vec<gimple, 3> x;
2002
2003 gimple_seq_add_stmt (&stmts, stmt);
2004 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2005 x.safe_push (gsi_stmt (gsi));
2006
2007 if (gimple_code (after_stmt) == GIMPLE_PHI)
2008 {
2009 gsi = gsi_after_labels (gimple_bb (after_stmt));
2010 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2011 }
2012 else
2013 {
2014 gsi = gsi_for_stmt (after_stmt);
2015 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2016 }
2017
2018 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2019 }
2020
2021 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2022
2023 static void
2024 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2025 {
2026 vec<data_reference_p> drs;
2027 drs.create (3);
2028 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2029 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2030 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2031 int index, n = SCOP_BBS (scop).length ();
2032
2033 /* The INDEX of PBB in SCOP_BBS. */
2034 for (index = 0; index < n; index++)
2035 if (SCOP_BBS (scop)[index] == pbb)
2036 break;
2037
2038 pbb1->domain = isl_set_copy (pbb->domain);
2039
2040 GBB_PBB (gbb1) = pbb1;
2041 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2042 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2043 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2044 }
2045
2046 /* Insert on edge E the assignment "RES := EXPR". */
2047
2048 static void
2049 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2050 {
2051 gimple_stmt_iterator gsi;
2052 gimple_seq stmts = NULL;
2053 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2054 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2055 basic_block bb;
2056 stack_vec<gimple, 3> x;
2057
2058 gimple_seq_add_stmt (&stmts, stmt);
2059 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2060 x.safe_push (gsi_stmt (gsi));
2061
2062 gsi_insert_seq_on_edge (e, stmts);
2063 gsi_commit_edge_inserts ();
2064 bb = gimple_bb (stmt);
2065
2066 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2067 return;
2068
2069 if (!gbb_from_bb (bb))
2070 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2071
2072 analyze_drs_in_stmts (scop, bb, x);
2073 }
2074
2075 /* Creates a zero dimension array of the same type as VAR. */
2076
2077 static tree
2078 create_zero_dim_array (tree var, const char *base_name)
2079 {
2080 tree index_type = build_index_type (integer_zero_node);
2081 tree elt_type = TREE_TYPE (var);
2082 tree array_type = build_array_type (elt_type, index_type);
2083 tree base = create_tmp_var (array_type, base_name);
2084
2085 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2086 NULL_TREE);
2087 }
2088
2089 /* Returns true when PHI is a loop close phi node. */
2090
2091 static bool
2092 scalar_close_phi_node_p (gimple phi)
2093 {
2094 if (gimple_code (phi) != GIMPLE_PHI
2095 || virtual_operand_p (gimple_phi_result (phi)))
2096 return false;
2097
2098 /* Note that loop close phi nodes should have a single argument
2099 because we translated the representation into a canonical form
2100 before Graphite: see canonicalize_loop_closed_ssa_form. */
2101 return (gimple_phi_num_args (phi) == 1);
2102 }
2103
2104 /* For a definition DEF in REGION, propagates the expression EXPR in
2105 all the uses of DEF outside REGION. */
2106
2107 static void
2108 propagate_expr_outside_region (tree def, tree expr, sese region)
2109 {
2110 imm_use_iterator imm_iter;
2111 gimple use_stmt;
2112 gimple_seq stmts;
2113 bool replaced_once = false;
2114
2115 gcc_assert (TREE_CODE (def) == SSA_NAME);
2116
2117 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2118 NULL_TREE);
2119
2120 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2121 if (!is_gimple_debug (use_stmt)
2122 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2123 {
2124 ssa_op_iter iter;
2125 use_operand_p use_p;
2126
2127 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2128 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2129 && (replaced_once = true))
2130 replace_exp (use_p, expr);
2131
2132 update_stmt (use_stmt);
2133 }
2134
2135 if (replaced_once)
2136 {
2137 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2138 gsi_commit_edge_inserts ();
2139 }
2140 }
2141
2142 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2143 dimension array for it. */
2144
2145 static void
2146 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2147 {
2148 sese region = SCOP_REGION (scop);
2149 gimple phi = gsi_stmt (*psi);
2150 tree res = gimple_phi_result (phi);
2151 basic_block bb = gimple_bb (phi);
2152 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2153 tree arg = gimple_phi_arg_def (phi, 0);
2154 gimple stmt;
2155
2156 /* Note that loop close phi nodes should have a single argument
2157 because we translated the representation into a canonical form
2158 before Graphite: see canonicalize_loop_closed_ssa_form. */
2159 gcc_assert (gimple_phi_num_args (phi) == 1);
2160
2161 /* The phi node can be a non close phi node, when its argument is
2162 invariant, or a default definition. */
2163 if (is_gimple_min_invariant (arg)
2164 || SSA_NAME_IS_DEFAULT_DEF (arg))
2165 {
2166 propagate_expr_outside_region (res, arg, region);
2167 gsi_next (psi);
2168 return;
2169 }
2170
2171 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2172 {
2173 propagate_expr_outside_region (res, arg, region);
2174 stmt = gimple_build_assign (res, arg);
2175 remove_phi_node (psi, false);
2176 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2177 SSA_NAME_DEF_STMT (res) = stmt;
2178 return;
2179 }
2180
2181 /* If res is scev analyzable and is not a scalar value, it is safe
2182 to ignore the close phi node: it will be code generated in the
2183 out of Graphite pass. */
2184 else if (scev_analyzable_p (res, region))
2185 {
2186 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2187 tree scev;
2188
2189 if (!loop_in_sese_p (loop, region))
2190 {
2191 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2192 scev = scalar_evolution_in_region (region, loop, arg);
2193 scev = compute_overall_effect_of_inner_loop (loop, scev);
2194 }
2195 else
2196 scev = scalar_evolution_in_region (region, loop, res);
2197
2198 if (tree_does_not_contain_chrecs (scev))
2199 propagate_expr_outside_region (res, scev, region);
2200
2201 gsi_next (psi);
2202 return;
2203 }
2204 else
2205 {
2206 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2207
2208 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2209
2210 if (TREE_CODE (arg) == SSA_NAME)
2211 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2212 SSA_NAME_DEF_STMT (arg));
2213 else
2214 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2215 zero_dim_array, arg);
2216 }
2217
2218 remove_phi_node (psi, false);
2219 SSA_NAME_DEF_STMT (res) = stmt;
2220
2221 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2222 }
2223
2224 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2225 dimension array for it. */
2226
2227 static void
2228 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2229 {
2230 size_t i;
2231 gimple phi = gsi_stmt (*psi);
2232 basic_block bb = gimple_bb (phi);
2233 tree res = gimple_phi_result (phi);
2234 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2235 gimple stmt;
2236
2237 for (i = 0; i < gimple_phi_num_args (phi); i++)
2238 {
2239 tree arg = gimple_phi_arg_def (phi, i);
2240 edge e = gimple_phi_arg_edge (phi, i);
2241
2242 /* Avoid the insertion of code in the loop latch to please the
2243 pattern matching of the vectorizer. */
2244 if (TREE_CODE (arg) == SSA_NAME
2245 && e->src == bb->loop_father->latch)
2246 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2247 SSA_NAME_DEF_STMT (arg));
2248 else
2249 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2250 }
2251
2252 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2253 remove_phi_node (psi, false);
2254 SSA_NAME_DEF_STMT (res) = stmt;
2255 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2256 }
2257
2258 /* Rewrite the degenerate phi node at position PSI from the degenerate
2259 form "x = phi (y, y, ..., y)" to "x = y". */
2260
2261 static void
2262 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2263 {
2264 tree rhs;
2265 gimple stmt;
2266 gimple_stmt_iterator gsi;
2267 gimple phi = gsi_stmt (*psi);
2268 tree res = gimple_phi_result (phi);
2269 basic_block bb;
2270
2271 bb = gimple_bb (phi);
2272 rhs = degenerate_phi_result (phi);
2273 gcc_assert (rhs);
2274
2275 stmt = gimple_build_assign (res, rhs);
2276 remove_phi_node (psi, false);
2277 SSA_NAME_DEF_STMT (res) = stmt;
2278
2279 gsi = gsi_after_labels (bb);
2280 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2281 }
2282
2283 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2284
2285 static void
2286 rewrite_reductions_out_of_ssa (scop_p scop)
2287 {
2288 basic_block bb;
2289 gimple_stmt_iterator psi;
2290 sese region = SCOP_REGION (scop);
2291
2292 FOR_EACH_BB (bb)
2293 if (bb_in_sese_p (bb, region))
2294 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2295 {
2296 gimple phi = gsi_stmt (psi);
2297
2298 if (virtual_operand_p (gimple_phi_result (phi)))
2299 {
2300 gsi_next (&psi);
2301 continue;
2302 }
2303
2304 if (gimple_phi_num_args (phi) > 1
2305 && degenerate_phi_result (phi))
2306 rewrite_degenerate_phi (&psi);
2307
2308 else if (scalar_close_phi_node_p (phi))
2309 rewrite_close_phi_out_of_ssa (scop, &psi);
2310
2311 else if (reduction_phi_p (region, &psi))
2312 rewrite_phi_out_of_ssa (scop, &psi);
2313 }
2314
2315 update_ssa (TODO_update_ssa);
2316 #ifdef ENABLE_CHECKING
2317 verify_loop_closed_ssa (true);
2318 #endif
2319 }
2320
2321 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2322 read from ZERO_DIM_ARRAY. */
2323
2324 static void
2325 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2326 tree def, gimple use_stmt)
2327 {
2328 gimple name_stmt;
2329 tree name;
2330 ssa_op_iter iter;
2331 use_operand_p use_p;
2332
2333 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2334
2335 name = copy_ssa_name (def, NULL);
2336 name_stmt = gimple_build_assign (name, zero_dim_array);
2337
2338 gimple_assign_set_lhs (name_stmt, name);
2339 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2340
2341 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2342 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2343 replace_exp (use_p, name);
2344
2345 update_stmt (use_stmt);
2346 }
2347
2348 /* For every definition DEF in the SCOP that is used outside the scop,
2349 insert a closing-scop definition in the basic block just after this
2350 SCOP. */
2351
2352 static void
2353 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2354 {
2355 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2356 tree new_name = make_ssa_name (var, stmt);
2357 bool needs_copy = false;
2358 use_operand_p use_p;
2359 imm_use_iterator imm_iter;
2360 gimple use_stmt;
2361 sese region = SCOP_REGION (scop);
2362
2363 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2364 {
2365 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2366 {
2367 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2368 {
2369 SET_USE (use_p, new_name);
2370 }
2371 update_stmt (use_stmt);
2372 needs_copy = true;
2373 }
2374 }
2375
2376 /* Insert in the empty BB just after the scop a use of DEF such
2377 that the rewrite of cross_bb_scalar_dependences won't insert
2378 arrays everywhere else. */
2379 if (needs_copy)
2380 {
2381 gimple assign = gimple_build_assign (new_name, def);
2382 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2383
2384 SSA_NAME_DEF_STMT (new_name) = assign;
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