move scop detection related stuff to graphite-scop-detection.c
[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_poly_bb_p
202 new_gimple_poly_bb (basic_block bb, vec<data_reference_p> drs)
203 {
204 gimple_poly_bb_p gbb;
205
206 gbb = XNEW (struct gimple_poly_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 data_reference_p dr;
221
222 FOR_EACH_VEC_ELT (datarefs, i, dr)
223 if (dr->aux)
224 {
225 base_alias_pair_p bap = (base_alias_pair_p)(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_poly_bb (gimple_poly_bb_p 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_poly_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 /* Return an ISL identifier for the polyhedral basic block PBB. */
278
279 static isl_id *
280 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
281 {
282 char name[50];
283 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
284 return isl_id_alloc (s->ctx, name, pbb);
285 }
286
287 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
288 We generate SCATTERING_DIMENSIONS scattering dimensions.
289
290 The scattering polyhedron consists of these dimensions: scattering,
291 loop_iterators, parameters.
292
293 Example:
294
295 | scattering_dimensions = 5
296 | nb_iterators = 1
297 | scop_nb_params = 2
298 |
299 | Schedule:
300 | i
301 | 4 5
302 |
303 | Scattering polyhedron:
304 |
305 | scattering: {s1, s2, s3, s4, s5}
306 | loop_iterators: {i}
307 | parameters: {p1, p2}
308 |
309 | s1 s2 s3 s4 s5 i p1 p2 1
310 | 1 0 0 0 0 0 0 0 -4 = 0
311 | 0 1 0 0 0 -1 0 0 0 = 0
312 | 0 0 1 0 0 0 0 0 -5 = 0 */
313
314 static void
315 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
316 poly_bb_p pbb)
317 {
318 int i;
319 isl_val *val;
320 isl_space *dc, *dm;
321
322 int scattering_dimensions = isl_set_dim (pbb->domain, isl_dim_set) * 2 + 1;
323
324 dc = isl_set_get_space (pbb->domain);
325 dm = isl_space_add_dims (isl_space_from_domain (dc),
326 isl_dim_out, scattering_dimensions);
327 pbb->schedule = isl_map_universe (dm);
328
329 for (i = 0; i < scattering_dimensions; i++)
330 {
331 /* Textual order inside this loop. */
332 if ((i % 2) == 0)
333 {
334 isl_constraint *c = isl_equality_alloc
335 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
336
337 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
338 gcc_assert (val && isl_val_is_int (val));
339
340 val = isl_val_neg (val);
341 c = isl_constraint_set_constant_val (c, val);
342 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
343 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
344 }
345
346 /* Iterations of this loop. */
347 else /* if ((i % 2) == 1) */
348 {
349 int loop = (i - 1) / 2;
350 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
351 isl_dim_out, i);
352 }
353 }
354
355 pbb->transformed = isl_map_copy (pbb->schedule);
356 }
357
358 /* Build for BB the static schedule.
359
360 The static schedule is a Dewey numbering of the abstract syntax
361 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
362
363 The following example informally defines the static schedule:
364
365 A
366 for (i: ...)
367 {
368 for (j: ...)
369 {
370 B
371 C
372 }
373
374 for (k: ...)
375 {
376 D
377 E
378 }
379 }
380 F
381
382 Static schedules for A to F:
383
384 DEPTH
385 0 1 2
386 A 0
387 B 1 0 0
388 C 1 0 1
389 D 1 1 0
390 E 1 1 1
391 F 2
392 */
393
394 static void
395 build_scop_scattering (scop_p scop)
396 {
397 int i;
398 poly_bb_p pbb;
399 gimple_poly_bb_p previous_gbb = NULL;
400 isl_space *dc = isl_set_get_space (scop->context);
401 isl_aff *static_sched;
402
403 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
404 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
405
406 /* We have to start schedules at 0 on the first component and
407 because we cannot compare_prefix_loops against a previous loop,
408 prefix will be equal to zero, and that index will be
409 incremented before copying. */
410 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
411
412 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
413 {
414 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
415 int prefix;
416
417 if (previous_gbb)
418 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
419 else
420 prefix = 0;
421
422 previous_gbb = gbb;
423
424 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
425 prefix, 1);
426 build_pbb_scattering_polyhedrons (static_sched, pbb);
427 }
428
429 isl_aff_free (static_sched);
430 }
431
432 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
433
434 /* Extract an affine expression from the chain of recurrence E. */
435
436 static isl_pw_aff *
437 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
438 {
439 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
440 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
441 isl_local_space *ls = isl_local_space_from_space (space);
442 unsigned pos = sese_loop_depth (SCOP_REGION (s), get_chrec_loop (e)) - 1;
443 isl_aff *loop = isl_aff_set_coefficient_si
444 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
445 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
446
447 /* Before multiplying, make sure that the result is affine. */
448 gcc_assert (isl_pw_aff_is_cst (rhs)
449 || isl_pw_aff_is_cst (l));
450
451 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
452 }
453
454 /* Extract an affine expression from the mult_expr E. */
455
456 static isl_pw_aff *
457 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
458 {
459 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
460 isl_space_copy (space));
461 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
462
463 if (!isl_pw_aff_is_cst (lhs)
464 && !isl_pw_aff_is_cst (rhs))
465 {
466 isl_pw_aff_free (lhs);
467 isl_pw_aff_free (rhs);
468 return NULL;
469 }
470
471 return isl_pw_aff_mul (lhs, rhs);
472 }
473
474 /* Return an ISL identifier from the name of the ssa_name E. */
475
476 static isl_id *
477 isl_id_for_ssa_name (scop_p s, tree e)
478 {
479 const char *name = get_name (e);
480 isl_id *id;
481
482 if (name)
483 id = isl_id_alloc (s->ctx, name, e);
484 else
485 {
486 char name1[50];
487 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
488 id = isl_id_alloc (s->ctx, name1, e);
489 }
490
491 return id;
492 }
493
494 /* Return an ISL identifier for the data reference DR. */
495
496 static isl_id *
497 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
498 {
499 /* Data references all get the same isl_id. They need to be comparable
500 and are distinguished through the first dimension, which contains the
501 alias set number. */
502 return isl_id_alloc (s->ctx, "", 0);
503 }
504
505 /* Extract an affine expression from the ssa_name E. */
506
507 static isl_pw_aff *
508 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
509 {
510 isl_aff *aff;
511 isl_set *dom;
512 isl_id *id;
513 int dimension;
514
515 id = isl_id_for_ssa_name (s, e);
516 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
517 isl_id_free (id);
518 dom = isl_set_universe (isl_space_copy (space));
519 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
520 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
521 return isl_pw_aff_alloc (dom, aff);
522 }
523
524 /* Extract an affine expression from the gmp constant G. */
525
526 static isl_pw_aff *
527 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
528 {
529 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
530 isl_aff *aff = isl_aff_zero_on_domain (ls);
531 isl_set *dom = isl_set_universe (space);
532 isl_val *v;
533 isl_ctx *ct;
534
535 ct = isl_aff_get_ctx (aff);
536 v = isl_val_int_from_gmp (ct, g);
537 aff = isl_aff_add_constant_val (aff, v);
538
539 return isl_pw_aff_alloc (dom, aff);
540 }
541
542 /* Extract an affine expression from the integer_cst E. */
543
544 static isl_pw_aff *
545 extract_affine_int (tree e, __isl_take isl_space *space)
546 {
547 isl_pw_aff *res;
548 mpz_t g;
549
550 mpz_init (g);
551 tree_int_to_gmp (e, g);
552 res = extract_affine_gmp (g, space);
553 mpz_clear (g);
554
555 return res;
556 }
557
558 /* Compute pwaff mod 2^width. */
559
560 static isl_pw_aff *
561 wrap (isl_pw_aff *pwaff, unsigned width)
562 {
563 isl_val *mod;
564
565 mod = isl_val_int_from_ui (isl_pw_aff_get_ctx (pwaff), width);
566 mod = isl_val_2exp (mod);
567 pwaff = isl_pw_aff_mod_val (pwaff, mod);
568
569 return pwaff;
570 }
571
572 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
573 Otherwise returns -1. */
574
575 static inline int
576 parameter_index_in_region_1 (tree name, sese region)
577 {
578 int i;
579 tree p;
580
581 gcc_assert (TREE_CODE (name) == SSA_NAME);
582
583 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
584 if (p == name)
585 return i;
586
587 return -1;
588 }
589
590 /* When the parameter NAME is in REGION, returns its index in
591 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
592 and returns the index of NAME. */
593
594 static int
595 parameter_index_in_region (tree name, sese region)
596 {
597 int i;
598
599 gcc_assert (TREE_CODE (name) == SSA_NAME);
600
601 /* Cannot constrain on anything else than INTEGER_TYPE parameters. */
602 if (TREE_CODE (TREE_TYPE (name)) != INTEGER_TYPE)
603 return -1;
604
605 if (!invariant_in_sese_p_rec (name, region))
606 return -1;
607
608 i = parameter_index_in_region_1 (name, region);
609 if (i != -1)
610 return i;
611
612 gcc_assert (SESE_ADD_PARAMS (region));
613
614 i = SESE_PARAMS (region).length ();
615 SESE_PARAMS (region).safe_push (name);
616 return i;
617 }
618
619 /* Extract an affine expression from the tree E in the scop S. */
620
621 static isl_pw_aff *
622 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
623 {
624 isl_pw_aff *lhs, *rhs, *res;
625 tree type;
626
627 if (e == chrec_dont_know) {
628 isl_space_free (space);
629 return NULL;
630 }
631
632 switch (TREE_CODE (e))
633 {
634 case POLYNOMIAL_CHREC:
635 res = extract_affine_chrec (s, e, space);
636 break;
637
638 case MULT_EXPR:
639 res = extract_affine_mul (s, e, space);
640 break;
641
642 case PLUS_EXPR:
643 case POINTER_PLUS_EXPR:
644 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
645 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
646 res = isl_pw_aff_add (lhs, rhs);
647 break;
648
649 case MINUS_EXPR:
650 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
651 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
652 res = isl_pw_aff_sub (lhs, rhs);
653 break;
654
655 case NEGATE_EXPR:
656 case BIT_NOT_EXPR:
657 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
658 rhs = extract_affine (s, integer_minus_one_node, space);
659 res = isl_pw_aff_mul (lhs, rhs);
660 break;
661
662 case SSA_NAME:
663 gcc_assert (-1 != parameter_index_in_region_1 (e, s->region)
664 || !invariant_in_sese_p_rec (e, s->region));
665 res = extract_affine_name (s, e, space);
666 break;
667
668 case INTEGER_CST:
669 res = extract_affine_int (e, space);
670 /* No need to wrap a single integer. */
671 return res;
672
673 CASE_CONVERT:
674 case NON_LVALUE_EXPR:
675 res = extract_affine (s, TREE_OPERAND (e, 0), space);
676 break;
677
678 default:
679 gcc_unreachable ();
680 break;
681 }
682
683 type = TREE_TYPE (e);
684 if (TYPE_UNSIGNED (type))
685 res = wrap (res, TYPE_PRECISION (type));
686
687 return res;
688 }
689
690 /* In the context of sese S, scan the expression E and translate it to
691 a linear expression C. When parsing a symbolic multiplication, K
692 represents the constant multiplier of an expression containing
693 parameters. */
694
695 static void
696 scan_tree_for_params (sese s, tree e)
697 {
698 if (e == chrec_dont_know)
699 return;
700
701 switch (TREE_CODE (e))
702 {
703 case POLYNOMIAL_CHREC:
704 scan_tree_for_params (s, CHREC_LEFT (e));
705 break;
706
707 case MULT_EXPR:
708 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
709 scan_tree_for_params (s, TREE_OPERAND (e, 0));
710 else
711 scan_tree_for_params (s, TREE_OPERAND (e, 1));
712 break;
713
714 case PLUS_EXPR:
715 case POINTER_PLUS_EXPR:
716 case MINUS_EXPR:
717 scan_tree_for_params (s, TREE_OPERAND (e, 0));
718 scan_tree_for_params (s, TREE_OPERAND (e, 1));
719 break;
720
721 case NEGATE_EXPR:
722 case BIT_NOT_EXPR:
723 CASE_CONVERT:
724 case NON_LVALUE_EXPR:
725 scan_tree_for_params (s, TREE_OPERAND (e, 0));
726 break;
727
728 case SSA_NAME:
729 parameter_index_in_region (e, s);
730 break;
731
732 case INTEGER_CST:
733 case ADDR_EXPR:
734 case REAL_CST:
735 case COMPLEX_CST:
736 case VECTOR_CST:
737 break;
738
739 default:
740 gcc_unreachable ();
741 break;
742 }
743 }
744
745 /* Find parameters with respect to REGION in BB. We are looking in memory
746 access functions, conditions and loop bounds. */
747
748 static void
749 find_params_in_bb (sese region, gimple_poly_bb_p gbb)
750 {
751 int i;
752 unsigned j;
753 data_reference_p dr;
754 gimple *stmt;
755 loop_p loop = GBB_BB (gbb)->loop_father;
756
757 /* Find parameters in the access functions of data references. */
758 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
759 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
760 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
761
762 /* Find parameters in conditional statements. */
763 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
764 {
765 tree lhs = scalar_evolution_in_region (region, loop,
766 gimple_cond_lhs (stmt));
767 tree rhs = scalar_evolution_in_region (region, loop,
768 gimple_cond_rhs (stmt));
769
770 scan_tree_for_params (region, lhs);
771 scan_tree_for_params (region, rhs);
772 }
773 }
774
775 /* Record the parameters used in the SCOP. A variable is a parameter
776 in a scop if it does not vary during the execution of that scop. */
777
778 static void
779 find_scop_parameters (scop_p scop)
780 {
781 poly_bb_p pbb;
782 unsigned i;
783 sese region = SCOP_REGION (scop);
784 struct loop *loop;
785 int nbp;
786
787 /* Find the parameters used in the loop bounds. */
788 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
789 {
790 tree nb_iters = number_of_latch_executions (loop);
791
792 if (!chrec_contains_symbols (nb_iters))
793 continue;
794
795 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
796 scan_tree_for_params (region, nb_iters);
797 }
798
799 /* Find the parameters used in data accesses. */
800 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
801 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
802
803 nbp = sese_nb_params (region);
804 scop_set_nb_params (scop, nbp);
805 SESE_ADD_PARAMS (region) = false;
806 }
807
808 /* Assign dimension for each parameter in SCOP. */
809
810 static void
811 set_scop_parameter_dim (scop_p scop)
812 {
813 sese region = SCOP_REGION (scop);
814 unsigned nbp = sese_nb_params (region);
815 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
816
817 unsigned i;
818 tree e;
819 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
820 space = isl_space_set_dim_id (space, isl_dim_param, i,
821 isl_id_for_ssa_name (scop, e));
822
823 scop->context = isl_set_universe (space);
824 }
825
826 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
827 the constraints for the surrounding loops. */
828
829 static void
830 build_loop_iteration_domains (scop_p scop, struct loop *loop,
831 int nb,
832 isl_set *outer, isl_set **doms)
833 {
834 tree nb_iters = number_of_latch_executions (loop);
835 sese region = SCOP_REGION (scop);
836
837 isl_set *inner = isl_set_copy (outer);
838 isl_space *space;
839 isl_constraint *c;
840 int pos = isl_set_dim (outer, isl_dim_set);
841 isl_val *v;
842 mpz_t g;
843
844 mpz_init (g);
845
846 inner = isl_set_add_dims (inner, isl_dim_set, 1);
847 space = isl_set_get_space (inner);
848
849 /* 0 <= loop_i */
850 c = isl_inequality_alloc
851 (isl_local_space_from_space (isl_space_copy (space)));
852 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
853 inner = isl_set_add_constraint (inner, c);
854
855 /* loop_i <= cst_nb_iters */
856 if (TREE_CODE (nb_iters) == INTEGER_CST)
857 {
858 c = isl_inequality_alloc
859 (isl_local_space_from_space (isl_space_copy (space)));
860 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
861 tree_int_to_gmp (nb_iters, g);
862 v = isl_val_int_from_gmp (scop->ctx, g);
863 c = isl_constraint_set_constant_val (c, v);
864 inner = isl_set_add_constraint (inner, c);
865 }
866
867 /* loop_i <= expr_nb_iters */
868 else if (!chrec_contains_undetermined (nb_iters))
869 {
870 widest_int nit;
871 isl_pw_aff *aff;
872 isl_set *valid;
873 isl_local_space *ls;
874 isl_aff *al;
875 isl_set *le;
876
877 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
878
879 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
880 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
881 valid = isl_set_project_out (valid, isl_dim_set, 0,
882 isl_set_dim (valid, isl_dim_set));
883 scop->context = isl_set_intersect (scop->context, valid);
884
885 ls = isl_local_space_from_space (isl_space_copy (space));
886 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
887 isl_dim_in, pos, 1);
888 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
889 isl_pw_aff_copy (aff));
890 inner = isl_set_intersect (inner, le);
891
892 if (max_stmt_executions (loop, &nit))
893 {
894 /* Insert in the context the constraints from the
895 estimation of the number of iterations NIT and the
896 symbolic number of iterations (involving parameter
897 names) NB_ITERS. First, build the affine expression
898 "NIT - NB_ITERS" and then say that it is positive,
899 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
900 isl_pw_aff *approx;
901 mpz_t g;
902 isl_set *x;
903 isl_constraint *c;
904
905 mpz_init (g);
906 wi::to_mpz (nit, g, SIGNED);
907 mpz_sub_ui (g, g, 1);
908 approx = extract_affine_gmp (g, isl_set_get_space (inner));
909 x = isl_pw_aff_ge_set (approx, aff);
910 x = isl_set_project_out (x, isl_dim_set, 0,
911 isl_set_dim (x, isl_dim_set));
912 scop->context = isl_set_intersect (scop->context, x);
913
914 c = isl_inequality_alloc
915 (isl_local_space_from_space (isl_space_copy (space)));
916 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
917 v = isl_val_int_from_gmp (scop->ctx, g);
918 mpz_clear (g);
919 c = isl_constraint_set_constant_val (c, v);
920 inner = isl_set_add_constraint (inner, c);
921 }
922 else
923 isl_pw_aff_free (aff);
924 }
925 else
926 gcc_unreachable ();
927
928 if (loop->inner && loop_in_sese_p (loop->inner, region))
929 build_loop_iteration_domains (scop, loop->inner, nb + 1,
930 isl_set_copy (inner), doms);
931
932 if (nb != 0
933 && loop->next
934 && loop_in_sese_p (loop->next, region))
935 build_loop_iteration_domains (scop, loop->next, nb,
936 isl_set_copy (outer), doms);
937
938 doms[loop->num] = inner;
939
940 isl_set_free (outer);
941 isl_space_free (space);
942 mpz_clear (g);
943 }
944
945 /* Returns a linear expression for tree T evaluated in PBB. */
946
947 static isl_pw_aff *
948 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
949 {
950 scop_p scop = PBB_SCOP (pbb);
951
952 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
953 gcc_assert (!automatically_generated_chrec_p (t));
954
955 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
956 }
957
958 /* Add conditional statement STMT to pbb. CODE is used as the comparison
959 operator. This allows us to invert the condition or to handle
960 inequalities. */
961
962 static void
963 add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
964 {
965 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
966 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
967 isl_set *cond;
968
969 switch (code)
970 {
971 case LT_EXPR:
972 cond = isl_pw_aff_lt_set (lhs, rhs);
973 break;
974
975 case GT_EXPR:
976 cond = isl_pw_aff_gt_set (lhs, rhs);
977 break;
978
979 case LE_EXPR:
980 cond = isl_pw_aff_le_set (lhs, rhs);
981 break;
982
983 case GE_EXPR:
984 cond = isl_pw_aff_ge_set (lhs, rhs);
985 break;
986
987 case EQ_EXPR:
988 cond = isl_pw_aff_eq_set (lhs, rhs);
989 break;
990
991 case NE_EXPR:
992 cond = isl_pw_aff_ne_set (lhs, rhs);
993 break;
994
995 default:
996 isl_pw_aff_free (lhs);
997 isl_pw_aff_free (rhs);
998 return;
999 }
1000
1001 cond = isl_set_coalesce (cond);
1002 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1003 pbb->domain = isl_set_intersect (pbb->domain, cond);
1004 }
1005
1006 /* Add conditions to the domain of PBB. */
1007
1008 static void
1009 add_conditions_to_domain (poly_bb_p pbb)
1010 {
1011 unsigned int i;
1012 gimple *stmt;
1013 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
1014
1015 if (GBB_CONDITIONS (gbb).is_empty ())
1016 return;
1017
1018 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1019 switch (gimple_code (stmt))
1020 {
1021 case GIMPLE_COND:
1022 {
1023 /* Don't constrain on anything else than INTEGER_TYPE. */
1024 if (TREE_CODE (TREE_TYPE (gimple_cond_lhs (stmt))) != INTEGER_TYPE)
1025 break;
1026
1027 gcond *cond_stmt = as_a <gcond *> (stmt);
1028 enum tree_code code = gimple_cond_code (cond_stmt);
1029
1030 /* The conditions for ELSE-branches are inverted. */
1031 if (!GBB_CONDITION_CASES (gbb)[i])
1032 code = invert_tree_comparison (code, false);
1033
1034 add_condition_to_pbb (pbb, cond_stmt, code);
1035 break;
1036 }
1037
1038 case GIMPLE_SWITCH:
1039 /* Switch statements are not supported right now - fall through. */
1040
1041 default:
1042 gcc_unreachable ();
1043 break;
1044 }
1045 }
1046
1047 /* Traverses all the GBBs of the SCOP and add their constraints to the
1048 iteration domains. */
1049
1050 static void
1051 add_conditions_to_constraints (scop_p scop)
1052 {
1053 int i;
1054 poly_bb_p pbb;
1055
1056 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1057 add_conditions_to_domain (pbb);
1058 }
1059
1060 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1061 edge between BB and its predecessor is not a loop exit edge, and
1062 the last statement of the single predecessor is a COND_EXPR. */
1063
1064 static gcond *
1065 single_pred_cond_non_loop_exit (basic_block bb)
1066 {
1067 if (single_pred_p (bb))
1068 {
1069 edge e = single_pred_edge (bb);
1070 basic_block pred = e->src;
1071 gimple *stmt;
1072
1073 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1074 return NULL;
1075
1076 stmt = last_stmt (pred);
1077
1078 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1079 return as_a <gcond *> (stmt);
1080 }
1081
1082 return NULL;
1083 }
1084
1085 class sese_dom_walker : public dom_walker
1086 {
1087 public:
1088 sese_dom_walker (cdi_direction, sese);
1089
1090 virtual void before_dom_children (basic_block);
1091 virtual void after_dom_children (basic_block);
1092
1093 private:
1094 auto_vec<gimple *, 3> m_conditions, m_cases;
1095 sese m_region;
1096 };
1097
1098 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1099 : dom_walker (direction), m_region (region)
1100 {
1101 }
1102
1103 /* Call-back for dom_walk executed before visiting the dominated
1104 blocks. */
1105
1106 void
1107 sese_dom_walker::before_dom_children (basic_block bb)
1108 {
1109 gimple_poly_bb_p gbb;
1110 gcond *stmt;
1111
1112 if (!bb_in_sese_p (bb, m_region))
1113 return;
1114
1115 stmt = single_pred_cond_non_loop_exit (bb);
1116
1117 if (stmt)
1118 {
1119 edge e = single_pred_edge (bb);
1120
1121 m_conditions.safe_push (stmt);
1122
1123 if (e->flags & EDGE_TRUE_VALUE)
1124 m_cases.safe_push (stmt);
1125 else
1126 m_cases.safe_push (NULL);
1127 }
1128
1129 gbb = gbb_from_bb (bb);
1130
1131 if (gbb)
1132 {
1133 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1134 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1135 }
1136 }
1137
1138 /* Call-back for dom_walk executed after visiting the dominated
1139 blocks. */
1140
1141 void
1142 sese_dom_walker::after_dom_children (basic_block bb)
1143 {
1144 if (!bb_in_sese_p (bb, m_region))
1145 return;
1146
1147 if (single_pred_cond_non_loop_exit (bb))
1148 {
1149 m_conditions.pop ();
1150 m_cases.pop ();
1151 }
1152 }
1153
1154 /* Add constraints on the possible values of parameter P from the type
1155 of P. */
1156
1157 static void
1158 add_param_constraints (scop_p scop, graphite_dim_t p)
1159 {
1160 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1161 tree type = TREE_TYPE (parameter);
1162 tree lb = NULL_TREE;
1163 tree ub = NULL_TREE;
1164
1165 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1166 lb = lower_bound_in_type (type, type);
1167 else
1168 lb = TYPE_MIN_VALUE (type);
1169
1170 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1171 ub = upper_bound_in_type (type, type);
1172 else
1173 ub = TYPE_MAX_VALUE (type);
1174
1175 if (lb)
1176 {
1177 isl_space *space = isl_set_get_space (scop->context);
1178 isl_constraint *c;
1179 mpz_t g;
1180 isl_val *v;
1181
1182 c = isl_inequality_alloc (isl_local_space_from_space (space));
1183 mpz_init (g);
1184 tree_int_to_gmp (lb, g);
1185 v = isl_val_int_from_gmp (scop->ctx, g);
1186 v = isl_val_neg (v);
1187 mpz_clear (g);
1188 c = isl_constraint_set_constant_val (c, v);
1189 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1190
1191 scop->context = isl_set_add_constraint (scop->context, c);
1192 }
1193
1194 if (ub)
1195 {
1196 isl_space *space = isl_set_get_space (scop->context);
1197 isl_constraint *c;
1198 mpz_t g;
1199 isl_val *v;
1200
1201 c = isl_inequality_alloc (isl_local_space_from_space (space));
1202
1203 mpz_init (g);
1204 tree_int_to_gmp (ub, g);
1205 v = isl_val_int_from_gmp (scop->ctx, g);
1206 mpz_clear (g);
1207 c = isl_constraint_set_constant_val (c, v);
1208 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1209
1210 scop->context = isl_set_add_constraint (scop->context, c);
1211 }
1212 }
1213
1214 /* Build the context of the SCOP. The context usually contains extra
1215 constraints that are added to the iteration domains that constrain
1216 some parameters. */
1217
1218 static void
1219 build_scop_context (scop_p scop)
1220 {
1221 graphite_dim_t p, n = scop_nb_params (scop);
1222
1223 for (p = 0; p < n; p++)
1224 add_param_constraints (scop, p);
1225 }
1226
1227 /* Build the iteration domains: the loops belonging to the current
1228 SCOP, and that vary for the execution of the current basic block.
1229 Returns false if there is no loop in SCOP. */
1230
1231 static void
1232 build_scop_iteration_domain (scop_p scop)
1233 {
1234 struct loop *loop;
1235 sese region = SCOP_REGION (scop);
1236 int i;
1237 poly_bb_p pbb;
1238 int nb_loops = number_of_loops (cfun);
1239 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1240
1241 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1242 if (!loop_in_sese_p (loop_outer (loop), region))
1243 build_loop_iteration_domains (scop, loop, 0,
1244 isl_set_copy (scop->context), doms);
1245
1246 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1247 {
1248 loop = pbb_loop (pbb);
1249
1250 if (doms[loop->num])
1251 pbb->domain = isl_set_copy (doms[loop->num]);
1252 else
1253 pbb->domain = isl_set_copy (scop->context);
1254
1255 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1256 isl_id_for_pbb (scop, pbb));
1257 }
1258
1259 for (i = 0; i < nb_loops; i++)
1260 if (doms[i])
1261 isl_set_free (doms[i]);
1262
1263 free (doms);
1264 }
1265
1266 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1267 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1268 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1269 domain. */
1270
1271 static isl_map *
1272 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1273 {
1274 isl_constraint *c;
1275 int alias_set_num = 0;
1276 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1277
1278 if (bap && bap->alias_set)
1279 alias_set_num = *(bap->alias_set);
1280
1281 c = isl_equality_alloc
1282 (isl_local_space_from_space (isl_map_get_space (acc)));
1283 c = isl_constraint_set_constant_si (c, -alias_set_num);
1284 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1285
1286 return isl_map_add_constraint (acc, c);
1287 }
1288
1289 /* Assign the affine expression INDEX to the output dimension POS of
1290 MAP and return the result. */
1291
1292 static isl_map *
1293 set_index (isl_map *map, int pos, isl_pw_aff *index)
1294 {
1295 isl_map *index_map;
1296 int len = isl_map_dim (map, isl_dim_out);
1297 isl_id *id;
1298
1299 index_map = isl_map_from_pw_aff (index);
1300 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1301 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1302
1303 id = isl_map_get_tuple_id (map, isl_dim_out);
1304 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1305 id = isl_map_get_tuple_id (map, isl_dim_in);
1306 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1307
1308 return isl_map_intersect (map, index_map);
1309 }
1310
1311 /* Add to ACCESSES polyhedron equalities defining the access functions
1312 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1313 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1314 PBB is the poly_bb_p that contains the data reference DR. */
1315
1316 static isl_map *
1317 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1318 {
1319 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1320 scop_p scop = PBB_SCOP (pbb);
1321
1322 for (i = 0; i < nb_subscripts; i++)
1323 {
1324 isl_pw_aff *aff;
1325 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1326
1327 aff = extract_affine (scop, afn,
1328 isl_space_domain (isl_map_get_space (acc)));
1329 acc = set_index (acc, i + 1, aff);
1330 }
1331
1332 return acc;
1333 }
1334
1335 /* Add constrains representing the size of the accessed data to the
1336 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1337 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1338 domain. */
1339
1340 static isl_set *
1341 pdr_add_data_dimensions (isl_set *subscript_sizes, scop_p scop,
1342 data_reference_p dr)
1343 {
1344 tree ref = DR_REF (dr);
1345
1346 int nb_subscripts = DR_NUM_DIMENSIONS (dr);
1347 for (int i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1348 {
1349 if (TREE_CODE (ref) != ARRAY_REF)
1350 return subscript_sizes;
1351
1352 tree low = array_ref_low_bound (ref);
1353 tree high = array_ref_up_bound (ref);
1354
1355 /* XXX The PPL code dealt separately with
1356 subscript - low >= 0 and high - subscript >= 0 in case one of
1357 the two bounds isn't known. Do the same here? */
1358
1359 if (tree_fits_shwi_p (low)
1360 && high
1361 && tree_fits_shwi_p (high)
1362 /* 1-element arrays at end of structures may extend over
1363 their declared size. */
1364 && !(array_at_struct_end_p (ref)
1365 && operand_equal_p (low, high, 0)))
1366 {
1367 isl_id *id;
1368 isl_aff *aff;
1369 isl_set *univ, *lbs, *ubs;
1370 isl_pw_aff *index;
1371 isl_set *valid;
1372 isl_space *space = isl_set_get_space (subscript_sizes);
1373 isl_pw_aff *lb = extract_affine_int (low, isl_space_copy (space));
1374 isl_pw_aff *ub = extract_affine_int (high, isl_space_copy (space));
1375
1376 /* high >= 0 */
1377 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1378 valid = isl_set_project_out (valid, isl_dim_set, 0,
1379 isl_set_dim (valid, isl_dim_set));
1380 scop->context = isl_set_intersect (scop->context, valid);
1381
1382 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1383 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1384 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1385 index = isl_pw_aff_alloc (univ, aff);
1386
1387 id = isl_set_get_tuple_id (subscript_sizes);
1388 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1389 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1390
1391 /* low <= sub_i <= high */
1392 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1393 ubs = isl_pw_aff_le_set (index, ub);
1394 subscript_sizes = isl_set_intersect (subscript_sizes, lbs);
1395 subscript_sizes = isl_set_intersect (subscript_sizes, ubs);
1396 }
1397 }
1398
1399 return subscript_sizes;
1400 }
1401
1402 /* Build data accesses for DR in PBB. */
1403
1404 static void
1405 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1406 {
1407 int dr_base_object_set;
1408 isl_map *acc;
1409 isl_set *subscript_sizes;
1410 scop_p scop = PBB_SCOP (pbb);
1411
1412 {
1413 isl_space *dc = isl_set_get_space (pbb->domain);
1414 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1415 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1416 isl_dim_out, nb_out);
1417
1418 acc = isl_map_universe (space);
1419 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1420 }
1421
1422 acc = pdr_add_alias_set (acc, dr);
1423 acc = pdr_add_memory_accesses (acc, dr, pbb);
1424
1425 {
1426 isl_id *id = isl_id_for_dr (scop, dr);
1427 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1428 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1429 int alias_set_num = 0;
1430 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1431
1432 if (bap && bap->alias_set)
1433 alias_set_num = *(bap->alias_set);
1434
1435 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1436 subscript_sizes = isl_set_nat_universe (space);
1437 subscript_sizes = isl_set_fix_si (subscript_sizes, isl_dim_set, 0,
1438 alias_set_num);
1439 subscript_sizes = pdr_add_data_dimensions (subscript_sizes, scop, dr);
1440 }
1441
1442 gcc_assert (dr->aux);
1443 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1444
1445 new_poly_dr (pbb, dr_base_object_set,
1446 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1447 dr, DR_NUM_DIMENSIONS (dr), acc, subscript_sizes);
1448 }
1449
1450 /* Write to FILE the alias graph of data references in DIMACS format. */
1451
1452 static inline bool
1453 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1454 vec<data_reference_p> drs)
1455 {
1456 int num_vertex = drs.length ();
1457 int edge_num = 0;
1458 data_reference_p dr1, dr2;
1459 int i, j;
1460
1461 if (num_vertex == 0)
1462 return true;
1463
1464 FOR_EACH_VEC_ELT (drs, i, dr1)
1465 for (j = i + 1; drs.iterate (j, &dr2); j++)
1466 if (dr_may_alias_p (dr1, dr2, true))
1467 edge_num++;
1468
1469 fprintf (file, "$\n");
1470
1471 if (comment)
1472 fprintf (file, "c %s\n", comment);
1473
1474 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1475
1476 FOR_EACH_VEC_ELT (drs, i, dr1)
1477 for (j = i + 1; drs.iterate (j, &dr2); j++)
1478 if (dr_may_alias_p (dr1, dr2, true))
1479 fprintf (file, "e %d %d\n", i + 1, j + 1);
1480
1481 return true;
1482 }
1483
1484 /* Write to FILE the alias graph of data references in DOT format. */
1485
1486 static inline bool
1487 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1488 vec<data_reference_p> drs)
1489 {
1490 int num_vertex = drs.length ();
1491 data_reference_p dr1, dr2;
1492 int i, j;
1493
1494 if (num_vertex == 0)
1495 return true;
1496
1497 fprintf (file, "$\n");
1498
1499 if (comment)
1500 fprintf (file, "c %s\n", comment);
1501
1502 /* First print all the vertices. */
1503 FOR_EACH_VEC_ELT (drs, i, dr1)
1504 fprintf (file, "n%d;\n", i);
1505
1506 FOR_EACH_VEC_ELT (drs, i, dr1)
1507 for (j = i + 1; drs.iterate (j, &dr2); j++)
1508 if (dr_may_alias_p (dr1, dr2, true))
1509 fprintf (file, "n%d n%d\n", i, j);
1510
1511 return true;
1512 }
1513
1514 /* Write to FILE the alias graph of data references in ECC format. */
1515
1516 static inline bool
1517 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1518 vec<data_reference_p> drs)
1519 {
1520 int num_vertex = drs.length ();
1521 data_reference_p dr1, dr2;
1522 int i, j;
1523
1524 if (num_vertex == 0)
1525 return true;
1526
1527 fprintf (file, "$\n");
1528
1529 if (comment)
1530 fprintf (file, "c %s\n", comment);
1531
1532 FOR_EACH_VEC_ELT (drs, i, dr1)
1533 for (j = i + 1; drs.iterate (j, &dr2); j++)
1534 if (dr_may_alias_p (dr1, dr2, true))
1535 fprintf (file, "%d %d\n", i, j);
1536
1537 return true;
1538 }
1539
1540 /* Check if DR1 and DR2 are in the same object set. */
1541
1542 static bool
1543 dr_same_base_object_p (const struct data_reference *dr1,
1544 const struct data_reference *dr2)
1545 {
1546 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1547 }
1548
1549 /* Uses DFS component number as representative of alias-sets. Also tests for
1550 optimality by verifying if every connected component is a clique. Returns
1551 true (1) if the above test is true, and false (0) otherwise. */
1552
1553 static int
1554 build_alias_set_optimal_p (vec<data_reference_p> drs)
1555 {
1556 int num_vertices = drs.length ();
1557 struct graph *g = new_graph (num_vertices);
1558 data_reference_p dr1, dr2;
1559 int i, j;
1560 int num_connected_components;
1561 int v_indx1, v_indx2, num_vertices_in_component;
1562 int *all_vertices;
1563 int *vertices;
1564 struct graph_edge *e;
1565 int this_component_is_clique;
1566 int all_components_are_cliques = 1;
1567
1568 FOR_EACH_VEC_ELT (drs, i, dr1)
1569 for (j = i+1; drs.iterate (j, &dr2); j++)
1570 if (dr_may_alias_p (dr1, dr2, true))
1571 {
1572 add_edge (g, i, j);
1573 add_edge (g, j, i);
1574 }
1575
1576 all_vertices = XNEWVEC (int, num_vertices);
1577 vertices = XNEWVEC (int, num_vertices);
1578 for (i = 0; i < num_vertices; i++)
1579 all_vertices[i] = i;
1580
1581 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1582 NULL, true, NULL);
1583 for (i = 0; i < g->n_vertices; i++)
1584 {
1585 data_reference_p dr = drs[i];
1586 base_alias_pair *bap;
1587
1588 gcc_assert (dr->aux);
1589 bap = (base_alias_pair *)(dr->aux);
1590
1591 bap->alias_set = XNEW (int);
1592 *(bap->alias_set) = g->vertices[i].component + 1;
1593 }
1594
1595 /* Verify if the DFS numbering results in optimal solution. */
1596 for (i = 0; i < num_connected_components; i++)
1597 {
1598 num_vertices_in_component = 0;
1599 /* Get all vertices whose DFS component number is the same as i. */
1600 for (j = 0; j < num_vertices; j++)
1601 if (g->vertices[j].component == i)
1602 vertices[num_vertices_in_component++] = j;
1603
1604 /* Now test if the vertices in 'vertices' form a clique, by testing
1605 for edges among each pair. */
1606 this_component_is_clique = 1;
1607 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1608 {
1609 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1610 {
1611 /* Check if the two vertices are connected by iterating
1612 through all the edges which have one of these are source. */
1613 e = g->vertices[vertices[v_indx2]].pred;
1614 while (e)
1615 {
1616 if (e->src == vertices[v_indx1])
1617 break;
1618 e = e->pred_next;
1619 }
1620 if (!e)
1621 {
1622 this_component_is_clique = 0;
1623 break;
1624 }
1625 }
1626 if (!this_component_is_clique)
1627 all_components_are_cliques = 0;
1628 }
1629 }
1630
1631 free (all_vertices);
1632 free (vertices);
1633 free_graph (g);
1634 return all_components_are_cliques;
1635 }
1636
1637 /* Group each data reference in DRS with its base object set num. */
1638
1639 static void
1640 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1641 {
1642 int num_vertex = drs.length ();
1643 struct graph *g = new_graph (num_vertex);
1644 data_reference_p dr1, dr2;
1645 int i, j;
1646 int *queue;
1647
1648 FOR_EACH_VEC_ELT (drs, i, dr1)
1649 for (j = i + 1; drs.iterate (j, &dr2); j++)
1650 if (dr_same_base_object_p (dr1, dr2))
1651 {
1652 add_edge (g, i, j);
1653 add_edge (g, j, i);
1654 }
1655
1656 queue = XNEWVEC (int, num_vertex);
1657 for (i = 0; i < num_vertex; i++)
1658 queue[i] = i;
1659
1660 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1661
1662 for (i = 0; i < g->n_vertices; i++)
1663 {
1664 data_reference_p dr = drs[i];
1665 base_alias_pair *bap;
1666
1667 gcc_assert (dr->aux);
1668 bap = (base_alias_pair *)(dr->aux);
1669
1670 bap->base_obj_set = g->vertices[i].component + 1;
1671 }
1672
1673 free (queue);
1674 free_graph (g);
1675 }
1676
1677 /* Build the data references for PBB. */
1678
1679 static void
1680 build_pbb_drs (poly_bb_p pbb)
1681 {
1682 int j;
1683 data_reference_p dr;
1684 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1685
1686 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1687 build_poly_dr (dr, pbb);
1688 }
1689
1690 /* Dump to file the alias graphs for the data references in DRS. */
1691
1692 static void
1693 dump_alias_graphs (vec<data_reference_p> drs)
1694 {
1695 char comment[100];
1696 FILE *file_dimacs, *file_ecc, *file_dot;
1697
1698 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1699 if (file_dimacs)
1700 {
1701 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1702 current_function_name ());
1703 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1704 fclose (file_dimacs);
1705 }
1706
1707 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1708 if (file_ecc)
1709 {
1710 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1711 current_function_name ());
1712 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1713 fclose (file_ecc);
1714 }
1715
1716 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1717 if (file_dot)
1718 {
1719 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1720 current_function_name ());
1721 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1722 fclose (file_dot);
1723 }
1724 }
1725
1726 /* Build data references in SCOP. */
1727
1728 static void
1729 build_scop_drs (scop_p scop)
1730 {
1731 int i, j;
1732 poly_bb_p pbb;
1733 data_reference_p dr;
1734 auto_vec<data_reference_p, 3> drs;
1735
1736 /* Remove all the PBBs that do not have data references: these basic
1737 blocks are not handled in the polyhedral representation. */
1738 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1739 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1740 {
1741 free_gimple_poly_bb (PBB_BLACK_BOX (pbb));
1742 free_poly_bb (pbb);
1743 SCOP_BBS (scop).ordered_remove (i);
1744 i--;
1745 }
1746
1747 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1748 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1749 drs.safe_push (dr);
1750
1751 FOR_EACH_VEC_ELT (drs, i, dr)
1752 dr->aux = XNEW (base_alias_pair);
1753
1754 if (!build_alias_set_optimal_p (drs))
1755 {
1756 /* TODO: Add support when building alias set is not optimal. */
1757 ;
1758 }
1759
1760 build_base_obj_set_for_drs (drs);
1761
1762 /* When debugging, enable the following code. This cannot be used
1763 in production compilers. */
1764 if (0)
1765 dump_alias_graphs (drs);
1766
1767 drs.release ();
1768
1769 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1770 build_pbb_drs (pbb);
1771 }
1772
1773 /* Analyze all the data references of STMTS and add them to the
1774 GBB_DATA_REFS vector of BB. */
1775
1776 static void
1777 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple *> stmts)
1778 {
1779 loop_p nest;
1780 gimple_poly_bb_p gbb;
1781 gimple *stmt;
1782 int i;
1783 sese region = SCOP_REGION (scop);
1784
1785 if (!bb_in_sese_p (bb, region))
1786 return;
1787
1788 nest = outermost_loop_in_sese (region, bb);
1789
1790 loop_p loop = bb->loop_father;
1791 if (!loop_in_sese_p (loop, region))
1792 loop = nest;
1793
1794 gbb = gbb_from_bb (bb);
1795
1796 FOR_EACH_VEC_ELT (stmts, i, stmt)
1797 {
1798 if (is_gimple_debug (stmt))
1799 continue;
1800
1801 graphite_find_data_references_in_stmt (nest, loop, stmt,
1802 &GBB_DATA_REFS (gbb));
1803 }
1804 }
1805
1806 /* Insert STMT at the end of the STMTS sequence and then insert the
1807 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1808 on STMTS. */
1809
1810 static void
1811 insert_stmts (scop_p scop, gimple *stmt, gimple_seq stmts,
1812 gimple_stmt_iterator insert_gsi)
1813 {
1814 gimple_stmt_iterator gsi;
1815 auto_vec<gimple *, 3> x;
1816
1817 gimple_seq_add_stmt (&stmts, stmt);
1818 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1819 x.safe_push (gsi_stmt (gsi));
1820
1821 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
1822 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1823 }
1824
1825 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
1826
1827 static void
1828 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple *after_stmt)
1829 {
1830 gimple_seq stmts;
1831 gimple_stmt_iterator gsi;
1832 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1833 gassign *stmt = gimple_build_assign (unshare_expr (res), var);
1834 auto_vec<gimple *, 3> x;
1835
1836 gimple_seq_add_stmt (&stmts, stmt);
1837 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1838 x.safe_push (gsi_stmt (gsi));
1839
1840 if (gimple_code (after_stmt) == GIMPLE_PHI)
1841 {
1842 gsi = gsi_after_labels (gimple_bb (after_stmt));
1843 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1844 }
1845 else
1846 {
1847 gsi = gsi_for_stmt (after_stmt);
1848 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
1849 }
1850
1851 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
1852 }
1853
1854 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
1855
1856 static void
1857 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
1858 {
1859 vec<data_reference_p> drs;
1860 drs.create (3);
1861 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
1862 gimple_poly_bb_p gbb1 = new_gimple_poly_bb (bb, drs);
1863 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
1864 int index, n = SCOP_BBS (scop).length ();
1865
1866 /* The INDEX of PBB in SCOP_BBS. */
1867 for (index = 0; index < n; index++)
1868 if (SCOP_BBS (scop)[index] == pbb)
1869 break;
1870
1871 pbb1->domain = isl_set_copy (pbb->domain);
1872 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
1873 isl_id_for_pbb (scop, pbb1));
1874
1875 GBB_PBB (gbb1) = pbb1;
1876 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
1877 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
1878 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
1879 }
1880
1881 /* Insert on edge E the assignment "RES := EXPR". */
1882
1883 static void
1884 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
1885 {
1886 gimple_stmt_iterator gsi;
1887 gimple_seq stmts = NULL;
1888 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1889 gimple *stmt = gimple_build_assign (unshare_expr (res), var);
1890 basic_block bb;
1891 auto_vec<gimple *, 3> x;
1892
1893 gimple_seq_add_stmt (&stmts, stmt);
1894 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1895 x.safe_push (gsi_stmt (gsi));
1896
1897 gsi_insert_seq_on_edge (e, stmts);
1898 gsi_commit_edge_inserts ();
1899 bb = gimple_bb (stmt);
1900
1901 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
1902 return;
1903
1904 if (!gbb_from_bb (bb))
1905 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
1906
1907 analyze_drs_in_stmts (scop, bb, x);
1908 }
1909
1910 /* Creates a zero dimension array of the same type as VAR. */
1911
1912 static tree
1913 create_zero_dim_array (tree var, const char *base_name)
1914 {
1915 tree index_type = build_index_type (integer_zero_node);
1916 tree elt_type = TREE_TYPE (var);
1917 tree array_type = build_array_type (elt_type, index_type);
1918 tree base = create_tmp_var (array_type, base_name);
1919
1920 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1921 NULL_TREE);
1922 }
1923
1924 /* Returns true when PHI is a loop close phi node. */
1925
1926 static bool
1927 scalar_close_phi_node_p (gimple *phi)
1928 {
1929 if (gimple_code (phi) != GIMPLE_PHI
1930 || virtual_operand_p (gimple_phi_result (phi)))
1931 return false;
1932
1933 /* Note that loop close phi nodes should have a single argument
1934 because we translated the representation into a canonical form
1935 before Graphite: see canonicalize_loop_closed_ssa_form. */
1936 return (gimple_phi_num_args (phi) == 1);
1937 }
1938
1939 /* For a definition DEF in REGION, propagates the expression EXPR in
1940 all the uses of DEF outside REGION. */
1941
1942 static void
1943 propagate_expr_outside_region (tree def, tree expr, sese region)
1944 {
1945 imm_use_iterator imm_iter;
1946 gimple *use_stmt;
1947 gimple_seq stmts;
1948 bool replaced_once = false;
1949
1950 gcc_assert (TREE_CODE (def) == SSA_NAME);
1951
1952 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
1953 NULL_TREE);
1954
1955 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1956 if (!is_gimple_debug (use_stmt)
1957 && !bb_in_sese_p (gimple_bb (use_stmt), region))
1958 {
1959 ssa_op_iter iter;
1960 use_operand_p use_p;
1961
1962 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
1963 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
1964 && (replaced_once = true))
1965 replace_exp (use_p, expr);
1966
1967 update_stmt (use_stmt);
1968 }
1969
1970 if (replaced_once)
1971 {
1972 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
1973 gsi_commit_edge_inserts ();
1974 }
1975 }
1976
1977 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1978 dimension array for it. */
1979
1980 static void
1981 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
1982 {
1983 sese region = SCOP_REGION (scop);
1984 gimple *phi = gsi_stmt (*psi);
1985 tree res = gimple_phi_result (phi);
1986 basic_block bb = gimple_bb (phi);
1987 gimple_stmt_iterator gsi = gsi_after_labels (bb);
1988 tree arg = gimple_phi_arg_def (phi, 0);
1989 gimple *stmt;
1990
1991 /* Note that loop close phi nodes should have a single argument
1992 because we translated the representation into a canonical form
1993 before Graphite: see canonicalize_loop_closed_ssa_form. */
1994 gcc_assert (gimple_phi_num_args (phi) == 1);
1995
1996 /* The phi node can be a non close phi node, when its argument is
1997 invariant, or a default definition. */
1998 if (is_gimple_min_invariant (arg)
1999 || SSA_NAME_IS_DEFAULT_DEF (arg))
2000 {
2001 propagate_expr_outside_region (res, arg, region);
2002 gsi_next (psi);
2003 return;
2004 }
2005
2006 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2007 {
2008 propagate_expr_outside_region (res, arg, region);
2009 stmt = gimple_build_assign (res, arg);
2010 remove_phi_node (psi, false);
2011 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2012 return;
2013 }
2014
2015 /* If res is scev analyzable and is not a scalar value, it is safe
2016 to ignore the close phi node: it will be code generated in the
2017 out of Graphite pass. */
2018 else if (scev_analyzable_p (res, region))
2019 {
2020 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2021 tree scev;
2022
2023 if (!loop_in_sese_p (loop, region))
2024 {
2025 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2026 scev = scalar_evolution_in_region (region, loop, arg);
2027 scev = compute_overall_effect_of_inner_loop (loop, scev);
2028 }
2029 else
2030 scev = scalar_evolution_in_region (region, loop, res);
2031
2032 if (tree_does_not_contain_chrecs (scev))
2033 propagate_expr_outside_region (res, scev, region);
2034
2035 gsi_next (psi);
2036 return;
2037 }
2038 else
2039 {
2040 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2041
2042 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2043
2044 if (TREE_CODE (arg) == SSA_NAME)
2045 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2046 SSA_NAME_DEF_STMT (arg));
2047 else
2048 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2049 zero_dim_array, arg);
2050 }
2051
2052 remove_phi_node (psi, false);
2053 SSA_NAME_DEF_STMT (res) = stmt;
2054
2055 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2056 }
2057
2058 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2059 dimension array for it. */
2060
2061 static void
2062 rewrite_phi_out_of_ssa (scop_p scop, gphi_iterator *psi)
2063 {
2064 size_t i;
2065 gphi *phi = psi->phi ();
2066 basic_block bb = gimple_bb (phi);
2067 tree res = gimple_phi_result (phi);
2068 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2069 gimple *stmt;
2070
2071 for (i = 0; i < gimple_phi_num_args (phi); i++)
2072 {
2073 tree arg = gimple_phi_arg_def (phi, i);
2074 edge e = gimple_phi_arg_edge (phi, i);
2075
2076 /* Avoid the insertion of code in the loop latch to please the
2077 pattern matching of the vectorizer. */
2078 if (TREE_CODE (arg) == SSA_NAME
2079 && !SSA_NAME_IS_DEFAULT_DEF (arg)
2080 && e->src == bb->loop_father->latch)
2081 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2082 SSA_NAME_DEF_STMT (arg));
2083 else
2084 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2085 }
2086
2087 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2088 remove_phi_node (psi, false);
2089 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2090 }
2091
2092 /* Rewrite the degenerate phi node at position PSI from the degenerate
2093 form "x = phi (y, y, ..., y)" to "x = y". */
2094
2095 static void
2096 rewrite_degenerate_phi (gphi_iterator *psi)
2097 {
2098 tree rhs;
2099 gimple *stmt;
2100 gimple_stmt_iterator gsi;
2101 gphi *phi = psi->phi ();
2102 tree res = gimple_phi_result (phi);
2103 basic_block bb;
2104
2105 bb = gimple_bb (phi);
2106 rhs = degenerate_phi_result (phi);
2107 gcc_assert (rhs);
2108
2109 stmt = gimple_build_assign (res, rhs);
2110 remove_phi_node (psi, false);
2111
2112 gsi = gsi_after_labels (bb);
2113 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2114 }
2115
2116 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2117
2118 static void
2119 rewrite_reductions_out_of_ssa (scop_p scop)
2120 {
2121 basic_block bb;
2122 gphi_iterator psi;
2123 sese region = SCOP_REGION (scop);
2124
2125 FOR_EACH_BB_FN (bb, cfun)
2126 if (bb_in_sese_p (bb, region))
2127 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2128 {
2129 gphi *phi = psi.phi ();
2130
2131 if (virtual_operand_p (gimple_phi_result (phi)))
2132 {
2133 gsi_next (&psi);
2134 continue;
2135 }
2136
2137 if (gimple_phi_num_args (phi) > 1
2138 && degenerate_phi_result (phi))
2139 rewrite_degenerate_phi (&psi);
2140
2141 else if (scalar_close_phi_node_p (phi))
2142 rewrite_close_phi_out_of_ssa (scop, &psi);
2143
2144 else if (reduction_phi_p (region, &psi))
2145 rewrite_phi_out_of_ssa (scop, &psi);
2146 }
2147
2148 update_ssa (TODO_update_ssa);
2149 #ifdef ENABLE_CHECKING
2150 verify_loop_closed_ssa (true);
2151 #endif
2152 }
2153
2154 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2155 read from ZERO_DIM_ARRAY. */
2156
2157 static void
2158 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2159 tree def, gimple *use_stmt)
2160 {
2161 gimple *name_stmt;
2162 tree name;
2163 ssa_op_iter iter;
2164 use_operand_p use_p;
2165
2166 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2167
2168 name = copy_ssa_name (def);
2169 name_stmt = gimple_build_assign (name, zero_dim_array);
2170
2171 gimple_assign_set_lhs (name_stmt, name);
2172 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2173
2174 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2175 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2176 replace_exp (use_p, name);
2177
2178 update_stmt (use_stmt);
2179 }
2180
2181 /* For every definition DEF in the SCOP that is used outside the scop,
2182 insert a closing-scop definition in the basic block just after this
2183 SCOP. */
2184
2185 static void
2186 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple *stmt)
2187 {
2188 tree var = create_tmp_reg (TREE_TYPE (def));
2189 tree new_name = make_ssa_name (var, stmt);
2190 bool needs_copy = false;
2191 use_operand_p use_p;
2192 imm_use_iterator imm_iter;
2193 gimple *use_stmt;
2194 sese region = SCOP_REGION (scop);
2195
2196 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2197 {
2198 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2199 {
2200 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2201 {
2202 SET_USE (use_p, new_name);
2203 }
2204 update_stmt (use_stmt);
2205 needs_copy = true;
2206 }
2207 }
2208
2209 /* Insert in the empty BB just after the scop a use of DEF such
2210 that the rewrite of cross_bb_scalar_dependences won't insert
2211 arrays everywhere else. */
2212 if (needs_copy)
2213 {
2214 gimple *assign = gimple_build_assign (new_name, def);
2215 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2216
2217 update_stmt (assign);
2218 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2219 }
2220 }
2221
2222 /* Rewrite the scalar dependences crossing the boundary of the BB
2223 containing STMT with an array. Return true when something has been
2224 changed. */
2225
2226 static bool
2227 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2228 {
2229 sese region = SCOP_REGION (scop);
2230 gimple *stmt = gsi_stmt (*gsi);
2231 imm_use_iterator imm_iter;
2232 tree def;
2233 basic_block def_bb;
2234 tree zero_dim_array = NULL_TREE;
2235 gimple *use_stmt;
2236 bool res = false;
2237
2238 switch (gimple_code (stmt))
2239 {
2240 case GIMPLE_ASSIGN:
2241 def = gimple_assign_lhs (stmt);
2242 break;
2243
2244 case GIMPLE_CALL:
2245 def = gimple_call_lhs (stmt);
2246 break;
2247
2248 default:
2249 return false;
2250 }
2251
2252 if (!def
2253 || !is_gimple_reg (def))
2254 return false;
2255
2256 if (scev_analyzable_p (def, region))
2257 {
2258 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2259 tree scev = scalar_evolution_in_region (region, loop, def);
2260
2261 if (tree_contains_chrecs (scev, NULL))
2262 return false;
2263
2264 propagate_expr_outside_region (def, scev, region);
2265 return true;
2266 }
2267
2268 def_bb = gimple_bb (stmt);
2269
2270 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2271
2272 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2273 if (gphi *phi = dyn_cast <gphi *> (use_stmt))
2274 {
2275 res = true;
2276 gphi_iterator psi = gsi_for_phi (phi);
2277
2278 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2279 rewrite_close_phi_out_of_ssa (scop, &psi);
2280 else
2281 rewrite_phi_out_of_ssa (scop, &psi);
2282 }
2283
2284 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2285 if (gimple_code (use_stmt) != GIMPLE_PHI
2286 && def_bb != gimple_bb (use_stmt)
2287 && !is_gimple_debug (use_stmt)
2288 && (res = true))
2289 {
2290 if (!zero_dim_array)
2291 {
2292 zero_dim_array = create_zero_dim_array
2293 (def, "Cross_BB_scalar_dependence");
2294 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2295 SSA_NAME_DEF_STMT (def));
2296 gsi_next (gsi);
2297 }
2298
2299 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
2300 def, use_stmt);
2301 }
2302
2303 update_ssa (TODO_update_ssa);
2304
2305 return res;
2306 }
2307
2308 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2309
2310 static void
2311 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2312 {
2313 basic_block bb;
2314 gimple_stmt_iterator psi;
2315 sese region = SCOP_REGION (scop);
2316 bool changed = false;
2317
2318 /* Create an extra empty BB after the scop. */
2319 split_edge (SESE_EXIT (region));
2320
2321 FOR_EACH_BB_FN (bb, cfun)
2322 if (bb_in_sese_p (bb, region))
2323 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2324 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2325
2326 if (changed)
2327 {
2328 scev_reset_htab ();
2329 update_ssa (TODO_update_ssa);
2330 #ifdef ENABLE_CHECKING
2331 verify_loop_closed_ssa (true);
2332 #endif
2333 }
2334 }
2335
2336 /* Builds the polyhedral representation for a SESE region. */
2337
2338 void
2339 build_poly_scop (scop_p scop)
2340 {
2341 find_scop_parameters (scop);
2342
2343 graphite_dim_t max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
2344 if (scop_nb_params (scop) > max_dim)
2345 return;
2346 set_scop_parameter_dim (scop);
2347 build_scop_iteration_domain (scop);
2348 build_scop_context (scop);
2349 add_conditions_to_constraints (scop);
2350
2351 /* Rewrite out of SSA only after having translated the
2352 representation to the polyhedral representation to avoid scev
2353 analysis failures. That means that these functions will insert
2354 new data references that they create in the right place. */
2355 rewrite_reductions_out_of_ssa (scop);
2356 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
2357
2358 build_scop_drs (scop);
2359 build_scop_scattering (scop);
2360
2361 /* This SCoP has been translated to the polyhedral
2362 representation. */
2363 POLY_SCOP_P (scop) = true;
2364 }
2365 #endif /* HAVE_isl */