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