]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/graphite-sese-to-poly.c
re PR tree-optimization/54886 (FAIL: gcc.dg/graphite/pr(42521|42771).c (internal...
[thirdparty/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 else
1062 isl_pw_aff_free (aff);
1063 }
1064 else
1065 gcc_unreachable ();
1066
1067 if (loop->inner && loop_in_sese_p (loop->inner, region))
1068 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1069 isl_set_copy (inner), doms);
1070
1071 if (nb != 0
1072 && loop->next
1073 && loop_in_sese_p (loop->next, region))
1074 build_loop_iteration_domains (scop, loop->next, nb,
1075 isl_set_copy (outer), doms);
1076
1077 doms[loop->num] = inner;
1078
1079 isl_set_free (outer);
1080 isl_space_free (space);
1081 isl_int_clear (v);
1082 mpz_clear (g);
1083 }
1084
1085 /* Returns a linear expression for tree T evaluated in PBB. */
1086
1087 static isl_pw_aff *
1088 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1089 {
1090 scop_p scop = PBB_SCOP (pbb);
1091
1092 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1093 gcc_assert (!automatically_generated_chrec_p (t));
1094
1095 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1096 }
1097
1098 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1099 operator. This allows us to invert the condition or to handle
1100 inequalities. */
1101
1102 static void
1103 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1104 {
1105 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1106 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1107 isl_set *cond;
1108
1109 switch (code)
1110 {
1111 case LT_EXPR:
1112 cond = isl_pw_aff_lt_set (lhs, rhs);
1113 break;
1114
1115 case GT_EXPR:
1116 cond = isl_pw_aff_gt_set (lhs, rhs);
1117 break;
1118
1119 case LE_EXPR:
1120 cond = isl_pw_aff_le_set (lhs, rhs);
1121 break;
1122
1123 case GE_EXPR:
1124 cond = isl_pw_aff_ge_set (lhs, rhs);
1125 break;
1126
1127 case EQ_EXPR:
1128 cond = isl_pw_aff_eq_set (lhs, rhs);
1129 break;
1130
1131 case NE_EXPR:
1132 cond = isl_pw_aff_ne_set (lhs, rhs);
1133 break;
1134
1135 default:
1136 isl_pw_aff_free(lhs);
1137 isl_pw_aff_free(rhs);
1138 return;
1139 }
1140
1141 cond = isl_set_coalesce (cond);
1142 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1143 pbb->domain = isl_set_intersect (pbb->domain, cond);
1144 }
1145
1146 /* Add conditions to the domain of PBB. */
1147
1148 static void
1149 add_conditions_to_domain (poly_bb_p pbb)
1150 {
1151 unsigned int i;
1152 gimple stmt;
1153 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1154
1155 if (GBB_CONDITIONS (gbb).is_empty ())
1156 return;
1157
1158 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1159 switch (gimple_code (stmt))
1160 {
1161 case GIMPLE_COND:
1162 {
1163 enum tree_code code = gimple_cond_code (stmt);
1164
1165 /* The conditions for ELSE-branches are inverted. */
1166 if (!GBB_CONDITION_CASES (gbb)[i])
1167 code = invert_tree_comparison (code, false);
1168
1169 add_condition_to_pbb (pbb, stmt, code);
1170 break;
1171 }
1172
1173 case GIMPLE_SWITCH:
1174 /* Switch statements are not supported right now - fall through. */
1175
1176 default:
1177 gcc_unreachable ();
1178 break;
1179 }
1180 }
1181
1182 /* Traverses all the GBBs of the SCOP and add their constraints to the
1183 iteration domains. */
1184
1185 static void
1186 add_conditions_to_constraints (scop_p scop)
1187 {
1188 int i;
1189 poly_bb_p pbb;
1190
1191 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1192 add_conditions_to_domain (pbb);
1193 }
1194
1195 /* Structure used to pass data to dom_walk. */
1196
1197 struct bsc
1198 {
1199 vec<gimple> *conditions, *cases;
1200 sese region;
1201 };
1202
1203 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1204 edge between BB and its predecessor is not a loop exit edge, and
1205 the last statement of the single predecessor is a COND_EXPR. */
1206
1207 static gimple
1208 single_pred_cond_non_loop_exit (basic_block bb)
1209 {
1210 if (single_pred_p (bb))
1211 {
1212 edge e = single_pred_edge (bb);
1213 basic_block pred = e->src;
1214 gimple stmt;
1215
1216 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1217 return NULL;
1218
1219 stmt = last_stmt (pred);
1220
1221 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1222 return stmt;
1223 }
1224
1225 return NULL;
1226 }
1227
1228 /* Call-back for dom_walk executed before visiting the dominated
1229 blocks. */
1230
1231 static void
1232 build_sese_conditions_before (struct dom_walk_data *dw_data,
1233 basic_block bb)
1234 {
1235 struct bsc *data = (struct bsc *) dw_data->global_data;
1236 vec<gimple> *conditions = data->conditions;
1237 vec<gimple> *cases = data->cases;
1238 gimple_bb_p gbb;
1239 gimple stmt;
1240
1241 if (!bb_in_sese_p (bb, data->region))
1242 return;
1243
1244 stmt = single_pred_cond_non_loop_exit (bb);
1245
1246 if (stmt)
1247 {
1248 edge e = single_pred_edge (bb);
1249
1250 conditions->safe_push (stmt);
1251
1252 if (e->flags & EDGE_TRUE_VALUE)
1253 cases->safe_push (stmt);
1254 else
1255 cases->safe_push (NULL);
1256 }
1257
1258 gbb = gbb_from_bb (bb);
1259
1260 if (gbb)
1261 {
1262 GBB_CONDITIONS (gbb) = conditions->copy ();
1263 GBB_CONDITION_CASES (gbb) = cases->copy ();
1264 }
1265 }
1266
1267 /* Call-back for dom_walk executed after visiting the dominated
1268 blocks. */
1269
1270 static void
1271 build_sese_conditions_after (struct dom_walk_data *dw_data,
1272 basic_block bb)
1273 {
1274 struct bsc *data = (struct bsc *) dw_data->global_data;
1275 vec<gimple> *conditions = data->conditions;
1276 vec<gimple> *cases = data->cases;
1277
1278 if (!bb_in_sese_p (bb, data->region))
1279 return;
1280
1281 if (single_pred_cond_non_loop_exit (bb))
1282 {
1283 conditions->pop ();
1284 cases->pop ();
1285 }
1286 }
1287
1288 /* Record all conditions in REGION. */
1289
1290 static void
1291 build_sese_conditions (sese region)
1292 {
1293 struct dom_walk_data walk_data;
1294 vec<gimple> conditions;
1295 conditions.create (3);
1296 vec<gimple> cases;
1297 cases.create (3);
1298 struct bsc data;
1299
1300 data.conditions = &conditions;
1301 data.cases = &cases;
1302 data.region = region;
1303
1304 walk_data.dom_direction = CDI_DOMINATORS;
1305 walk_data.initialize_block_local_data = NULL;
1306 walk_data.before_dom_children = build_sese_conditions_before;
1307 walk_data.after_dom_children = build_sese_conditions_after;
1308 walk_data.global_data = &data;
1309 walk_data.block_local_data_size = 0;
1310
1311 init_walk_dominator_tree (&walk_data);
1312 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1313 fini_walk_dominator_tree (&walk_data);
1314
1315 conditions.release ();
1316 cases.release ();
1317 }
1318
1319 /* Add constraints on the possible values of parameter P from the type
1320 of P. */
1321
1322 static void
1323 add_param_constraints (scop_p scop, graphite_dim_t p)
1324 {
1325 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1326 tree type = TREE_TYPE (parameter);
1327 tree lb = NULL_TREE;
1328 tree ub = NULL_TREE;
1329
1330 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1331 lb = lower_bound_in_type (type, type);
1332 else
1333 lb = TYPE_MIN_VALUE (type);
1334
1335 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1336 ub = upper_bound_in_type (type, type);
1337 else
1338 ub = TYPE_MAX_VALUE (type);
1339
1340 if (lb)
1341 {
1342 isl_space *space = isl_set_get_space (scop->context);
1343 isl_constraint *c;
1344 mpz_t g;
1345 isl_int v;
1346
1347 c = isl_inequality_alloc (isl_local_space_from_space (space));
1348 mpz_init (g);
1349 isl_int_init (v);
1350 tree_int_to_gmp (lb, g);
1351 isl_int_set_gmp (v, g);
1352 isl_int_neg (v, v);
1353 mpz_clear (g);
1354 c = isl_constraint_set_constant (c, v);
1355 isl_int_clear (v);
1356 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1357
1358 scop->context = isl_set_add_constraint (scop->context, c);
1359 }
1360
1361 if (ub)
1362 {
1363 isl_space *space = isl_set_get_space (scop->context);
1364 isl_constraint *c;
1365 mpz_t g;
1366 isl_int v;
1367
1368 c = isl_inequality_alloc (isl_local_space_from_space (space));
1369
1370 mpz_init (g);
1371 isl_int_init (v);
1372 tree_int_to_gmp (ub, g);
1373 isl_int_set_gmp (v, g);
1374 mpz_clear (g);
1375 c = isl_constraint_set_constant (c, v);
1376 isl_int_clear (v);
1377 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1378
1379 scop->context = isl_set_add_constraint (scop->context, c);
1380 }
1381 }
1382
1383 /* Build the context of the SCOP. The context usually contains extra
1384 constraints that are added to the iteration domains that constrain
1385 some parameters. */
1386
1387 static void
1388 build_scop_context (scop_p scop)
1389 {
1390 graphite_dim_t p, n = scop_nb_params (scop);
1391
1392 for (p = 0; p < n; p++)
1393 add_param_constraints (scop, p);
1394 }
1395
1396 /* Build the iteration domains: the loops belonging to the current
1397 SCOP, and that vary for the execution of the current basic block.
1398 Returns false if there is no loop in SCOP. */
1399
1400 static void
1401 build_scop_iteration_domain (scop_p scop)
1402 {
1403 struct loop *loop;
1404 sese region = SCOP_REGION (scop);
1405 int i;
1406 poly_bb_p pbb;
1407 int nb_loops = number_of_loops ();
1408 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1409
1410 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1411 if (!loop_in_sese_p (loop_outer (loop), region))
1412 build_loop_iteration_domains (scop, loop, 0,
1413 isl_set_copy (scop->context), doms);
1414
1415 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1416 {
1417 loop = pbb_loop (pbb);
1418
1419 if (doms[loop->num])
1420 pbb->domain = isl_set_copy (doms[loop->num]);
1421 else
1422 pbb->domain = isl_set_copy (scop->context);
1423
1424 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1425 isl_id_for_pbb (scop, pbb));
1426 }
1427
1428 for (i = 0; i < nb_loops; i++)
1429 if (doms[i])
1430 isl_set_free (doms[i]);
1431
1432 free (doms);
1433 }
1434
1435 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1436 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1437 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1438 domain. */
1439
1440 static isl_map *
1441 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1442 {
1443 isl_constraint *c;
1444 int alias_set_num = 0;
1445 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1446
1447 if (bap && bap->alias_set)
1448 alias_set_num = *(bap->alias_set);
1449
1450 c = isl_equality_alloc
1451 (isl_local_space_from_space (isl_map_get_space (acc)));
1452 c = isl_constraint_set_constant_si (c, -alias_set_num);
1453 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1454
1455 return isl_map_add_constraint (acc, c);
1456 }
1457
1458 /* Assign the affine expression INDEX to the output dimension POS of
1459 MAP and return the result. */
1460
1461 static isl_map *
1462 set_index (isl_map *map, int pos, isl_pw_aff *index)
1463 {
1464 isl_map *index_map;
1465 int len = isl_map_dim (map, isl_dim_out);
1466 isl_id *id;
1467
1468 index_map = isl_map_from_pw_aff (index);
1469 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1470 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1471
1472 id = isl_map_get_tuple_id (map, isl_dim_out);
1473 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1474 id = isl_map_get_tuple_id (map, isl_dim_in);
1475 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1476
1477 return isl_map_intersect (map, index_map);
1478 }
1479
1480 /* Add to ACCESSES polyhedron equalities defining the access functions
1481 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1482 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1483 PBB is the poly_bb_p that contains the data reference DR. */
1484
1485 static isl_map *
1486 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1487 {
1488 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1489 scop_p scop = PBB_SCOP (pbb);
1490
1491 for (i = 0; i < nb_subscripts; i++)
1492 {
1493 isl_pw_aff *aff;
1494 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1495
1496 aff = extract_affine (scop, afn,
1497 isl_space_domain (isl_map_get_space (acc)));
1498 acc = set_index (acc, i + 1, aff);
1499 }
1500
1501 return acc;
1502 }
1503
1504 /* Add constrains representing the size of the accessed data to the
1505 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1506 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1507 domain. */
1508
1509 static isl_set *
1510 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1511 {
1512 tree ref = DR_REF (dr);
1513 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1514
1515 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1516 {
1517 tree low, high;
1518
1519 if (TREE_CODE (ref) != ARRAY_REF)
1520 break;
1521
1522 low = array_ref_low_bound (ref);
1523 high = array_ref_up_bound (ref);
1524
1525 /* XXX The PPL code dealt separately with
1526 subscript - low >= 0 and high - subscript >= 0 in case one of
1527 the two bounds isn't known. Do the same here? */
1528
1529 if (host_integerp (low, 0)
1530 && high
1531 && host_integerp (high, 0)
1532 /* 1-element arrays at end of structures may extend over
1533 their declared size. */
1534 && !(array_at_struct_end_p (ref)
1535 && operand_equal_p (low, high, 0)))
1536 {
1537 isl_id *id;
1538 isl_aff *aff;
1539 isl_set *univ, *lbs, *ubs;
1540 isl_pw_aff *index;
1541 isl_space *space;
1542 isl_set *valid;
1543 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1544 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1545
1546 /* high >= 0 */
1547 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1548 valid = isl_set_project_out (valid, isl_dim_set, 0,
1549 isl_set_dim (valid, isl_dim_set));
1550 scop->context = isl_set_intersect (scop->context, valid);
1551
1552 space = isl_set_get_space (extent);
1553 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1554 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1555 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1556 index = isl_pw_aff_alloc (univ, aff);
1557
1558 id = isl_set_get_tuple_id (extent);
1559 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1560 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1561
1562 /* low <= sub_i <= high */
1563 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1564 ubs = isl_pw_aff_le_set (index, ub);
1565 extent = isl_set_intersect (extent, lbs);
1566 extent = isl_set_intersect (extent, ubs);
1567 }
1568 }
1569
1570 return extent;
1571 }
1572
1573 /* Build data accesses for DR in PBB. */
1574
1575 static void
1576 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1577 {
1578 int dr_base_object_set;
1579 isl_map *acc;
1580 isl_set *extent;
1581 scop_p scop = PBB_SCOP (pbb);
1582
1583 {
1584 isl_space *dc = isl_set_get_space (pbb->domain);
1585 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1586 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1587 isl_dim_out, nb_out);
1588
1589 acc = isl_map_universe (space);
1590 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1591 }
1592
1593 acc = pdr_add_alias_set (acc, dr);
1594 acc = pdr_add_memory_accesses (acc, dr, pbb);
1595
1596 {
1597 isl_id *id = isl_id_for_dr (scop, dr);
1598 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1599 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1600 int alias_set_num = 0;
1601 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1602
1603 if (bap && bap->alias_set)
1604 alias_set_num = *(bap->alias_set);
1605
1606 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1607 extent = isl_set_nat_universe (space);
1608 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1609 extent = pdr_add_data_dimensions (extent, scop, dr);
1610 }
1611
1612 gcc_assert (dr->aux);
1613 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1614
1615 new_poly_dr (pbb, dr_base_object_set,
1616 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1617 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1618 }
1619
1620 /* Write to FILE the alias graph of data references in DIMACS format. */
1621
1622 static inline bool
1623 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1624 vec<data_reference_p> drs)
1625 {
1626 int num_vertex = drs.length ();
1627 int edge_num = 0;
1628 data_reference_p dr1, dr2;
1629 int i, j;
1630
1631 if (num_vertex == 0)
1632 return true;
1633
1634 FOR_EACH_VEC_ELT (drs, i, dr1)
1635 for (j = i + 1; drs.iterate (j, &dr2); j++)
1636 if (dr_may_alias_p (dr1, dr2, true))
1637 edge_num++;
1638
1639 fprintf (file, "$\n");
1640
1641 if (comment)
1642 fprintf (file, "c %s\n", comment);
1643
1644 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1645
1646 FOR_EACH_VEC_ELT (drs, i, dr1)
1647 for (j = i + 1; drs.iterate (j, &dr2); j++)
1648 if (dr_may_alias_p (dr1, dr2, true))
1649 fprintf (file, "e %d %d\n", i + 1, j + 1);
1650
1651 return true;
1652 }
1653
1654 /* Write to FILE the alias graph of data references in DOT format. */
1655
1656 static inline bool
1657 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1658 vec<data_reference_p> drs)
1659 {
1660 int num_vertex = drs.length ();
1661 data_reference_p dr1, dr2;
1662 int i, j;
1663
1664 if (num_vertex == 0)
1665 return true;
1666
1667 fprintf (file, "$\n");
1668
1669 if (comment)
1670 fprintf (file, "c %s\n", comment);
1671
1672 /* First print all the vertices. */
1673 FOR_EACH_VEC_ELT (drs, i, dr1)
1674 fprintf (file, "n%d;\n", i);
1675
1676 FOR_EACH_VEC_ELT (drs, i, dr1)
1677 for (j = i + 1; drs.iterate (j, &dr2); j++)
1678 if (dr_may_alias_p (dr1, dr2, true))
1679 fprintf (file, "n%d n%d\n", i, j);
1680
1681 return true;
1682 }
1683
1684 /* Write to FILE the alias graph of data references in ECC format. */
1685
1686 static inline bool
1687 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1688 vec<data_reference_p> drs)
1689 {
1690 int num_vertex = drs.length ();
1691 data_reference_p dr1, dr2;
1692 int i, j;
1693
1694 if (num_vertex == 0)
1695 return true;
1696
1697 fprintf (file, "$\n");
1698
1699 if (comment)
1700 fprintf (file, "c %s\n", comment);
1701
1702 FOR_EACH_VEC_ELT (drs, i, dr1)
1703 for (j = i + 1; drs.iterate (j, &dr2); j++)
1704 if (dr_may_alias_p (dr1, dr2, true))
1705 fprintf (file, "%d %d\n", i, j);
1706
1707 return true;
1708 }
1709
1710 /* Check if DR1 and DR2 are in the same object set. */
1711
1712 static bool
1713 dr_same_base_object_p (const struct data_reference *dr1,
1714 const struct data_reference *dr2)
1715 {
1716 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1717 }
1718
1719 /* Uses DFS component number as representative of alias-sets. Also tests for
1720 optimality by verifying if every connected component is a clique. Returns
1721 true (1) if the above test is true, and false (0) otherwise. */
1722
1723 static int
1724 build_alias_set_optimal_p (vec<data_reference_p> drs)
1725 {
1726 int num_vertices = drs.length ();
1727 struct graph *g = new_graph (num_vertices);
1728 data_reference_p dr1, dr2;
1729 int i, j;
1730 int num_connected_components;
1731 int v_indx1, v_indx2, num_vertices_in_component;
1732 int *all_vertices;
1733 int *vertices;
1734 struct graph_edge *e;
1735 int this_component_is_clique;
1736 int all_components_are_cliques = 1;
1737
1738 FOR_EACH_VEC_ELT (drs, i, dr1)
1739 for (j = i+1; drs.iterate (j, &dr2); j++)
1740 if (dr_may_alias_p (dr1, dr2, true))
1741 {
1742 add_edge (g, i, j);
1743 add_edge (g, j, i);
1744 }
1745
1746 all_vertices = XNEWVEC (int, num_vertices);
1747 vertices = XNEWVEC (int, num_vertices);
1748 for (i = 0; i < num_vertices; i++)
1749 all_vertices[i] = i;
1750
1751 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1752 NULL, true, NULL);
1753 for (i = 0; i < g->n_vertices; i++)
1754 {
1755 data_reference_p dr = drs[i];
1756 base_alias_pair *bap;
1757
1758 gcc_assert (dr->aux);
1759 bap = (base_alias_pair *)(dr->aux);
1760
1761 bap->alias_set = XNEW (int);
1762 *(bap->alias_set) = g->vertices[i].component + 1;
1763 }
1764
1765 /* Verify if the DFS numbering results in optimal solution. */
1766 for (i = 0; i < num_connected_components; i++)
1767 {
1768 num_vertices_in_component = 0;
1769 /* Get all vertices whose DFS component number is the same as i. */
1770 for (j = 0; j < num_vertices; j++)
1771 if (g->vertices[j].component == i)
1772 vertices[num_vertices_in_component++] = j;
1773
1774 /* Now test if the vertices in 'vertices' form a clique, by testing
1775 for edges among each pair. */
1776 this_component_is_clique = 1;
1777 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1778 {
1779 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1780 {
1781 /* Check if the two vertices are connected by iterating
1782 through all the edges which have one of these are source. */
1783 e = g->vertices[vertices[v_indx2]].pred;
1784 while (e)
1785 {
1786 if (e->src == vertices[v_indx1])
1787 break;
1788 e = e->pred_next;
1789 }
1790 if (!e)
1791 {
1792 this_component_is_clique = 0;
1793 break;
1794 }
1795 }
1796 if (!this_component_is_clique)
1797 all_components_are_cliques = 0;
1798 }
1799 }
1800
1801 free (all_vertices);
1802 free (vertices);
1803 free_graph (g);
1804 return all_components_are_cliques;
1805 }
1806
1807 /* Group each data reference in DRS with its base object set num. */
1808
1809 static void
1810 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1811 {
1812 int num_vertex = drs.length ();
1813 struct graph *g = new_graph (num_vertex);
1814 data_reference_p dr1, dr2;
1815 int i, j;
1816 int *queue;
1817
1818 FOR_EACH_VEC_ELT (drs, i, dr1)
1819 for (j = i + 1; drs.iterate (j, &dr2); j++)
1820 if (dr_same_base_object_p (dr1, dr2))
1821 {
1822 add_edge (g, i, j);
1823 add_edge (g, j, i);
1824 }
1825
1826 queue = XNEWVEC (int, num_vertex);
1827 for (i = 0; i < num_vertex; i++)
1828 queue[i] = i;
1829
1830 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1831
1832 for (i = 0; i < g->n_vertices; i++)
1833 {
1834 data_reference_p dr = drs[i];
1835 base_alias_pair *bap;
1836
1837 gcc_assert (dr->aux);
1838 bap = (base_alias_pair *)(dr->aux);
1839
1840 bap->base_obj_set = g->vertices[i].component + 1;
1841 }
1842
1843 free (queue);
1844 free_graph (g);
1845 }
1846
1847 /* Build the data references for PBB. */
1848
1849 static void
1850 build_pbb_drs (poly_bb_p pbb)
1851 {
1852 int j;
1853 data_reference_p dr;
1854 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1855
1856 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1857 build_poly_dr (dr, pbb);
1858 }
1859
1860 /* Dump to file the alias graphs for the data references in DRS. */
1861
1862 static void
1863 dump_alias_graphs (vec<data_reference_p> drs)
1864 {
1865 char comment[100];
1866 FILE *file_dimacs, *file_ecc, *file_dot;
1867
1868 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1869 if (file_dimacs)
1870 {
1871 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1872 current_function_name ());
1873 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1874 fclose (file_dimacs);
1875 }
1876
1877 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1878 if (file_ecc)
1879 {
1880 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1881 current_function_name ());
1882 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1883 fclose (file_ecc);
1884 }
1885
1886 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1887 if (file_dot)
1888 {
1889 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1890 current_function_name ());
1891 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1892 fclose (file_dot);
1893 }
1894 }
1895
1896 /* Build data references in SCOP. */
1897
1898 static void
1899 build_scop_drs (scop_p scop)
1900 {
1901 int i, j;
1902 poly_bb_p pbb;
1903 data_reference_p dr;
1904 vec<data_reference_p> drs;
1905 drs.create (3);
1906
1907 /* Remove all the PBBs that do not have data references: these basic
1908 blocks are not handled in the polyhedral representation. */
1909 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1910 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1911 {
1912 free_gimple_bb (PBB_BLACK_BOX (pbb));
1913 free_poly_bb (pbb);
1914 SCOP_BBS (scop).ordered_remove (i);
1915 i--;
1916 }
1917
1918 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1919 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1920 drs.safe_push (dr);
1921
1922 FOR_EACH_VEC_ELT (drs, i, dr)
1923 dr->aux = XNEW (base_alias_pair);
1924
1925 if (!build_alias_set_optimal_p (drs))
1926 {
1927 /* TODO: Add support when building alias set is not optimal. */
1928 ;
1929 }
1930
1931 build_base_obj_set_for_drs (drs);
1932
1933 /* When debugging, enable the following code. This cannot be used
1934 in production compilers. */
1935 if (0)
1936 dump_alias_graphs (drs);
1937
1938 drs.release ();
1939
1940 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1941 build_pbb_drs (pbb);
1942 }
1943
1944 /* Return a gsi at the position of the phi node STMT. */
1945
1946 static gimple_stmt_iterator
1947 gsi_for_phi_node (gimple stmt)
1948 {
1949 gimple_stmt_iterator psi;
1950 basic_block bb = gimple_bb (stmt);
1951
1952 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1953 if (stmt == gsi_stmt (psi))
1954 return psi;
1955
1956 gcc_unreachable ();
1957 return psi;
1958 }
1959
1960 /* Analyze all the data references of STMTS and add them to the
1961 GBB_DATA_REFS vector of BB. */
1962
1963 static void
1964 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1965 {
1966 loop_p nest;
1967 gimple_bb_p gbb;
1968 gimple stmt;
1969 int i;
1970 sese region = SCOP_REGION (scop);
1971
1972 if (!bb_in_sese_p (bb, region))
1973 return;
1974
1975 nest = outermost_loop_in_sese_1 (region, bb);
1976 gbb = gbb_from_bb (bb);
1977
1978 FOR_EACH_VEC_ELT (stmts, i, stmt)
1979 {
1980 loop_p loop;
1981
1982 if (is_gimple_debug (stmt))
1983 continue;
1984
1985 loop = loop_containing_stmt (stmt);
1986 if (!loop_in_sese_p (loop, region))
1987 loop = nest;
1988
1989 graphite_find_data_references_in_stmt (nest, loop, stmt,
1990 &GBB_DATA_REFS (gbb));
1991 }
1992 }
1993
1994 /* Insert STMT at the end of the STMTS sequence and then insert the
1995 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1996 on STMTS. */
1997
1998 static void
1999 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2000 gimple_stmt_iterator insert_gsi)
2001 {
2002 gimple_stmt_iterator gsi;
2003 vec<gimple> x;
2004 x.create (3);
2005
2006 gimple_seq_add_stmt (&stmts, stmt);
2007 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2008 x.safe_push (gsi_stmt (gsi));
2009
2010 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2011 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2012 x.release ();
2013 }
2014
2015 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2016
2017 static void
2018 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2019 {
2020 gimple_seq stmts;
2021 gimple_stmt_iterator gsi;
2022 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2023 gimple stmt = gimple_build_assign (res, var);
2024 vec<gimple> x;
2025 x.create (3);
2026
2027 gimple_seq_add_stmt (&stmts, stmt);
2028 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2029 x.safe_push (gsi_stmt (gsi));
2030
2031 if (gimple_code (after_stmt) == GIMPLE_PHI)
2032 {
2033 gsi = gsi_after_labels (gimple_bb (after_stmt));
2034 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2035 }
2036 else
2037 {
2038 gsi = gsi_for_stmt (after_stmt);
2039 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2040 }
2041
2042 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2043 x.release ();
2044 }
2045
2046 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2047
2048 static void
2049 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2050 {
2051 vec<data_reference_p> drs;
2052 drs.create (3);
2053 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2054 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2055 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2056 int index, n = SCOP_BBS (scop).length ();
2057
2058 /* The INDEX of PBB in SCOP_BBS. */
2059 for (index = 0; index < n; index++)
2060 if (SCOP_BBS (scop)[index] == pbb)
2061 break;
2062
2063 pbb1->domain = isl_set_copy (pbb->domain);
2064
2065 GBB_PBB (gbb1) = pbb1;
2066 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2067 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2068 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2069 }
2070
2071 /* Insert on edge E the assignment "RES := EXPR". */
2072
2073 static void
2074 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2075 {
2076 gimple_stmt_iterator gsi;
2077 gimple_seq stmts = NULL;
2078 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2079 gimple stmt = gimple_build_assign (res, var);
2080 basic_block bb;
2081 vec<gimple> x;
2082 x.create (3);
2083
2084 gimple_seq_add_stmt (&stmts, stmt);
2085 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2086 x.safe_push (gsi_stmt (gsi));
2087
2088 gsi_insert_seq_on_edge (e, stmts);
2089 gsi_commit_edge_inserts ();
2090 bb = gimple_bb (stmt);
2091
2092 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2093 return;
2094
2095 if (!gbb_from_bb (bb))
2096 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2097
2098 analyze_drs_in_stmts (scop, bb, x);
2099 x.release ();
2100 }
2101
2102 /* Creates a zero dimension array of the same type as VAR. */
2103
2104 static tree
2105 create_zero_dim_array (tree var, const char *base_name)
2106 {
2107 tree index_type = build_index_type (integer_zero_node);
2108 tree elt_type = TREE_TYPE (var);
2109 tree array_type = build_array_type (elt_type, index_type);
2110 tree base = create_tmp_var (array_type, base_name);
2111
2112 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2113 NULL_TREE);
2114 }
2115
2116 /* Returns true when PHI is a loop close phi node. */
2117
2118 static bool
2119 scalar_close_phi_node_p (gimple phi)
2120 {
2121 if (gimple_code (phi) != GIMPLE_PHI
2122 || virtual_operand_p (gimple_phi_result (phi)))
2123 return false;
2124
2125 /* Note that loop close phi nodes should have a single argument
2126 because we translated the representation into a canonical form
2127 before Graphite: see canonicalize_loop_closed_ssa_form. */
2128 return (gimple_phi_num_args (phi) == 1);
2129 }
2130
2131 /* For a definition DEF in REGION, propagates the expression EXPR in
2132 all the uses of DEF outside REGION. */
2133
2134 static void
2135 propagate_expr_outside_region (tree def, tree expr, sese region)
2136 {
2137 imm_use_iterator imm_iter;
2138 gimple use_stmt;
2139 gimple_seq stmts;
2140 bool replaced_once = false;
2141
2142 gcc_assert (TREE_CODE (def) == SSA_NAME);
2143
2144 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2145 NULL_TREE);
2146
2147 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2148 if (!is_gimple_debug (use_stmt)
2149 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2150 {
2151 ssa_op_iter iter;
2152 use_operand_p use_p;
2153
2154 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2155 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2156 && (replaced_once = true))
2157 replace_exp (use_p, expr);
2158
2159 update_stmt (use_stmt);
2160 }
2161
2162 if (replaced_once)
2163 {
2164 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2165 gsi_commit_edge_inserts ();
2166 }
2167 }
2168
2169 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2170 dimension array for it. */
2171
2172 static void
2173 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2174 {
2175 sese region = SCOP_REGION (scop);
2176 gimple phi = gsi_stmt (*psi);
2177 tree res = gimple_phi_result (phi);
2178 basic_block bb = gimple_bb (phi);
2179 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2180 tree arg = gimple_phi_arg_def (phi, 0);
2181 gimple stmt;
2182
2183 /* Note that loop close phi nodes should have a single argument
2184 because we translated the representation into a canonical form
2185 before Graphite: see canonicalize_loop_closed_ssa_form. */
2186 gcc_assert (gimple_phi_num_args (phi) == 1);
2187
2188 /* The phi node can be a non close phi node, when its argument is
2189 invariant, or a default definition. */
2190 if (is_gimple_min_invariant (arg)
2191 || SSA_NAME_IS_DEFAULT_DEF (arg))
2192 {
2193 propagate_expr_outside_region (res, arg, region);
2194 gsi_next (psi);
2195 return;
2196 }
2197
2198 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2199 {
2200 propagate_expr_outside_region (res, arg, region);
2201 stmt = gimple_build_assign (res, arg);
2202 remove_phi_node (psi, false);
2203 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2204 SSA_NAME_DEF_STMT (res) = stmt;
2205 return;
2206 }
2207
2208 /* If res is scev analyzable and is not a scalar value, it is safe
2209 to ignore the close phi node: it will be code generated in the
2210 out of Graphite pass. */
2211 else if (scev_analyzable_p (res, region))
2212 {
2213 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2214 tree scev;
2215
2216 if (!loop_in_sese_p (loop, region))
2217 {
2218 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2219 scev = scalar_evolution_in_region (region, loop, arg);
2220 scev = compute_overall_effect_of_inner_loop (loop, scev);
2221 }
2222 else
2223 scev = scalar_evolution_in_region (region, loop, res);
2224
2225 if (tree_does_not_contain_chrecs (scev))
2226 propagate_expr_outside_region (res, scev, region);
2227
2228 gsi_next (psi);
2229 return;
2230 }
2231 else
2232 {
2233 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2234
2235 stmt = gimple_build_assign (res, zero_dim_array);
2236
2237 if (TREE_CODE (arg) == SSA_NAME)
2238 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2239 SSA_NAME_DEF_STMT (arg));
2240 else
2241 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2242 zero_dim_array, arg);
2243 }
2244
2245 remove_phi_node (psi, false);
2246 SSA_NAME_DEF_STMT (res) = stmt;
2247
2248 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2249 }
2250
2251 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2252 dimension array for it. */
2253
2254 static void
2255 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2256 {
2257 size_t i;
2258 gimple phi = gsi_stmt (*psi);
2259 basic_block bb = gimple_bb (phi);
2260 tree res = gimple_phi_result (phi);
2261 tree var;
2262 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2263 gimple stmt;
2264 gimple_seq stmts;
2265
2266 for (i = 0; i < gimple_phi_num_args (phi); i++)
2267 {
2268 tree arg = gimple_phi_arg_def (phi, i);
2269 edge e = gimple_phi_arg_edge (phi, i);
2270
2271 /* Avoid the insertion of code in the loop latch to please the
2272 pattern matching of the vectorizer. */
2273 if (TREE_CODE (arg) == SSA_NAME
2274 && e->src == bb->loop_father->latch)
2275 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2276 SSA_NAME_DEF_STMT (arg));
2277 else
2278 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2279 }
2280
2281 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2282
2283 stmt = gimple_build_assign (res, var);
2284 remove_phi_node (psi, false);
2285 SSA_NAME_DEF_STMT (res) = stmt;
2286
2287 insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2288 }
2289
2290 /* Rewrite the degenerate phi node at position PSI from the degenerate
2291 form "x = phi (y, y, ..., y)" to "x = y". */
2292
2293 static void
2294 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2295 {
2296 tree rhs;
2297 gimple stmt;
2298 gimple_stmt_iterator gsi;
2299 gimple phi = gsi_stmt (*psi);
2300 tree res = gimple_phi_result (phi);
2301 basic_block bb;
2302
2303 bb = gimple_bb (phi);
2304 rhs = degenerate_phi_result (phi);
2305 gcc_assert (rhs);
2306
2307 stmt = gimple_build_assign (res, rhs);
2308 remove_phi_node (psi, false);
2309 SSA_NAME_DEF_STMT (res) = stmt;
2310
2311 gsi = gsi_after_labels (bb);
2312 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2313 }
2314
2315 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2316
2317 static void
2318 rewrite_reductions_out_of_ssa (scop_p scop)
2319 {
2320 basic_block bb;
2321 gimple_stmt_iterator psi;
2322 sese region = SCOP_REGION (scop);
2323
2324 FOR_EACH_BB (bb)
2325 if (bb_in_sese_p (bb, region))
2326 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2327 {
2328 gimple phi = gsi_stmt (psi);
2329
2330 if (virtual_operand_p (gimple_phi_result (phi)))
2331 {
2332 gsi_next (&psi);
2333 continue;
2334 }
2335
2336 if (gimple_phi_num_args (phi) > 1
2337 && degenerate_phi_result (phi))
2338 rewrite_degenerate_phi (&psi);
2339
2340 else if (scalar_close_phi_node_p (phi))
2341 rewrite_close_phi_out_of_ssa (scop, &psi);
2342
2343 else if (reduction_phi_p (region, &psi))
2344 rewrite_phi_out_of_ssa (scop, &psi);
2345 }
2346
2347 update_ssa (TODO_update_ssa);
2348 #ifdef ENABLE_CHECKING
2349 verify_loop_closed_ssa (true);
2350 #endif
2351 }
2352
2353 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2354 read from ZERO_DIM_ARRAY. */
2355
2356 static void
2357 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2358 tree def, gimple use_stmt)
2359 {
2360 gimple name_stmt;
2361 tree name;
2362 ssa_op_iter iter;
2363 use_operand_p use_p;
2364
2365 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2366
2367 name = copy_ssa_name (def, NULL);
2368 name_stmt = gimple_build_assign (name, zero_dim_array);
2369
2370 gimple_assign_set_lhs (name_stmt, name);
2371 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2372
2373 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2374 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2375 replace_exp (use_p, name);
2376
2377 update_stmt (use_stmt);
2378 }
2379
2380 /* For every definition DEF in the SCOP that is used outside the scop,
2381 insert a closing-scop definition in the basic block just after this
2382 SCOP. */
2383
2384 static void
2385 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2386 {
2387 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2388 tree new_name = make_ssa_name (var, stmt);
2389 bool needs_copy = false;
2390 use_operand_p use_p;
2391 imm_use_iterator imm_iter;
2392 gimple use_stmt;
2393 sese region = SCOP_REGION (scop);
2394
2395 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2396 {
2397 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2398 {
2399 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2400 {
2401 SET_USE (use_p, new_name);
2402 }
2403 update_stmt (use_stmt);
2404 needs_copy = true;
2405 }
2406 }
2407
2408 /* Insert in the empty BB just after the scop a use of DEF such
2409 that the rewrite of cross_bb_scalar_dependences won't insert
2410 arrays everywhere else. */
2411 if (needs_copy)
2412 {
2413 gimple assign = gimple_build_assign (new_name, def);
2414 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2415
2416 SSA_NAME_DEF_STMT (new_name) = assign;
2417 update_stmt (assign);
2418 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2419 }
2420 }
2421
2422 /* Rewrite the scalar dependences crossing the boundary of the BB
2423 containing STMT with an array. Return true when something has been
2424 changed. */
2425
2426 static bool
2427 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2428 {
2429 sese region = SCOP_REGION (scop);
2430 gimple stmt = gsi_stmt (*gsi);
2431 imm_use_iterator imm_iter;
2432 tree def;
2433 basic_block def_bb;
2434 tree zero_dim_array = NULL_TREE;
2435 gimple use_stmt;
2436 bool res = false;
2437
2438 switch (gimple_code (stmt))
2439 {
2440 case GIMPLE_ASSIGN:
2441 def = gimple_assign_lhs (stmt);
2442 break;
2443
2444 case GIMPLE_CALL:
2445 def = gimple_call_lhs (stmt);
2446 break;
2447
2448 default:
2449 return false;
2450 }
2451
2452 if (!def
2453 || !is_gimple_reg (def))
2454 return false;
2455
2456 if (scev_analyzable_p (def, region))
2457 {
2458 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2459 tree scev = scalar_evolution_in_region (region, loop, def);
2460
2461 if (tree_contains_chrecs (scev, NULL))
2462 return false;
2463
2464 propagate_expr_outside_region (def, scev, region);
2465 return true;
2466 }
2467
2468 def_bb = gimple_bb (stmt);
2469
2470 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2471
2472 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2473 if (gimple_code (use_stmt) == GIMPLE_PHI
2474 && (res = true))
2475 {
2476 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2477
2478 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2479 rewrite_close_phi_out_of_ssa (scop, &psi);
2480 else
2481 rewrite_phi_out_of_ssa (scop, &psi);
2482 }
2483
2484 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2485 if (gimple_code (use_stmt) != GIMPLE_PHI
2486 && def_bb != gimple_bb (use_stmt)
2487 && !is_gimple_debug (use_stmt)
2488 && (res = true))
2489 {
2490 if (!zero_dim_array)
2491 {
2492 zero_dim_array = create_zero_dim_array
2493 (def, "Cross_BB_scalar_dependence");
2494 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2495 SSA_NAME_DEF_STMT (def));
2496 gsi_next (gsi);
2497 }
2498
2499 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2500 def, use_stmt);
2501 }
2502
2503 return res;
2504 }
2505
2506 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2507
2508 static void
2509 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2510 {
2511 basic_block bb;
2512 gimple_stmt_iterator psi;
2513 sese region = SCOP_REGION (scop);
2514 bool changed = false;
2515
2516 /* Create an extra empty BB after the scop. */
2517 split_edge (SESE_EXIT (region));
2518
2519 FOR_EACH_BB (bb)
2520 if (bb_in_sese_p (bb, region))
2521 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2522 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2523
2524 if (changed)
2525 {
2526 scev_reset_htab ();
2527 update_ssa (TODO_update_ssa);
2528 #ifdef ENABLE_CHECKING
2529 verify_loop_closed_ssa (true);
2530 #endif
2531 }
2532 }
2533
2534 /* Returns the number of pbbs that are in loops contained in SCOP. */
2535
2536 static int
2537 nb_pbbs_in_loops (scop_p scop)
2538 {
2539 int i;
2540 poly_bb_p pbb;
2541 int res = 0;
2542
2543 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2544 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2545 res++;
2546
2547 return res;
2548 }
2549
2550 /* Return the number of data references in BB that write in
2551 memory. */
2552
2553 static int
2554 nb_data_writes_in_bb (basic_block bb)
2555 {
2556 int res = 0;
2557 gimple_stmt_iterator gsi;
2558
2559 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2560 if (gimple_vdef (gsi_stmt (gsi)))
2561 res++;
2562
2563 return res;
2564 }
2565
2566 /* Splits at STMT the basic block BB represented as PBB in the
2567 polyhedral form. */
2568
2569 static edge
2570 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2571 {
2572 edge e1 = split_block (bb, stmt);
2573 new_pbb_from_pbb (scop, pbb, e1->dest);
2574 return e1;
2575 }
2576
2577 /* Splits STMT out of its current BB. This is done for reduction
2578 statements for which we want to ignore data dependences. */
2579
2580 static basic_block
2581 split_reduction_stmt (scop_p scop, gimple stmt)
2582 {
2583 basic_block bb = gimple_bb (stmt);
2584 poly_bb_p pbb = pbb_from_bb (bb);
2585 gimple_bb_p gbb = gbb_from_bb (bb);
2586 edge e1;
2587 int i;
2588 data_reference_p dr;
2589
2590 /* Do not split basic blocks with no writes to memory: the reduction
2591 will be the only write to memory. */
2592 if (nb_data_writes_in_bb (bb) == 0
2593 /* Or if we have already marked BB as a reduction. */
2594 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2595 return bb;
2596
2597 e1 = split_pbb (scop, pbb, bb, stmt);
2598
2599 /* Split once more only when the reduction stmt is not the only one
2600 left in the original BB. */
2601 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2602 {
2603 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2604 gsi_prev (&gsi);
2605 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2606 }
2607
2608 /* A part of the data references will end in a different basic block
2609 after the split: move the DRs from the original GBB to the newly
2610 created GBB1. */
2611 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2612 {
2613 basic_block bb1 = gimple_bb (DR_STMT (dr));
2614
2615 if (bb1 != bb)
2616 {
2617 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2618 GBB_DATA_REFS (gbb1).safe_push (dr);
2619 GBB_DATA_REFS (gbb).ordered_remove (i);
2620 i--;
2621 }
2622 }
2623
2624 return e1->dest;
2625 }
2626
2627 /* Return true when stmt is a reduction operation. */
2628
2629 static inline bool
2630 is_reduction_operation_p (gimple stmt)
2631 {
2632 enum tree_code code;
2633
2634 gcc_assert (is_gimple_assign (stmt));
2635 code = gimple_assign_rhs_code (stmt);
2636
2637 return flag_associative_math
2638 && commutative_tree_code (code)
2639 && associative_tree_code (code);
2640 }
2641
2642 /* Returns true when PHI contains an argument ARG. */
2643
2644 static bool
2645 phi_contains_arg (gimple phi, tree arg)
2646 {
2647 size_t i;
2648
2649 for (i = 0; i < gimple_phi_num_args (phi); i++)
2650 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2651 return true;
2652
2653 return false;
2654 }
2655
2656 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2657
2658 static gimple
2659 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2660 {
2661 gimple stmt;
2662
2663 if (TREE_CODE (arg) != SSA_NAME)
2664 return NULL;
2665
2666 stmt = SSA_NAME_DEF_STMT (arg);
2667
2668 if (gimple_code (stmt) == GIMPLE_NOP
2669 || gimple_code (stmt) == GIMPLE_CALL)
2670 return NULL;
2671
2672 if (gimple_code (stmt) == GIMPLE_PHI)
2673 {
2674 if (phi_contains_arg (stmt, lhs))
2675 return stmt;
2676 return NULL;
2677 }
2678
2679 if (!is_gimple_assign (stmt))
2680 return NULL;
2681
2682 if (gimple_num_ops (stmt) == 2)
2683 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2684
2685 if (is_reduction_operation_p (stmt))
2686 {
2687 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2688
2689 return res ? res :
2690 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2691 }
2692
2693 return NULL;
2694 }
2695
2696 /* Detect commutative and associative scalar reductions starting at
2697 the STMT. Return the phi node of the reduction cycle, or NULL. */
2698
2699 static gimple
2700 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2701 vec<gimple> *in,
2702 vec<gimple> *out)
2703 {
2704 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2705
2706 if (!phi)
2707 return NULL;
2708
2709 in->safe_push (stmt);
2710 out->safe_push (stmt);
2711 return phi;
2712 }
2713
2714 /* Detect commutative and associative scalar reductions starting at
2715 STMT. Return the phi node of the reduction cycle, or NULL. */
2716
2717 static gimple
2718 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2719 vec<gimple> *out)
2720 {
2721 tree lhs = gimple_assign_lhs (stmt);
2722
2723 if (gimple_num_ops (stmt) == 2)
2724 return detect_commutative_reduction_arg (lhs, stmt,
2725 gimple_assign_rhs1 (stmt),
2726 in, out);
2727
2728 if (is_reduction_operation_p (stmt))
2729 {
2730 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2731 gimple_assign_rhs1 (stmt),
2732 in, out);
2733 return res ? res
2734 : detect_commutative_reduction_arg (lhs, stmt,
2735 gimple_assign_rhs2 (stmt),
2736 in, out);
2737 }
2738
2739 return NULL;
2740 }
2741
2742 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2743
2744 static gimple
2745 follow_inital_value_to_phi (tree arg, tree lhs)
2746 {
2747 gimple stmt;
2748
2749 if (!arg || TREE_CODE (arg) != SSA_NAME)
2750 return NULL;
2751
2752 stmt = SSA_NAME_DEF_STMT (arg);
2753
2754 if (gimple_code (stmt) == GIMPLE_PHI
2755 && phi_contains_arg (stmt, lhs))
2756 return stmt;
2757
2758 return NULL;
2759 }
2760
2761
2762 /* Return the argument of the loop PHI that is the initial value coming
2763 from outside the loop. */
2764
2765 static edge
2766 edge_initial_value_for_loop_phi (gimple phi)
2767 {
2768 size_t i;
2769
2770 for (i = 0; i < gimple_phi_num_args (phi); i++)
2771 {
2772 edge e = gimple_phi_arg_edge (phi, i);
2773
2774 if (loop_depth (e->src->loop_father)
2775 < loop_depth (e->dest->loop_father))
2776 return e;
2777 }
2778
2779 return NULL;
2780 }
2781
2782 /* Return the argument of the loop PHI that is the initial value coming
2783 from outside the loop. */
2784
2785 static tree
2786 initial_value_for_loop_phi (gimple phi)
2787 {
2788 size_t i;
2789
2790 for (i = 0; i < gimple_phi_num_args (phi); i++)
2791 {
2792 edge e = gimple_phi_arg_edge (phi, i);
2793
2794 if (loop_depth (e->src->loop_father)
2795 < loop_depth (e->dest->loop_father))
2796 return gimple_phi_arg_def (phi, i);
2797 }
2798
2799 return NULL_TREE;
2800 }
2801
2802 /* Returns true when DEF is used outside the reduction cycle of
2803 LOOP_PHI. */
2804
2805 static bool
2806 used_outside_reduction (tree def, gimple loop_phi)
2807 {
2808 use_operand_p use_p;
2809 imm_use_iterator imm_iter;
2810 loop_p loop = loop_containing_stmt (loop_phi);
2811
2812 /* In LOOP, DEF should be used only in LOOP_PHI. */
2813 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2814 {
2815 gimple stmt = USE_STMT (use_p);
2816
2817 if (stmt != loop_phi
2818 && !is_gimple_debug (stmt)
2819 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2820 return true;
2821 }
2822
2823 return false;
2824 }
2825
2826 /* Detect commutative and associative scalar reductions belonging to
2827 the SCOP starting at the loop closed phi node STMT. Return the phi
2828 node of the reduction cycle, or NULL. */
2829
2830 static gimple
2831 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2832 vec<gimple> *out)
2833 {
2834 if (scalar_close_phi_node_p (stmt))
2835 {
2836 gimple def, loop_phi, phi, close_phi = stmt;
2837 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2838
2839 if (TREE_CODE (arg) != SSA_NAME)
2840 return NULL;
2841
2842 /* Note that loop close phi nodes should have a single argument
2843 because we translated the representation into a canonical form
2844 before Graphite: see canonicalize_loop_closed_ssa_form. */
2845 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2846
2847 def = SSA_NAME_DEF_STMT (arg);
2848 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2849 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2850 return NULL;
2851
2852 lhs = gimple_phi_result (close_phi);
2853 init = initial_value_for_loop_phi (loop_phi);
2854 phi = follow_inital_value_to_phi (init, lhs);
2855
2856 if (phi && (used_outside_reduction (lhs, phi)
2857 || !has_single_use (gimple_phi_result (phi))))
2858 return NULL;
2859
2860 in->safe_push (loop_phi);
2861 out->safe_push (close_phi);
2862 return phi;
2863 }
2864
2865 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2866 return detect_commutative_reduction_assign (stmt, in, out);
2867
2868 return NULL;
2869 }
2870
2871 /* Translate the scalar reduction statement STMT to an array RED
2872 knowing that its recursive phi node is LOOP_PHI. */
2873
2874 static void
2875 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2876 gimple stmt, gimple loop_phi)
2877 {
2878 tree res = gimple_phi_result (loop_phi);
2879 gimple assign = gimple_build_assign (res, unshare_expr (red));
2880 gimple_stmt_iterator gsi;
2881
2882 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2883
2884 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2885 gsi = gsi_for_stmt (stmt);
2886 gsi_next (&gsi);
2887 insert_stmts (scop, assign, NULL, gsi);
2888 }
2889
2890 /* Removes the PHI node and resets all the debug stmts that are using
2891 the PHI_RESULT. */
2892
2893 static void
2894 remove_phi (gimple phi)
2895 {
2896 imm_use_iterator imm_iter;
2897 tree def;
2898 use_operand_p use_p;
2899 gimple_stmt_iterator gsi;
2900 vec<gimple> update;
2901 update.create (3);
2902 unsigned int i;
2903 gimple stmt;
2904
2905 def = PHI_RESULT (phi);
2906 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2907 {
2908 stmt = USE_STMT (use_p);
2909
2910 if (is_gimple_debug (stmt))
2911 {
2912 gimple_debug_bind_reset_value (stmt);
2913 update.safe_push (stmt);
2914 }
2915 }
2916
2917 FOR_EACH_VEC_ELT (update, i, stmt)
2918 update_stmt (stmt);
2919
2920 update.release ();
2921
2922 gsi = gsi_for_phi_node (phi);
2923 remove_phi_node (&gsi, false);
2924 }
2925
2926 /* Helper function for for_each_index. For each INDEX of the data
2927 reference REF, returns true when its indices are valid in the loop
2928 nest LOOP passed in as DATA. */
2929
2930 static bool
2931 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2932 {
2933 loop_p loop;
2934 basic_block header, def_bb;
2935 gimple stmt;
2936
2937 if (TREE_CODE (*index) != SSA_NAME)
2938 return true;
2939
2940 loop = *((loop_p *) data);
2941 header = loop->header;
2942 stmt = SSA_NAME_DEF_STMT (*index);
2943
2944 if (!stmt)
2945 return true;
2946
2947 def_bb = gimple_bb (stmt);
2948
2949 if (!def_bb)
2950 return true;
2951
2952 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2953 }
2954
2955 /* When the result of a CLOSE_PHI is written to a memory location,
2956 return a pointer to that memory reference, otherwise return
2957 NULL_TREE. */
2958
2959 static tree
2960 close_phi_written_to_memory (gimple close_phi)
2961 {
2962 imm_use_iterator imm_iter;
2963 use_operand_p use_p;
2964 gimple stmt;
2965 tree res, def = gimple_phi_result (close_phi);
2966
2967 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2968 if ((stmt = USE_STMT (use_p))
2969 && gimple_code (stmt) == GIMPLE_ASSIGN
2970 && (res = gimple_assign_lhs (stmt)))
2971 {
2972 switch (TREE_CODE (res))
2973 {
2974 case VAR_DECL:
2975 case PARM_DECL:
2976 case RESULT_DECL:
2977 return res;
2978
2979 case ARRAY_REF:
2980 case MEM_REF:
2981 {
2982 tree arg = gimple_phi_arg_def (close_phi, 0);
2983 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2984
2985 /* FIXME: this restriction is for id-{24,25}.f and
2986 could be handled by duplicating the computation of
2987 array indices before the loop of the close_phi. */
2988 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2989 return res;
2990 }
2991 /* Fallthru. */
2992
2993 default:
2994 continue;
2995 }
2996 }
2997 return NULL_TREE;
2998 }
2999
3000 /* Rewrite out of SSA the reduction described by the loop phi nodes
3001 IN, and the close phi nodes OUT. IN and OUT are structured by loop
3002 levels like this:
3003
3004 IN: stmt, loop_n, ..., loop_0
3005 OUT: stmt, close_n, ..., close_0
3006
3007 the first element is the reduction statement, and the next elements
3008 are the loop and close phi nodes of each of the outer loops. */
3009
3010 static void
3011 translate_scalar_reduction_to_array (scop_p scop,
3012 vec<gimple> in,
3013 vec<gimple> out)
3014 {
3015 gimple loop_phi;
3016 unsigned int i = out.length () - 1;
3017 tree red = close_phi_written_to_memory (out[i]);
3018
3019 FOR_EACH_VEC_ELT (in, i, loop_phi)
3020 {
3021 gimple close_phi = out[i];
3022
3023 if (i == 0)
3024 {
3025 gimple stmt = loop_phi;
3026 basic_block bb = split_reduction_stmt (scop, stmt);
3027 poly_bb_p pbb = pbb_from_bb (bb);
3028 PBB_IS_REDUCTION (pbb) = true;
3029 gcc_assert (close_phi == loop_phi);
3030
3031 if (!red)
3032 red = create_zero_dim_array
3033 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3034
3035 translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
3036 continue;
3037 }
3038
3039 if (i == in.length () - 1)
3040 {
3041 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3042 unshare_expr (red), close_phi);
3043 insert_out_of_ssa_copy_on_edge
3044 (scop, edge_initial_value_for_loop_phi (loop_phi),
3045 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3046 }
3047
3048 remove_phi (loop_phi);
3049 remove_phi (close_phi);
3050 }
3051 }
3052
3053 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3054 true when something has been changed. */
3055
3056 static bool
3057 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3058 gimple close_phi)
3059 {
3060 bool res;
3061 vec<gimple> in;
3062 in.create (10);
3063 vec<gimple> out;
3064 out.create (10);
3065
3066 detect_commutative_reduction (scop, close_phi, &in, &out);
3067 res = in.length () > 1;
3068 if (res)
3069 translate_scalar_reduction_to_array (scop, in, out);
3070
3071 in.release ();
3072 out.release ();
3073 return res;
3074 }
3075
3076 /* Rewrites all the commutative reductions from LOOP out of SSA.
3077 Returns true when something has been changed. */
3078
3079 static bool
3080 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3081 loop_p loop)
3082 {
3083 gimple_stmt_iterator gsi;
3084 edge exit = single_exit (loop);
3085 tree res;
3086 bool changed = false;
3087
3088 if (!exit)
3089 return false;
3090
3091 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3092 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3093 && !virtual_operand_p (res)
3094 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3095 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3096 (scop, gsi_stmt (gsi));
3097
3098 return changed;
3099 }
3100
3101 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3102
3103 static void
3104 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3105 {
3106 loop_iterator li;
3107 loop_p loop;
3108 bool changed = false;
3109 sese region = SCOP_REGION (scop);
3110
3111 FOR_EACH_LOOP (li, loop, 0)
3112 if (loop_in_sese_p (loop, region))
3113 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3114
3115 if (changed)
3116 {
3117 scev_reset_htab ();
3118 gsi_commit_edge_inserts ();
3119 update_ssa (TODO_update_ssa);
3120 #ifdef ENABLE_CHECKING
3121 verify_loop_closed_ssa (true);
3122 #endif
3123 }
3124 }
3125
3126 /* Can all ivs be represented by a signed integer?
3127 As CLooG might generate negative values in its expressions, signed loop ivs
3128 are required in the backend. */
3129
3130 static bool
3131 scop_ivs_can_be_represented (scop_p scop)
3132 {
3133 loop_iterator li;
3134 loop_p loop;
3135 gimple_stmt_iterator psi;
3136 bool result = true;
3137
3138 FOR_EACH_LOOP (li, loop, 0)
3139 {
3140 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3141 continue;
3142
3143 for (psi = gsi_start_phis (loop->header);
3144 !gsi_end_p (psi); gsi_next (&psi))
3145 {
3146 gimple phi = gsi_stmt (psi);
3147 tree res = PHI_RESULT (phi);
3148 tree type = TREE_TYPE (res);
3149
3150 if (TYPE_UNSIGNED (type)
3151 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3152 {
3153 result = false;
3154 break;
3155 }
3156 }
3157 if (!result)
3158 FOR_EACH_LOOP_BREAK (li);
3159 }
3160
3161 return result;
3162 }
3163
3164 /* Builds the polyhedral representation for a SESE region. */
3165
3166 void
3167 build_poly_scop (scop_p scop)
3168 {
3169 sese region = SCOP_REGION (scop);
3170 graphite_dim_t max_dim;
3171
3172 build_scop_bbs (scop);
3173
3174 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3175 Once CLooG is fixed, remove this guard. Anyways, it makes no
3176 sense to optimize a scop containing only PBBs that do not belong
3177 to any loops. */
3178 if (nb_pbbs_in_loops (scop) == 0)
3179 return;
3180
3181 if (!scop_ivs_can_be_represented (scop))
3182 return;
3183
3184 if (flag_associative_math)
3185 rewrite_commutative_reductions_out_of_ssa (scop);
3186
3187 build_sese_loop_nests (region);
3188 build_sese_conditions (region);
3189 find_scop_parameters (scop);
3190
3191 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3192 if (scop_nb_params (scop) > max_dim)
3193 return;
3194
3195 build_scop_iteration_domain (scop);
3196 build_scop_context (scop);
3197 add_conditions_to_constraints (scop);
3198
3199 /* Rewrite out of SSA only after having translated the
3200 representation to the polyhedral representation to avoid scev
3201 analysis failures. That means that these functions will insert
3202 new data references that they create in the right place. */
3203 rewrite_reductions_out_of_ssa (scop);
3204 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3205
3206 build_scop_drs (scop);
3207 scop_to_lst (scop);
3208 build_scop_scattering (scop);
3209
3210 /* This SCoP has been translated to the polyhedral
3211 representation. */
3212 POLY_SCOP_P (scop) = true;
3213 }
3214 #endif