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