]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/graphite-sese-to-poly.c
Refactor graphite-sese-to-poly, sese.h, graphite-poly.h
[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 static const unsigned ssa_name_version_typesize = sizeof(unsigned);
72
73 /* Assigns to RES the value of the INTEGER_CST T. */
74
75 static inline void
76 tree_int_to_gmp (tree t, mpz_t res)
77 {
78 wi::to_mpz (t, res, TYPE_SIGN (TREE_TYPE (t)));
79 }
80
81 /* Returns the index of the PHI argument defined in the outermost
82 loop. */
83
84 static size_t
85 phi_arg_in_outermost_loop (gphi *phi)
86 {
87 loop_p loop = gimple_bb (phi)->loop_father;
88 size_t i, res = 0;
89
90 for (i = 0; i < gimple_phi_num_args (phi); i++)
91 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
92 {
93 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
94 res = i;
95 }
96
97 return res;
98 }
99
100 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
101 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
102
103 static void
104 remove_simple_copy_phi (gphi_iterator *psi)
105 {
106 gphi *phi = psi->phi ();
107 tree res = gimple_phi_result (phi);
108 size_t entry = phi_arg_in_outermost_loop (phi);
109 tree init = gimple_phi_arg_def (phi, entry);
110 gassign *stmt = gimple_build_assign (res, init);
111 edge e = gimple_phi_arg_edge (phi, entry);
112
113 remove_phi_node (psi, false);
114 gsi_insert_on_edge_immediate (e, stmt);
115 }
116
117 /* Removes an invariant phi node at position PSI by inserting on the
118 loop ENTRY edge the assignment RES = INIT. */
119
120 static void
121 remove_invariant_phi (sese_l &region, gphi_iterator *psi)
122 {
123 gphi *phi = psi->phi ();
124 loop_p loop = loop_containing_stmt (phi);
125 tree res = gimple_phi_result (phi);
126 tree scev = scalar_evolution_in_region (region, loop, res);
127 size_t entry = phi_arg_in_outermost_loop (phi);
128 edge e = gimple_phi_arg_edge (phi, entry);
129 tree var;
130 gassign *stmt;
131 gimple_seq stmts = NULL;
132
133 if (tree_contains_chrecs (scev, NULL))
134 scev = gimple_phi_arg_def (phi, entry);
135
136 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
137 stmt = gimple_build_assign (res, var);
138 remove_phi_node (psi, false);
139
140 gimple_seq_add_stmt (&stmts, stmt);
141 gsi_insert_seq_on_edge (e, stmts);
142 gsi_commit_edge_inserts ();
143 SSA_NAME_DEF_STMT (res) = stmt;
144 }
145
146 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
147
148 static inline bool
149 simple_copy_phi_p (gphi *phi)
150 {
151 if (gimple_phi_num_args (phi) != 2)
152 return false;
153
154 tree 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_l &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 /* Return an ISL identifier for the polyhedral basic block PBB. */
200
201 static isl_id *
202 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
203 {
204 char name[ssa_name_version_typesize];
205 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
206 return isl_id_alloc (s->isl_context, name, pbb);
207 }
208
209 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
210 We generate SCATTERING_DIMENSIONS scattering dimensions.
211
212 The scattering polyhedron consists of these dimensions: scattering,
213 loop_iterators, parameters.
214
215 Example:
216
217 | scattering_dimensions = 5
218 | nb_iterators = 1
219 | scop_nb_params = 2
220 |
221 | Schedule:
222 | i
223 | 4 5
224 |
225 | Scattering polyhedron:
226 |
227 | scattering: {s1, s2, s3, s4, s5}
228 | loop_iterators: {i}
229 | parameters: {p1, p2}
230 |
231 | s1 s2 s3 s4 s5 i p1 p2 1
232 | 1 0 0 0 0 0 0 0 -4 = 0
233 | 0 1 0 0 0 -1 0 0 0 = 0
234 | 0 0 1 0 0 0 0 0 -5 = 0 */
235
236 static void
237 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
238 poly_bb_p pbb)
239 {
240 isl_val *val;
241
242 int scattering_dimensions = isl_set_dim (pbb->domain, isl_dim_set) * 2 + 1;
243
244 isl_space *dc = isl_set_get_space (pbb->domain);
245 isl_space *dm = isl_space_add_dims (isl_space_from_domain (dc),
246 isl_dim_out, scattering_dimensions);
247 pbb->schedule = isl_map_universe (dm);
248
249 for (int i = 0; i < scattering_dimensions; i++)
250 {
251 /* Textual order inside this loop. */
252 if ((i % 2) == 0)
253 {
254 isl_constraint *c = isl_equality_alloc
255 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
256
257 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
258 gcc_assert (val && isl_val_is_int (val));
259
260 val = isl_val_neg (val);
261 c = isl_constraint_set_constant_val (c, val);
262 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
263 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
264 }
265
266 /* Iterations of this loop. */
267 else /* if ((i % 2) == 1) */
268 {
269 int loop = (i - 1) / 2;
270 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
271 isl_dim_out, i);
272 }
273 }
274
275 pbb->transformed = isl_map_copy (pbb->schedule);
276 }
277
278 /* Build for BB the static schedule.
279
280 The static schedule is a Dewey numbering of the abstract syntax
281 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
282
283 The following example informally defines the static schedule:
284
285 A
286 for (i: ...)
287 {
288 for (j: ...)
289 {
290 B
291 C
292 }
293
294 for (k: ...)
295 {
296 D
297 E
298 }
299 }
300 F
301
302 Static schedules for A to F:
303
304 DEPTH
305 0 1 2
306 A 0
307 B 1 0 0
308 C 1 0 1
309 D 1 1 0
310 E 1 1 1
311 F 2
312 */
313
314 static void
315 build_scop_scattering (scop_p scop)
316 {
317 gimple_poly_bb_p previous_gbb = NULL;
318 isl_space *dc = isl_set_get_space (scop->param_context);
319 isl_aff *static_sched;
320
321 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
322 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
323
324 /* We have to start schedules at 0 on the first component and
325 because we cannot compare_prefix_loops against a previous loop,
326 prefix will be equal to zero, and that index will be
327 incremented before copying. */
328 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
329
330 int i;
331 poly_bb_p pbb;
332 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
333 {
334 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
335 int prefix = 0;
336
337 if (previous_gbb)
338 prefix = nb_common_loops (scop->scop_info->region, previous_gbb, gbb);
339
340 previous_gbb = gbb;
341
342 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
343 prefix, 1);
344 build_pbb_scattering_polyhedrons (static_sched, pbb);
345 }
346
347 isl_aff_free (static_sched);
348 }
349
350 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
351
352 /* Extract an affine expression from the chain of recurrence E. */
353
354 static isl_pw_aff *
355 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
356 {
357 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
358 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
359 isl_local_space *ls = isl_local_space_from_space (space);
360 unsigned pos = sese_loop_depth (s->scop_info->region, get_chrec_loop (e)) - 1;
361 isl_aff *loop = isl_aff_set_coefficient_si
362 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
363 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
364
365 /* Before multiplying, make sure that the result is affine. */
366 gcc_assert (isl_pw_aff_is_cst (rhs)
367 || isl_pw_aff_is_cst (l));
368
369 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
370 }
371
372 /* Extract an affine expression from the mult_expr E. */
373
374 static isl_pw_aff *
375 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
376 {
377 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
378 isl_space_copy (space));
379 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
380
381 if (!isl_pw_aff_is_cst (lhs)
382 && !isl_pw_aff_is_cst (rhs))
383 {
384 isl_pw_aff_free (lhs);
385 isl_pw_aff_free (rhs);
386 return NULL;
387 }
388
389 return isl_pw_aff_mul (lhs, rhs);
390 }
391
392 /* Return an ISL identifier from the name of the ssa_name E. */
393
394 static isl_id *
395 isl_id_for_ssa_name (scop_p s, tree e)
396 {
397 const char *name = get_name (e);
398 isl_id *id;
399
400 if (name)
401 id = isl_id_alloc (s->isl_context, name, e);
402 else
403 {
404 char name1[ssa_name_version_typesize];
405 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
406 id = isl_id_alloc (s->isl_context, name1, e);
407 }
408
409 return id;
410 }
411
412 /* Return an ISL identifier for the data reference DR. */
413
414 static isl_id *
415 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
416 {
417 /* Data references all get the same isl_id. They need to be comparable
418 and are distinguished through the first dimension, which contains the
419 alias set number. */
420 return isl_id_alloc (s->isl_context, "", 0);
421 }
422
423 /* Extract an affine expression from the ssa_name E. */
424
425 static isl_pw_aff *
426 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
427 {
428 isl_id *id = isl_id_for_ssa_name (s, e);
429 int dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
430 isl_id_free (id);
431 isl_set *dom = isl_set_universe (isl_space_copy (space));
432 isl_aff *aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
433 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
434 return isl_pw_aff_alloc (dom, aff);
435 }
436
437 /* Extract an affine expression from the gmp constant G. */
438
439 static isl_pw_aff *
440 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
441 {
442 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
443 isl_aff *aff = isl_aff_zero_on_domain (ls);
444 isl_set *dom = isl_set_universe (space);
445 isl_ctx *ct = isl_aff_get_ctx (aff);
446 isl_val *v = isl_val_int_from_gmp (ct, g);
447 aff = isl_aff_add_constant_val (aff, v);
448
449 return isl_pw_aff_alloc (dom, aff);
450 }
451
452 /* Extract an affine expression from the integer_cst E. */
453
454 static isl_pw_aff *
455 extract_affine_int (tree e, __isl_take isl_space *space)
456 {
457 mpz_t g;
458
459 mpz_init (g);
460 tree_int_to_gmp (e, g);
461 isl_pw_aff *res = extract_affine_gmp (g, space);
462 mpz_clear (g);
463
464 return res;
465 }
466
467 /* Compute pwaff mod 2^width. */
468
469 static isl_pw_aff *
470 wrap (isl_pw_aff *pwaff, unsigned width)
471 {
472 isl_val *mod;
473
474 mod = isl_val_int_from_ui (isl_pw_aff_get_ctx (pwaff), width);
475 mod = isl_val_2exp (mod);
476 pwaff = isl_pw_aff_mod_val (pwaff, mod);
477
478 return pwaff;
479 }
480
481 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
482 Otherwise returns -1. */
483
484 static inline int
485 parameter_index_in_region_1 (tree name, sese_info_p region)
486 {
487 int i;
488 tree p;
489
490 gcc_assert (TREE_CODE (name) == SSA_NAME);
491
492 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
493 if (p == name)
494 return i;
495
496 return -1;
497 }
498
499 /* Extract an affine expression from the tree E in the scop S. */
500
501 static isl_pw_aff *
502 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
503 {
504 isl_pw_aff *lhs, *rhs, *res;
505
506 if (e == chrec_dont_know) {
507 isl_space_free (space);
508 return NULL;
509 }
510
511 switch (TREE_CODE (e))
512 {
513 case POLYNOMIAL_CHREC:
514 res = extract_affine_chrec (s, e, space);
515 break;
516
517 case MULT_EXPR:
518 res = extract_affine_mul (s, e, space);
519 break;
520
521 case PLUS_EXPR:
522 case POINTER_PLUS_EXPR:
523 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
524 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
525 res = isl_pw_aff_add (lhs, rhs);
526 break;
527
528 case MINUS_EXPR:
529 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
530 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
531 res = isl_pw_aff_sub (lhs, rhs);
532 break;
533
534 case NEGATE_EXPR:
535 case BIT_NOT_EXPR:
536 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
537 rhs = extract_affine (s, integer_minus_one_node, space);
538 res = isl_pw_aff_mul (lhs, rhs);
539 break;
540
541 case SSA_NAME:
542 gcc_assert (-1 != parameter_index_in_region_1 (e, s->scop_info)
543 || !invariant_in_sese_p_rec (e, s->scop_info->region));
544 res = extract_affine_name (s, e, space);
545 break;
546
547 case INTEGER_CST:
548 res = extract_affine_int (e, space);
549 /* No need to wrap a single integer. */
550 return res;
551
552 CASE_CONVERT:
553 case NON_LVALUE_EXPR:
554 res = extract_affine (s, TREE_OPERAND (e, 0), space);
555 break;
556
557 default:
558 gcc_unreachable ();
559 break;
560 }
561
562 tree type = TREE_TYPE (e);
563 if (TYPE_UNSIGNED (type))
564 res = wrap (res, TYPE_PRECISION (type));
565
566 return res;
567 }
568
569 /* Assign dimension for each parameter in SCOP. */
570
571 static void
572 set_scop_parameter_dim (scop_p scop)
573 {
574 sese_info_p region = scop->scop_info;
575 unsigned nbp = sese_nb_params (region);
576 isl_space *space = isl_space_set_alloc (scop->isl_context, nbp, 0);
577
578 unsigned i;
579 tree e;
580 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
581 space = isl_space_set_dim_id (space, isl_dim_param, i,
582 isl_id_for_ssa_name (scop, e));
583
584 scop->param_context = isl_set_universe (space);
585 }
586
587 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
588 the constraints for the surrounding loops. */
589
590 static void
591 build_loop_iteration_domains (scop_p scop, struct loop *loop,
592 int nb,
593 isl_set *outer, isl_set **doms)
594 {
595
596 tree nb_iters = number_of_latch_executions (loop);
597 sese_l region = scop->scop_info->region;
598 gcc_assert (loop_in_sese_p (loop, region));
599
600 isl_set *inner = isl_set_copy (outer);
601 int pos = isl_set_dim (outer, isl_dim_set);
602 isl_val *v;
603 mpz_t g;
604
605 mpz_init (g);
606
607 inner = isl_set_add_dims (inner, isl_dim_set, 1);
608 isl_space *space = isl_set_get_space (inner);
609
610 /* 0 <= loop_i */
611 isl_constraint *c = isl_inequality_alloc
612 (isl_local_space_from_space (isl_space_copy (space)));
613 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
614 inner = isl_set_add_constraint (inner, c);
615
616 /* loop_i <= cst_nb_iters */
617 if (TREE_CODE (nb_iters) == INTEGER_CST)
618 {
619 c = isl_inequality_alloc
620 (isl_local_space_from_space (isl_space_copy (space)));
621 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
622 tree_int_to_gmp (nb_iters, g);
623 v = isl_val_int_from_gmp (scop->isl_context, g);
624 c = isl_constraint_set_constant_val (c, v);
625 inner = isl_set_add_constraint (inner, c);
626 }
627
628 /* loop_i <= expr_nb_iters */
629 else if (!chrec_contains_undetermined (nb_iters))
630 {
631 isl_pw_aff *aff;
632
633 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
634
635 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
636 isl_set *valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
637 valid = isl_set_project_out (valid, isl_dim_set, 0,
638 isl_set_dim (valid, isl_dim_set));
639 scop->param_context = isl_set_intersect (scop->param_context, valid);
640
641 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
642 isl_aff *al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
643 isl_dim_in, pos, 1);
644 isl_set *le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
645 isl_pw_aff_copy (aff));
646 inner = isl_set_intersect (inner, le);
647
648 widest_int nit;
649 if (max_stmt_executions (loop, &nit))
650 {
651 /* Insert in the context the constraints from the
652 estimation of the number of iterations NIT and the
653 symbolic number of iterations (involving parameter
654 names) NB_ITERS. First, build the affine expression
655 "NIT - NB_ITERS" and then say that it is positive,
656 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
657 mpz_t g;
658 mpz_init (g);
659 wi::to_mpz (nit, g, SIGNED);
660 mpz_sub_ui (g, g, 1);
661
662 isl_pw_aff *approx
663 = extract_affine_gmp (g, isl_set_get_space (inner));
664 isl_set *x = isl_pw_aff_ge_set (approx, aff);
665 x = isl_set_project_out (x, isl_dim_set, 0,
666 isl_set_dim (x, isl_dim_set));
667 scop->param_context = isl_set_intersect (scop->param_context, x);
668
669 isl_constraint *c = isl_inequality_alloc
670 (isl_local_space_from_space (isl_space_copy (space)));
671 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
672 v = isl_val_int_from_gmp (scop->isl_context, g);
673 mpz_clear (g);
674 c = isl_constraint_set_constant_val (c, v);
675 inner = isl_set_add_constraint (inner, c);
676 }
677 else
678 isl_pw_aff_free (aff);
679 }
680 else
681 gcc_unreachable ();
682
683 if (loop->inner)
684 build_loop_iteration_domains (scop, loop->inner, nb + 1,
685 isl_set_copy (inner), doms);
686
687 if (nb != 0
688 && loop->next
689 && loop_in_sese_p (loop->next, region))
690 build_loop_iteration_domains (scop, loop->next, nb,
691 isl_set_copy (outer), doms);
692
693 doms[loop->num] = inner;
694
695 isl_set_free (outer);
696 isl_space_free (space);
697 mpz_clear (g);
698 }
699
700 /* Returns a linear expression for tree T evaluated in PBB. */
701
702 static isl_pw_aff *
703 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
704 {
705 scop_p scop = PBB_SCOP (pbb);
706
707 t = scalar_evolution_in_region (scop->scop_info->region, pbb_loop (pbb), t);
708 gcc_assert (!automatically_generated_chrec_p (t));
709
710 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
711 }
712
713 /* Add conditional statement STMT to pbb. CODE is used as the comparison
714 operator. This allows us to invert the condition or to handle
715 inequalities. */
716
717 static void
718 add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
719 {
720 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
721 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
722 isl_set *cond;
723
724 switch (code)
725 {
726 case LT_EXPR:
727 cond = isl_pw_aff_lt_set (lhs, rhs);
728 break;
729
730 case GT_EXPR:
731 cond = isl_pw_aff_gt_set (lhs, rhs);
732 break;
733
734 case LE_EXPR:
735 cond = isl_pw_aff_le_set (lhs, rhs);
736 break;
737
738 case GE_EXPR:
739 cond = isl_pw_aff_ge_set (lhs, rhs);
740 break;
741
742 case EQ_EXPR:
743 cond = isl_pw_aff_eq_set (lhs, rhs);
744 break;
745
746 case NE_EXPR:
747 cond = isl_pw_aff_ne_set (lhs, rhs);
748 break;
749
750 default:
751 isl_pw_aff_free (lhs);
752 isl_pw_aff_free (rhs);
753 return;
754 }
755
756 cond = isl_set_coalesce (cond);
757 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
758 pbb->domain = isl_set_intersect (pbb->domain, cond);
759 }
760
761 /* Add conditions to the domain of PBB. */
762
763 static void
764 add_conditions_to_domain (poly_bb_p pbb)
765 {
766 unsigned int i;
767 gimple *stmt;
768 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
769
770 if (GBB_CONDITIONS (gbb).is_empty ())
771 return;
772
773 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
774 switch (gimple_code (stmt))
775 {
776 case GIMPLE_COND:
777 {
778 /* Don't constrain on anything else than INTEGER_TYPE. */
779 if (TREE_CODE (TREE_TYPE (gimple_cond_lhs (stmt))) != INTEGER_TYPE)
780 break;
781
782 gcond *cond_stmt = as_a <gcond *> (stmt);
783 enum tree_code code = gimple_cond_code (cond_stmt);
784
785 /* The conditions for ELSE-branches are inverted. */
786 if (!GBB_CONDITION_CASES (gbb)[i])
787 code = invert_tree_comparison (code, false);
788
789 add_condition_to_pbb (pbb, cond_stmt, code);
790 break;
791 }
792
793 case GIMPLE_SWITCH:
794 /* Switch statements are not supported right now - fall through. */
795
796 default:
797 gcc_unreachable ();
798 break;
799 }
800 }
801
802 /* Traverses all the GBBs of the SCOP and add their constraints to the
803 iteration domains. */
804
805 static void
806 add_conditions_to_constraints (scop_p scop)
807 {
808 int i;
809 poly_bb_p pbb;
810
811 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
812 add_conditions_to_domain (pbb);
813 }
814
815 /* Add constraints on the possible values of parameter P from the type
816 of P. */
817
818 static void
819 add_param_constraints (scop_p scop, graphite_dim_t p)
820 {
821 tree parameter = SESE_PARAMS (scop->scop_info)[p];
822 tree type = TREE_TYPE (parameter);
823 tree lb = NULL_TREE;
824 tree ub = NULL_TREE;
825
826 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
827 lb = lower_bound_in_type (type, type);
828 else
829 lb = TYPE_MIN_VALUE (type);
830
831 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
832 ub = upper_bound_in_type (type, type);
833 else
834 ub = TYPE_MAX_VALUE (type);
835
836 if (lb)
837 {
838 isl_space *space = isl_set_get_space (scop->param_context);
839 isl_constraint *c;
840 mpz_t g;
841 isl_val *v;
842
843 c = isl_inequality_alloc (isl_local_space_from_space (space));
844 mpz_init (g);
845 tree_int_to_gmp (lb, g);
846 v = isl_val_int_from_gmp (scop->isl_context, g);
847 v = isl_val_neg (v);
848 mpz_clear (g);
849 c = isl_constraint_set_constant_val (c, v);
850 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
851
852 scop->param_context = isl_set_add_constraint (scop->param_context, c);
853 }
854
855 if (ub)
856 {
857 isl_space *space = isl_set_get_space (scop->param_context);
858 isl_constraint *c;
859 mpz_t g;
860 isl_val *v;
861
862 c = isl_inequality_alloc (isl_local_space_from_space (space));
863
864 mpz_init (g);
865 tree_int_to_gmp (ub, g);
866 v = isl_val_int_from_gmp (scop->isl_context, g);
867 mpz_clear (g);
868 c = isl_constraint_set_constant_val (c, v);
869 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
870
871 scop->param_context = isl_set_add_constraint (scop->param_context, c);
872 }
873 }
874
875 /* Build the context of the SCOP. The context usually contains extra
876 constraints that are added to the iteration domains that constrain
877 some parameters. */
878
879 static void
880 build_scop_context (scop_p scop)
881 {
882 graphite_dim_t p, n = scop_nb_params (scop);
883
884 for (p = 0; p < n; p++)
885 add_param_constraints (scop, p);
886 }
887
888 /* Build the iteration domains: the loops belonging to the current
889 SCOP, and that vary for the execution of the current basic block.
890 Returns false if there is no loop in SCOP. */
891
892 static void
893 build_scop_iteration_domain (scop_p scop)
894 {
895 sese_info_p region = scop->scop_info;
896 int nb_loops = number_of_loops (cfun);
897 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
898
899 int i;
900 struct loop *loop;
901 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
902 if (!loop_in_sese_p (loop_outer (loop), region->region))
903 build_loop_iteration_domains (scop, loop, 0,
904 isl_set_copy (scop->param_context), doms);
905
906 poly_bb_p pbb;
907 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
908 {
909 loop = pbb_loop (pbb);
910
911 if (doms[loop->num])
912 pbb->domain = isl_set_copy (doms[loop->num]);
913 else
914 pbb->domain = isl_set_copy (scop->param_context);
915
916 pbb->domain = isl_set_set_tuple_id (pbb->domain,
917 isl_id_for_pbb (scop, pbb));
918 }
919
920 for (int i = 0; i < nb_loops; i++)
921 if (doms[i])
922 isl_set_free (doms[i]);
923
924 free (doms);
925 }
926
927 /* Add a constrain to the ACCESSES polyhedron for the alias set of
928 data reference DR. ACCESSP_NB_DIMS is the dimension of the
929 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
930 domain. */
931
932 static isl_map *
933 pdr_add_alias_set (isl_map *acc, dr_info &dri)
934 {
935 isl_constraint *c = isl_equality_alloc
936 (isl_local_space_from_space (isl_map_get_space (acc)));
937 c = isl_constraint_set_constant_si (c, -dri.alias_set);
938 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
939
940 return isl_map_add_constraint (acc, c);
941 }
942
943 /* Assign the affine expression INDEX to the output dimension POS of
944 MAP and return the result. */
945
946 static isl_map *
947 set_index (isl_map *map, int pos, isl_pw_aff *index)
948 {
949 isl_map *index_map;
950 int len = isl_map_dim (map, isl_dim_out);
951 isl_id *id;
952
953 index_map = isl_map_from_pw_aff (index);
954 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
955 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
956
957 id = isl_map_get_tuple_id (map, isl_dim_out);
958 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
959 id = isl_map_get_tuple_id (map, isl_dim_in);
960 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
961
962 return isl_map_intersect (map, index_map);
963 }
964
965 /* Add to ACCESSES polyhedron equalities defining the access functions
966 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
967 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
968 PBB is the poly_bb_p that contains the data reference DR. */
969
970 static isl_map *
971 pdr_add_memory_accesses (isl_map *acc, dr_info &dri)
972 {
973 data_reference_p dr = dri.dr;
974 poly_bb_p pbb = dri.pbb;
975 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
976 scop_p scop = PBB_SCOP (pbb);
977
978 for (i = 0; i < nb_subscripts; i++)
979 {
980 isl_pw_aff *aff;
981 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
982
983 aff = extract_affine (scop, afn,
984 isl_space_domain (isl_map_get_space (acc)));
985 acc = set_index (acc, i + 1, aff);
986 }
987
988 return acc;
989 }
990
991 /* Add constrains representing the size of the accessed data to the
992 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
993 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
994 domain. */
995
996 static isl_set *
997 pdr_add_data_dimensions (isl_set *subscript_sizes, scop_p scop,
998 data_reference_p dr)
999 {
1000 tree ref = DR_REF (dr);
1001
1002 int nb_subscripts = DR_NUM_DIMENSIONS (dr);
1003 for (int i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1004 {
1005 if (TREE_CODE (ref) != ARRAY_REF)
1006 return subscript_sizes;
1007
1008 tree low = array_ref_low_bound (ref);
1009 tree high = array_ref_up_bound (ref);
1010
1011 /* XXX The PPL code dealt separately with
1012 subscript - low >= 0 and high - subscript >= 0 in case one of
1013 the two bounds isn't known. Do the same here? */
1014
1015 if (tree_fits_shwi_p (low)
1016 && high
1017 && tree_fits_shwi_p (high)
1018 /* 1-element arrays at end of structures may extend over
1019 their declared size. */
1020 && !(array_at_struct_end_p (ref)
1021 && operand_equal_p (low, high, 0)))
1022 {
1023 isl_id *id;
1024 isl_aff *aff;
1025 isl_set *univ, *lbs, *ubs;
1026 isl_pw_aff *index;
1027 isl_set *valid;
1028 isl_space *space = isl_set_get_space (subscript_sizes);
1029 isl_pw_aff *lb = extract_affine_int (low, isl_space_copy (space));
1030 isl_pw_aff *ub = extract_affine_int (high, isl_space_copy (space));
1031
1032 /* high >= 0 */
1033 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1034 valid = isl_set_project_out (valid, isl_dim_set, 0,
1035 isl_set_dim (valid, isl_dim_set));
1036 scop->param_context = isl_set_intersect (scop->param_context, valid);
1037
1038 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1039 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1040 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1041 index = isl_pw_aff_alloc (univ, aff);
1042
1043 id = isl_set_get_tuple_id (subscript_sizes);
1044 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1045 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1046
1047 /* low <= sub_i <= high */
1048 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1049 ubs = isl_pw_aff_le_set (index, ub);
1050 subscript_sizes = isl_set_intersect (subscript_sizes, lbs);
1051 subscript_sizes = isl_set_intersect (subscript_sizes, ubs);
1052 }
1053 }
1054
1055 return subscript_sizes;
1056 }
1057
1058 /* Build data accesses for DR in PBB. */
1059
1060 static void
1061 build_poly_dr (dr_info &dri)
1062 {
1063 isl_map *acc;
1064 isl_set *subscript_sizes;
1065 poly_bb_p pbb = dri.pbb;
1066 data_reference_p dr = dri.dr;
1067 scop_p scop = PBB_SCOP (pbb);
1068
1069 {
1070 isl_space *dc = isl_set_get_space (pbb->domain);
1071 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1072 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1073 isl_dim_out, nb_out);
1074
1075 acc = isl_map_universe (space);
1076 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1077 }
1078
1079 acc = pdr_add_alias_set (acc, dri);
1080 acc = pdr_add_memory_accesses (acc, dri);
1081
1082 {
1083 isl_id *id = isl_id_for_dr (scop, dr);
1084 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1085 isl_space *space = isl_space_set_alloc (scop->isl_context, 0, nb);
1086
1087 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1088 subscript_sizes = isl_set_nat_universe (space);
1089 subscript_sizes = isl_set_fix_si (subscript_sizes, isl_dim_set, 0,
1090 dri.alias_set);
1091 subscript_sizes = pdr_add_data_dimensions (subscript_sizes, scop, dr);
1092 }
1093
1094 new_poly_dr (pbb,
1095 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1096 dr, DR_NUM_DIMENSIONS (dr), acc, subscript_sizes);
1097 }
1098
1099 /* Compute alias-sets for all data references in DRS. */
1100
1101 static void
1102 build_alias_set (scop_p scop)
1103 {
1104 int num_vertices = scop->drs.length ();
1105 struct graph *g = new_graph (num_vertices);
1106 dr_info *dr1, *dr2;
1107 int i, j;
1108 int *all_vertices;
1109
1110 FOR_EACH_VEC_ELT (scop->drs, i, dr1)
1111 for (j = i+1; scop->drs.iterate (j, &dr2); j++)
1112 if (dr_may_alias_p (dr1->dr, dr2->dr, true))
1113 {
1114 add_edge (g, i, j);
1115 add_edge (g, j, i);
1116 }
1117
1118 all_vertices = XNEWVEC (int, num_vertices);
1119 for (i = 0; i < num_vertices; i++)
1120 all_vertices[i] = i;
1121
1122 graphds_dfs (g, all_vertices, num_vertices, NULL, true, NULL);
1123 free (all_vertices);
1124
1125 for (i = 0; i < g->n_vertices; i++)
1126 scop->drs[i].alias_set = g->vertices[i].component + 1;
1127
1128 free_graph (g);
1129 }
1130
1131 /* Build data references in SCOP. */
1132
1133 static void
1134 build_scop_drs (scop_p scop)
1135 {
1136 int i, j;
1137 poly_bb_p pbb;
1138
1139 /* Remove all the PBBs that do not have data references: these basic
1140 blocks are not handled in the polyhedral representation. */
1141 for (i = 0; scop->pbbs.iterate (i, &pbb); i++)
1142 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1143 {
1144 free_gimple_poly_bb (PBB_BLACK_BOX (pbb));
1145 free_poly_bb (pbb);
1146 scop->pbbs.ordered_remove (i);
1147 i--;
1148 }
1149
1150 data_reference_p dr;
1151 FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
1152 if (pbb)
1153 FOR_EACH_VEC_ELT (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr)
1154 scop->drs.safe_push (dr_info (dr, pbb));
1155
1156 build_alias_set (scop);
1157
1158 dr_info *dri;
1159 FOR_EACH_VEC_ELT (scop->drs, i, dri)
1160 build_poly_dr (*dri);
1161 }
1162
1163 /* Analyze all the data references of STMTS and add them to the
1164 GBB_DATA_REFS vector of BB. */
1165
1166 static void
1167 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple *> stmts)
1168 {
1169 sese_l region = scop->scop_info->region;
1170 if (!bb_in_sese_p (bb, region))
1171 return;
1172
1173 loop_p nest = outermost_loop_in_sese (region, bb);
1174 loop_p loop = bb->loop_father;
1175 if (!loop_in_sese_p (loop, region))
1176 loop = nest;
1177
1178 gimple_poly_bb_p gbb = gbb_from_bb (bb);
1179
1180 gimple *stmt;
1181 int i;
1182 FOR_EACH_VEC_ELT (stmts, i, stmt)
1183 {
1184 if (is_gimple_debug (stmt))
1185 continue;
1186
1187 graphite_find_data_references_in_stmt (nest, loop, stmt,
1188 &GBB_DATA_REFS (gbb));
1189 }
1190 }
1191
1192 /* Insert STMT at the end of the STMTS sequence and then insert the
1193 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1194 on STMTS. */
1195
1196 static void
1197 insert_stmts (scop_p scop, gimple *stmt, gimple_seq stmts,
1198 gimple_stmt_iterator insert_gsi)
1199 {
1200 gimple_stmt_iterator gsi;
1201 auto_vec<gimple *, 3> x;
1202
1203 gimple_seq_add_stmt (&stmts, stmt);
1204 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1205 x.safe_push (gsi_stmt (gsi));
1206
1207 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
1208 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1209 }
1210
1211 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
1212
1213 static void
1214 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple *after_stmt)
1215 {
1216 gimple_stmt_iterator gsi;
1217 auto_vec<gimple *, 3> x;
1218 gimple_seq stmts;
1219 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1220 gassign *stmt = gimple_build_assign (unshare_expr (res), var);
1221
1222 gimple_seq_add_stmt (&stmts, stmt);
1223
1224 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1225 x.safe_push (gsi_stmt (gsi));
1226
1227 if (gimple_code (after_stmt) == GIMPLE_PHI)
1228 {
1229 gsi = gsi_after_labels (gimple_bb (after_stmt));
1230 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1231 }
1232 else
1233 {
1234 gsi = gsi_for_stmt (after_stmt);
1235 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
1236 }
1237
1238 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
1239 }
1240
1241 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
1242
1243 static void
1244 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
1245 {
1246 vec<data_reference_p> drs;
1247 drs.create (3);
1248 gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
1249 gimple_poly_bb_p gbb1 = new_gimple_poly_bb (bb, drs);
1250 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
1251 int index, n = scop->pbbs.length ();
1252
1253 for (index = 0; index < n; index++)
1254 if (scop->pbbs[index] == pbb)
1255 break;
1256
1257 pbb1->domain = isl_set_copy (pbb->domain);
1258 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
1259 isl_id_for_pbb (scop, pbb1));
1260
1261 GBB_PBB (gbb1) = pbb1;
1262 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
1263 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
1264 scop->pbbs.safe_insert (index + 1, pbb1);
1265 }
1266
1267 /* Insert on edge E the assignment "RES := EXPR". */
1268
1269 static void
1270 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
1271 {
1272 gimple_seq stmts = NULL;
1273 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
1274 gimple *stmt = gimple_build_assign (unshare_expr (res), var);
1275 auto_vec<gimple *, 3> x;
1276
1277 gimple_seq_add_stmt (&stmts, stmt);
1278 gimple_stmt_iterator gsi;
1279 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1280 x.safe_push (gsi_stmt (gsi));
1281
1282 gsi_insert_seq_on_edge (e, stmts);
1283 gsi_commit_edge_inserts ();
1284 basic_block bb = gimple_bb (stmt);
1285
1286 if (!bb_in_sese_p (bb, scop->scop_info->region))
1287 return;
1288
1289 if (!gbb_from_bb (bb))
1290 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
1291
1292 analyze_drs_in_stmts (scop, bb, x);
1293 }
1294
1295 /* Creates a zero dimension array of the same type as VAR. */
1296
1297 static tree
1298 create_zero_dim_array (tree var, const char *base_name)
1299 {
1300 tree index_type = build_index_type (integer_zero_node);
1301 tree elt_type = TREE_TYPE (var);
1302 tree array_type = build_array_type (elt_type, index_type);
1303 tree base = create_tmp_var (array_type, base_name);
1304
1305 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
1306 NULL_TREE);
1307 }
1308
1309 /* Returns true when PHI is a loop close phi node. */
1310
1311 static bool
1312 scalar_close_phi_node_p (gimple *phi)
1313 {
1314 if (gimple_code (phi) != GIMPLE_PHI
1315 || virtual_operand_p (gimple_phi_result (phi)))
1316 return false;
1317
1318 /* Note that loop close phi nodes should have a single argument
1319 because we translated the representation into a canonical form
1320 before Graphite: see canonicalize_loop_closed_ssa_form. */
1321 return (gimple_phi_num_args (phi) == 1);
1322 }
1323
1324 /* For a definition DEF in REGION, propagates the expression EXPR in
1325 all the uses of DEF outside REGION. */
1326
1327 static void
1328 propagate_expr_outside_region (tree def, tree expr, sese_l &region)
1329 {
1330 gimple_seq stmts;
1331 bool replaced_once = false;
1332
1333 gcc_assert (TREE_CODE (def) == SSA_NAME);
1334
1335 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
1336 NULL_TREE);
1337
1338 imm_use_iterator imm_iter;
1339 gimple *use_stmt;
1340 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1341 if (!is_gimple_debug (use_stmt)
1342 && !bb_in_sese_p (gimple_bb (use_stmt), region))
1343 {
1344 ssa_op_iter iter;
1345 use_operand_p use_p;
1346
1347 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
1348 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
1349 && (replaced_once = true))
1350 replace_exp (use_p, expr);
1351
1352 update_stmt (use_stmt);
1353 }
1354
1355 if (replaced_once)
1356 {
1357 gsi_insert_seq_on_edge (region.entry, stmts);
1358 gsi_commit_edge_inserts ();
1359 }
1360 }
1361
1362 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1363 dimension array for it. */
1364
1365 static void
1366 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
1367 {
1368 sese_l region = scop->scop_info->region;
1369 gimple *phi = gsi_stmt (*psi);
1370 tree res = gimple_phi_result (phi);
1371 basic_block bb = gimple_bb (phi);
1372 gimple_stmt_iterator gsi = gsi_after_labels (bb);
1373 tree arg = gimple_phi_arg_def (phi, 0);
1374 gimple *stmt;
1375
1376 /* Note that loop close phi nodes should have a single argument
1377 because we translated the representation into a canonical form
1378 before Graphite: see canonicalize_loop_closed_ssa_form. */
1379 gcc_assert (gimple_phi_num_args (phi) == 1);
1380
1381 /* The phi node can be a non close phi node, when its argument is
1382 invariant, or a default definition. */
1383 if (is_gimple_min_invariant (arg)
1384 || SSA_NAME_IS_DEFAULT_DEF (arg))
1385 {
1386 propagate_expr_outside_region (res, arg, region);
1387 gsi_next (psi);
1388 return;
1389 }
1390
1391 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
1392 {
1393 propagate_expr_outside_region (res, arg, region);
1394 stmt = gimple_build_assign (res, arg);
1395 remove_phi_node (psi, false);
1396 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1397 return;
1398 }
1399
1400 /* If res is scev analyzable and is not a scalar value, it is safe
1401 to ignore the close phi node: it will be code generated in the
1402 out of Graphite pass. */
1403 else if (scev_analyzable_p (res, region))
1404 {
1405 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
1406 tree scev;
1407
1408 if (!loop_in_sese_p (loop, region))
1409 {
1410 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
1411 scev = scalar_evolution_in_region (region, loop, arg);
1412 scev = compute_overall_effect_of_inner_loop (loop, scev);
1413 }
1414 else
1415 scev = scalar_evolution_in_region (region, loop, res);
1416
1417 if (tree_does_not_contain_chrecs (scev))
1418 propagate_expr_outside_region (res, scev, region);
1419
1420 gsi_next (psi);
1421 return;
1422 }
1423 else
1424 {
1425 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
1426
1427 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
1428
1429 if (TREE_CODE (arg) == SSA_NAME)
1430 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
1431 SSA_NAME_DEF_STMT (arg));
1432 else
1433 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
1434 zero_dim_array, arg);
1435 }
1436
1437 remove_phi_node (psi, false);
1438 SSA_NAME_DEF_STMT (res) = stmt;
1439
1440 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
1441 }
1442
1443 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
1444 dimension array for it. */
1445
1446 static void
1447 rewrite_phi_out_of_ssa (scop_p scop, gphi_iterator *psi)
1448 {
1449 gphi *phi = psi->phi ();
1450 basic_block bb = gimple_bb (phi);
1451 tree res = gimple_phi_result (phi);
1452 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
1453
1454 for (size_t i = 0; i < gimple_phi_num_args (phi); i++)
1455 {
1456 tree arg = gimple_phi_arg_def (phi, i);
1457 edge e = gimple_phi_arg_edge (phi, i);
1458
1459 /* Avoid the insertion of code in the loop latch to please the
1460 pattern matching of the vectorizer. */
1461 if (TREE_CODE (arg) == SSA_NAME
1462 && !SSA_NAME_IS_DEFAULT_DEF (arg)
1463 && e->src == bb->loop_father->latch)
1464 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
1465 SSA_NAME_DEF_STMT (arg));
1466 else
1467 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
1468 }
1469
1470 gimple *stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
1471 remove_phi_node (psi, false);
1472 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
1473 }
1474
1475 /* Rewrite the degenerate phi node at position PSI from the degenerate
1476 form "x = phi (y, y, ..., y)" to "x = y". */
1477
1478 static void
1479 rewrite_degenerate_phi (gphi_iterator *psi)
1480 {
1481 gphi *phi = psi->phi ();
1482 tree res = gimple_phi_result (phi);
1483
1484 basic_block bb = gimple_bb (phi);
1485 tree rhs = degenerate_phi_result (phi);
1486 gcc_assert (rhs);
1487
1488 gimple *stmt = gimple_build_assign (res, rhs);
1489 remove_phi_node (psi, false);
1490
1491 gimple_stmt_iterator gsi = gsi_after_labels (bb);
1492 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
1493 }
1494
1495 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
1496
1497 static void
1498 rewrite_reductions_out_of_ssa (scop_p scop)
1499 {
1500 int i;
1501 basic_block bb;
1502 FOR_EACH_VEC_ELT (scop->scop_info->bbs, i, bb)
1503 for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);)
1504 {
1505 gphi *phi = psi.phi ();
1506
1507 if (virtual_operand_p (gimple_phi_result (phi)))
1508 {
1509 gsi_next (&psi);
1510 continue;
1511 }
1512
1513 if (gimple_phi_num_args (phi) > 1
1514 && degenerate_phi_result (phi))
1515 rewrite_degenerate_phi (&psi);
1516
1517 else if (scalar_close_phi_node_p (phi))
1518 rewrite_close_phi_out_of_ssa (scop, &psi);
1519
1520 else if (reduction_phi_p (scop->scop_info->region, &psi))
1521 rewrite_phi_out_of_ssa (scop, &psi);
1522 }
1523
1524 update_ssa (TODO_update_ssa);
1525 #ifdef ENABLE_CHECKING
1526 verify_loop_closed_ssa (true);
1527 #endif
1528 }
1529
1530 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
1531 read from ZERO_DIM_ARRAY. */
1532
1533 static void
1534 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
1535 tree def, gimple *use_stmt)
1536 {
1537 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
1538
1539 tree name = copy_ssa_name (def);
1540 gimple *name_stmt = gimple_build_assign (name, zero_dim_array);
1541
1542 gimple_assign_set_lhs (name_stmt, name);
1543 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
1544
1545 ssa_op_iter iter;
1546 use_operand_p use_p;
1547 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
1548 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
1549 replace_exp (use_p, name);
1550
1551 update_stmt (use_stmt);
1552 }
1553
1554 /* For every definition DEF in the SCOP that is used outside the scop,
1555 insert a closing-scop definition in the basic block just after this
1556 SCOP. */
1557
1558 static void
1559 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple *stmt)
1560 {
1561 tree var = create_tmp_reg (TREE_TYPE (def));
1562 tree new_name = make_ssa_name (var, stmt);
1563 bool needs_copy = false;
1564 sese_l region = scop->scop_info->region;
1565
1566 imm_use_iterator imm_iter;
1567 gimple *use_stmt;
1568 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1569 {
1570 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
1571 {
1572 use_operand_p use_p;
1573 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1574 {
1575 SET_USE (use_p, new_name);
1576 }
1577 update_stmt (use_stmt);
1578 needs_copy = true;
1579 }
1580 }
1581
1582 /* Insert in the empty BB just after the scop a use of DEF such
1583 that the rewrite of cross_bb_scalar_dependences won't insert
1584 arrays everywhere else. */
1585 if (needs_copy)
1586 {
1587 gimple *assign = gimple_build_assign (new_name, def);
1588 gimple_stmt_iterator psi = gsi_after_labels (region.exit->dest);
1589
1590 update_stmt (assign);
1591 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
1592 }
1593 }
1594
1595 /* Rewrite the scalar dependences crossing the boundary of the BB
1596 containing STMT with an array. Return true when something has been
1597 changed. */
1598
1599 static bool
1600 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
1601 {
1602 sese_l region = scop->scop_info->region;
1603 gimple *stmt = gsi_stmt (*gsi);
1604 imm_use_iterator imm_iter;
1605 tree def;
1606 tree zero_dim_array = NULL_TREE;
1607 gimple *use_stmt;
1608 bool res = false;
1609
1610 switch (gimple_code (stmt))
1611 {
1612 case GIMPLE_ASSIGN:
1613 def = gimple_assign_lhs (stmt);
1614 break;
1615
1616 case GIMPLE_CALL:
1617 def = gimple_call_lhs (stmt);
1618 break;
1619
1620 default:
1621 return false;
1622 }
1623
1624 if (!def
1625 || !is_gimple_reg (def))
1626 return false;
1627
1628 if (scev_analyzable_p (def, region))
1629 {
1630 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
1631 tree scev = scalar_evolution_in_region (region, loop, def);
1632
1633 if (tree_contains_chrecs (scev, NULL))
1634 return false;
1635
1636 propagate_expr_outside_region (def, scev, region);
1637 return true;
1638 }
1639
1640 basic_block def_bb = gimple_bb (stmt);
1641
1642 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
1643
1644 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1645 if (gphi *phi = dyn_cast <gphi *> (use_stmt))
1646 {
1647 res = true;
1648 gphi_iterator psi = gsi_for_phi (phi);
1649
1650 if (scalar_close_phi_node_p (gsi_stmt (psi)))
1651 rewrite_close_phi_out_of_ssa (scop, &psi);
1652 else
1653 rewrite_phi_out_of_ssa (scop, &psi);
1654 }
1655
1656 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
1657 if (gimple_code (use_stmt) != GIMPLE_PHI
1658 && def_bb != gimple_bb (use_stmt)
1659 && !is_gimple_debug (use_stmt)
1660 && (res = true))
1661 {
1662 if (!zero_dim_array)
1663 {
1664 zero_dim_array = create_zero_dim_array
1665 (def, "Cross_BB_scalar_dependence");
1666 insert_out_of_ssa_copy (scop, zero_dim_array, def,
1667 SSA_NAME_DEF_STMT (def));
1668 gsi_next (gsi);
1669 }
1670
1671 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
1672 def, use_stmt);
1673 }
1674
1675 update_ssa (TODO_update_ssa);
1676
1677 return res;
1678 }
1679
1680 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
1681
1682 static void
1683 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
1684 {
1685 gimple_stmt_iterator psi;
1686 sese_l region = scop->scop_info->region;
1687 bool changed = false;
1688
1689 /* Create an extra empty BB after the scop. */
1690 split_edge (region.exit);
1691
1692 int i;
1693 basic_block bb;
1694 FOR_EACH_VEC_ELT (scop->scop_info->bbs, i, bb)
1695 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
1696 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
1697
1698 if (changed)
1699 {
1700 scev_reset_htab ();
1701 update_ssa (TODO_update_ssa);
1702 #ifdef ENABLE_CHECKING
1703 verify_loop_closed_ssa (true);
1704 #endif
1705 }
1706 }
1707
1708 /* Builds the polyhedral representation for a SESE region. */
1709
1710 void
1711 build_poly_scop (scop_p scop)
1712 {
1713 set_scop_parameter_dim (scop);
1714 build_scop_iteration_domain (scop);
1715 build_scop_context (scop);
1716 add_conditions_to_constraints (scop);
1717
1718 /* Rewrite out of SSA only after having translated the
1719 representation to the polyhedral representation to avoid scev
1720 analysis failures. That means that these functions will insert
1721 new data references that they create in the right place. */
1722 rewrite_reductions_out_of_ssa (scop);
1723 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
1724
1725 build_scop_drs (scop);
1726 build_scop_scattering (scop);
1727
1728 /* This SCoP has been translated to the polyhedral
1729 representation. */
1730 scop->poly_scop_p = true;
1731 }
1732 #endif /* HAVE_isl */