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