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