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