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