PR tree-optimization/66718
[official-gcc.git] / gcc / graphite-sese-to-poly.c
blob91955929344702aa058b5b4efc16ef5b0ad97009
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>.
5 This file is part of GCC.
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.
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.
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/>. */
21 #include "config.h"
23 #ifdef HAVE_isl
24 /* Workaround for GMP 5.1.3 bug, see PR56019. */
25 #include <stddef.h>
27 #include <isl/set.h>
28 #include <isl/map.h>
29 #include <isl/union_map.h>
30 #include <isl/constraint.h>
31 #include <isl/aff.h>
32 #include <isl/val.h>
34 /* Since ISL-0.13, the extern is in val_gmp.h. */
35 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
36 extern "C" {
37 #endif
38 #include <isl/val_gmp.h>
39 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
41 #endif
42 #endif
44 #include "system.h"
45 #include "coretypes.h"
46 #include "alias.h"
47 #include "backend.h"
48 #include "tree.h"
49 #include "gimple.h"
50 #include "rtl.h"
51 #include "ssa.h"
52 #include "options.h"
53 #include "fold-const.h"
54 #include "internal-fn.h"
55 #include "gimple-iterator.h"
56 #include "gimplify.h"
57 #include "gimplify-me.h"
58 #include "tree-cfg.h"
59 #include "tree-ssa-loop-manip.h"
60 #include "tree-ssa-loop-niter.h"
61 #include "tree-ssa-loop.h"
62 #include "tree-into-ssa.h"
63 #include "tree-pass.h"
64 #include "cfgloop.h"
65 #include "tree-chrec.h"
66 #include "tree-data-ref.h"
67 #include "tree-scalar-evolution.h"
68 #include "domwalk.h"
69 #include "sese.h"
70 #include "tree-ssa-propagate.h"
72 #ifdef HAVE_isl
73 #include "flags.h"
74 #include "insn-config.h"
75 #include "expmed.h"
76 #include "dojump.h"
77 #include "explow.h"
78 #include "calls.h"
79 #include "emit-rtl.h"
80 #include "varasm.h"
81 #include "stmt.h"
82 #include "expr.h"
83 #include "graphite-poly.h"
84 #include "graphite-sese-to-poly.h"
87 /* Assigns to RES the value of the INTEGER_CST T. */
89 static inline void
90 tree_int_to_gmp (tree t, mpz_t res)
92 wi::to_mpz (t, res, TYPE_SIGN (TREE_TYPE (t)));
95 /* Returns the index of the PHI argument defined in the outermost
96 loop. */
98 static size_t
99 phi_arg_in_outermost_loop (gphi *phi)
101 loop_p loop = gimple_bb (phi)->loop_father;
102 size_t i, res = 0;
104 for (i = 0; i < gimple_phi_num_args (phi); i++)
105 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
107 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
108 res = i;
111 return res;
114 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
115 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
117 static void
118 remove_simple_copy_phi (gphi_iterator *psi)
120 gphi *phi = psi->phi ();
121 tree res = gimple_phi_result (phi);
122 size_t entry = phi_arg_in_outermost_loop (phi);
123 tree init = gimple_phi_arg_def (phi, entry);
124 gassign *stmt = gimple_build_assign (res, init);
125 edge e = gimple_phi_arg_edge (phi, entry);
127 remove_phi_node (psi, false);
128 gsi_insert_on_edge_immediate (e, stmt);
131 /* Removes an invariant phi node at position PSI by inserting on the
132 loop ENTRY edge the assignment RES = INIT. */
134 static void
135 remove_invariant_phi (sese region, gphi_iterator *psi)
137 gphi *phi = psi->phi ();
138 loop_p loop = loop_containing_stmt (phi);
139 tree res = gimple_phi_result (phi);
140 tree scev = scalar_evolution_in_region (region, loop, res);
141 size_t entry = phi_arg_in_outermost_loop (phi);
142 edge e = gimple_phi_arg_edge (phi, entry);
143 tree var;
144 gassign *stmt;
145 gimple_seq stmts = NULL;
147 if (tree_contains_chrecs (scev, NULL))
148 scev = gimple_phi_arg_def (phi, entry);
150 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
151 stmt = gimple_build_assign (res, var);
152 remove_phi_node (psi, false);
154 gimple_seq_add_stmt (&stmts, stmt);
155 gsi_insert_seq_on_edge (e, stmts);
156 gsi_commit_edge_inserts ();
157 SSA_NAME_DEF_STMT (res) = stmt;
160 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
162 static inline bool
163 simple_copy_phi_p (gphi *phi)
165 tree res;
167 if (gimple_phi_num_args (phi) != 2)
168 return false;
170 res = gimple_phi_result (phi);
171 return (res == gimple_phi_arg_def (phi, 0)
172 || res == gimple_phi_arg_def (phi, 1));
175 /* Returns true when the phi node at position PSI is a reduction phi
176 node in REGION. Otherwise moves the pointer PSI to the next phi to
177 be considered. */
179 static bool
180 reduction_phi_p (sese region, gphi_iterator *psi)
182 loop_p loop;
183 gphi *phi = psi->phi ();
184 tree res = gimple_phi_result (phi);
186 loop = loop_containing_stmt (phi);
188 if (simple_copy_phi_p (phi))
190 /* PRE introduces phi nodes like these, for an example,
191 see id-5.f in the fortran graphite testsuite:
193 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
195 remove_simple_copy_phi (psi);
196 return false;
199 if (scev_analyzable_p (res, region))
201 tree scev = scalar_evolution_in_region (region, loop, res);
203 if (evolution_function_is_invariant_p (scev, loop->num))
204 remove_invariant_phi (region, psi);
205 else
206 gsi_next (psi);
208 return false;
211 /* All the other cases are considered reductions. */
212 return true;
215 /* Store the GRAPHITE representation of BB. */
217 static gimple_bb_p
218 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
220 struct gimple_bb *gbb;
222 gbb = XNEW (struct gimple_bb);
223 bb->aux = gbb;
224 GBB_BB (gbb) = bb;
225 GBB_DATA_REFS (gbb) = drs;
226 GBB_CONDITIONS (gbb).create (0);
227 GBB_CONDITION_CASES (gbb).create (0);
229 return gbb;
232 static void
233 free_data_refs_aux (vec<data_reference_p> datarefs)
235 unsigned int i;
236 struct data_reference *dr;
238 FOR_EACH_VEC_ELT (datarefs, i, dr)
239 if (dr->aux)
241 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
243 free (bap->alias_set);
245 free (bap);
246 dr->aux = NULL;
249 /* Frees GBB. */
251 static void
252 free_gimple_bb (struct gimple_bb *gbb)
254 free_data_refs_aux (GBB_DATA_REFS (gbb));
255 free_data_refs (GBB_DATA_REFS (gbb));
257 GBB_CONDITIONS (gbb).release ();
258 GBB_CONDITION_CASES (gbb).release ();
259 GBB_BB (gbb)->aux = 0;
260 XDELETE (gbb);
263 /* Deletes all gimple bbs in SCOP. */
265 static void
266 remove_gbbs_in_scop (scop_p scop)
268 int i;
269 poly_bb_p pbb;
271 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
272 free_gimple_bb (PBB_BLACK_BOX (pbb));
275 /* Deletes all scops in SCOPS. */
277 void
278 free_scops (vec<scop_p> scops)
280 int i;
281 scop_p scop;
283 FOR_EACH_VEC_ELT (scops, i, scop)
285 remove_gbbs_in_scop (scop);
286 free_sese (SCOP_REGION (scop));
287 free_scop (scop);
290 scops.release ();
293 /* Same as outermost_loop_in_sese, returns the outermost loop
294 containing BB in REGION, but makes sure that the returned loop
295 belongs to the REGION, and so this returns the first loop in the
296 REGION when the loop containing BB does not belong to REGION. */
298 static loop_p
299 outermost_loop_in_sese_1 (sese region, basic_block bb)
301 loop_p nest = outermost_loop_in_sese (region, bb);
303 if (loop_in_sese_p (nest, region))
304 return nest;
306 /* When the basic block BB does not belong to a loop in the region,
307 return the first loop in the region. */
308 nest = nest->inner;
309 while (nest)
310 if (loop_in_sese_p (nest, region))
311 break;
312 else
313 nest = nest->next;
315 gcc_assert (nest);
316 return nest;
319 /* Generates a polyhedral black box only if the bb contains interesting
320 information. */
322 static gimple_bb_p
323 try_generate_gimple_bb (scop_p scop, basic_block bb)
325 vec<data_reference_p> drs;
326 drs.create (5);
327 sese region = SCOP_REGION (scop);
328 loop_p nest = outermost_loop_in_sese_1 (region, bb);
329 gimple_stmt_iterator gsi;
331 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
333 gimple stmt = gsi_stmt (gsi);
334 loop_p loop;
336 if (is_gimple_debug (stmt))
337 continue;
339 loop = loop_containing_stmt (stmt);
340 if (!loop_in_sese_p (loop, region))
341 loop = nest;
343 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
346 return new_gimple_bb (bb, drs);
349 /* Returns true if all predecessors of BB, that are not dominated by BB, are
350 marked in MAP. The predecessors dominated by BB are loop latches and will
351 be handled after BB. */
353 static bool
354 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
356 edge e;
357 edge_iterator ei;
359 FOR_EACH_EDGE (e, ei, bb->preds)
360 if (!bitmap_bit_p (map, e->src->index)
361 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
362 return false;
364 return true;
367 /* Compare the depth of two basic_block's P1 and P2. */
369 static int
370 compare_bb_depths (const void *p1, const void *p2)
372 const_basic_block const bb1 = *(const_basic_block const*)p1;
373 const_basic_block const bb2 = *(const_basic_block const*)p2;
374 int d1 = loop_depth (bb1->loop_father);
375 int d2 = loop_depth (bb2->loop_father);
377 if (d1 < d2)
378 return 1;
380 if (d1 > d2)
381 return -1;
383 return 0;
386 /* Sort the basic blocks from DOM such that the first are the ones at
387 a deepest loop level. */
389 static void
390 graphite_sort_dominated_info (vec<basic_block> dom)
392 dom.qsort (compare_bb_depths);
395 /* Recursive helper function for build_scops_bbs. */
397 static void
398 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
400 sese region = SCOP_REGION (scop);
401 vec<basic_block> dom;
402 poly_bb_p pbb;
404 if (bitmap_bit_p (visited, bb->index)
405 || !bb_in_sese_p (bb, region))
406 return;
408 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
409 SCOP_BBS (scop).safe_push (pbb);
410 bitmap_set_bit (visited, bb->index);
412 dom = get_dominated_by (CDI_DOMINATORS, bb);
414 if (!dom.exists ())
415 return;
417 graphite_sort_dominated_info (dom);
419 while (!dom.is_empty ())
421 int i;
422 basic_block dom_bb;
424 FOR_EACH_VEC_ELT (dom, i, dom_bb)
425 if (all_non_dominated_preds_marked_p (dom_bb, visited))
427 build_scop_bbs_1 (scop, visited, dom_bb);
428 dom.unordered_remove (i);
429 break;
433 dom.release ();
436 /* Gather the basic blocks belonging to the SCOP. */
438 static void
439 build_scop_bbs (scop_p scop)
441 sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
442 sese region = SCOP_REGION (scop);
444 bitmap_clear (visited);
445 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
446 sbitmap_free (visited);
449 /* Return an ISL identifier for the polyhedral basic block PBB. */
451 static isl_id *
452 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
454 char name[50];
455 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
456 return isl_id_alloc (s->ctx, name, pbb);
459 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
460 We generate SCATTERING_DIMENSIONS scattering dimensions.
462 CLooG 0.15.0 and previous versions require, that all
463 scattering functions of one CloogProgram have the same number of
464 scattering dimensions, therefore we allow to specify it. This
465 should be removed in future versions of CLooG.
467 The scattering polyhedron consists of these dimensions: scattering,
468 loop_iterators, parameters.
470 Example:
472 | scattering_dimensions = 5
473 | used_scattering_dimensions = 3
474 | nb_iterators = 1
475 | scop_nb_params = 2
477 | Schedule:
479 | 4 5
481 | Scattering polyhedron:
483 | scattering: {s1, s2, s3, s4, s5}
484 | loop_iterators: {i}
485 | parameters: {p1, p2}
487 | s1 s2 s3 s4 s5 i p1 p2 1
488 | 1 0 0 0 0 0 0 0 -4 = 0
489 | 0 1 0 0 0 -1 0 0 0 = 0
490 | 0 0 1 0 0 0 0 0 -5 = 0 */
492 static void
493 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
494 poly_bb_p pbb, int scattering_dimensions)
496 int i;
497 int nb_iterators = pbb_dim_iter_domain (pbb);
498 int used_scattering_dimensions = nb_iterators * 2 + 1;
499 isl_val *val;
500 isl_space *dc, *dm;
502 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
504 dc = isl_set_get_space (pbb->domain);
505 dm = isl_space_add_dims (isl_space_from_domain (dc),
506 isl_dim_out, scattering_dimensions);
507 pbb->schedule = isl_map_universe (dm);
509 for (i = 0; i < scattering_dimensions; i++)
511 /* Textual order inside this loop. */
512 if ((i % 2) == 0)
514 isl_constraint *c = isl_equality_alloc
515 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
517 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
519 val = isl_val_neg (val);
520 c = isl_constraint_set_constant_val (c, val);
521 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
522 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
525 /* Iterations of this loop. */
526 else /* if ((i % 2) == 1) */
528 int loop = (i - 1) / 2;
529 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
530 isl_dim_out, i);
534 pbb->transformed = isl_map_copy (pbb->schedule);
537 /* Build for BB the static schedule.
539 The static schedule is a Dewey numbering of the abstract syntax
540 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
542 The following example informally defines the static schedule:
545 for (i: ...)
547 for (j: ...)
553 for (k: ...)
561 Static schedules for A to F:
563 DEPTH
564 0 1 2
566 B 1 0 0
567 C 1 0 1
568 D 1 1 0
569 E 1 1 1
573 static void
574 build_scop_scattering (scop_p scop)
576 int i;
577 poly_bb_p pbb;
578 gimple_bb_p previous_gbb = NULL;
579 isl_space *dc = isl_set_get_space (scop->context);
580 isl_aff *static_sched;
582 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
583 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
585 /* We have to start schedules at 0 on the first component and
586 because we cannot compare_prefix_loops against a previous loop,
587 prefix will be equal to zero, and that index will be
588 incremented before copying. */
589 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
591 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
593 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
594 int prefix;
595 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
597 if (previous_gbb)
598 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
599 else
600 prefix = 0;
602 previous_gbb = gbb;
604 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
605 prefix, 1);
606 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
609 isl_aff_free (static_sched);
612 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
614 /* Extract an affine expression from the chain of recurrence E. */
616 static isl_pw_aff *
617 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
619 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
620 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
621 isl_local_space *ls = isl_local_space_from_space (space);
622 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
623 isl_aff *loop = isl_aff_set_coefficient_si
624 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
625 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
627 /* Before multiplying, make sure that the result is affine. */
628 gcc_assert (isl_pw_aff_is_cst (rhs)
629 || isl_pw_aff_is_cst (l));
631 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
634 /* Extract an affine expression from the mult_expr E. */
636 static isl_pw_aff *
637 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
639 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
640 isl_space_copy (space));
641 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
643 if (!isl_pw_aff_is_cst (lhs)
644 && !isl_pw_aff_is_cst (rhs))
646 isl_pw_aff_free (lhs);
647 isl_pw_aff_free (rhs);
648 return NULL;
651 return isl_pw_aff_mul (lhs, rhs);
654 /* Return an ISL identifier from the name of the ssa_name E. */
656 static isl_id *
657 isl_id_for_ssa_name (scop_p s, tree e)
659 const char *name = get_name (e);
660 isl_id *id;
662 if (name)
663 id = isl_id_alloc (s->ctx, name, e);
664 else
666 char name1[50];
667 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
668 id = isl_id_alloc (s->ctx, name1, e);
671 return id;
674 /* Return an ISL identifier for the data reference DR. */
676 static isl_id *
677 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
679 /* Data references all get the same isl_id. They need to be comparable
680 and are distinguished through the first dimension, which contains the
681 alias set number. */
682 return isl_id_alloc (s->ctx, "", 0);
685 /* Extract an affine expression from the ssa_name E. */
687 static isl_pw_aff *
688 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
690 isl_aff *aff;
691 isl_set *dom;
692 isl_id *id;
693 int dimension;
695 id = isl_id_for_ssa_name (s, e);
696 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
697 isl_id_free (id);
698 dom = isl_set_universe (isl_space_copy (space));
699 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
700 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
701 return isl_pw_aff_alloc (dom, aff);
704 /* Extract an affine expression from the gmp constant G. */
706 static isl_pw_aff *
707 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
709 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
710 isl_aff *aff = isl_aff_zero_on_domain (ls);
711 isl_set *dom = isl_set_universe (space);
712 isl_val *v;
713 isl_ctx *ct;
715 ct = isl_aff_get_ctx (aff);
716 v = isl_val_int_from_gmp (ct, g);
717 aff = isl_aff_add_constant_val (aff, v);
719 return isl_pw_aff_alloc (dom, aff);
722 /* Extract an affine expression from the integer_cst E. */
724 static isl_pw_aff *
725 extract_affine_int (tree e, __isl_take isl_space *space)
727 isl_pw_aff *res;
728 mpz_t g;
730 mpz_init (g);
731 tree_int_to_gmp (e, g);
732 res = extract_affine_gmp (g, space);
733 mpz_clear (g);
735 return res;
738 /* Compute pwaff mod 2^width. */
740 extern isl_ctx *the_isl_ctx;
742 static isl_pw_aff *
743 wrap (isl_pw_aff *pwaff, unsigned width)
745 isl_val *mod;
747 mod = isl_val_int_from_ui(the_isl_ctx, width);
748 mod = isl_val_2exp (mod);
749 pwaff = isl_pw_aff_mod_val (pwaff, mod);
751 return pwaff;
754 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
755 Otherwise returns -1. */
757 static inline int
758 parameter_index_in_region_1 (tree name, sese region)
760 int i;
761 tree p;
763 gcc_assert (TREE_CODE (name) == SSA_NAME);
765 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
766 if (p == name)
767 return i;
769 return -1;
772 /* When the parameter NAME is in REGION, returns its index in
773 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
774 and returns the index of NAME. */
776 static int
777 parameter_index_in_region (tree name, sese region)
779 int i;
781 gcc_assert (TREE_CODE (name) == SSA_NAME);
783 i = parameter_index_in_region_1 (name, region);
784 if (i != -1)
785 return i;
787 gcc_assert (SESE_ADD_PARAMS (region));
789 i = SESE_PARAMS (region).length ();
790 SESE_PARAMS (region).safe_push (name);
791 return i;
794 /* Extract an affine expression from the tree E in the scop S. */
796 static isl_pw_aff *
797 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
799 isl_pw_aff *lhs, *rhs, *res;
800 tree type;
802 if (e == chrec_dont_know) {
803 isl_space_free (space);
804 return NULL;
807 switch (TREE_CODE (e))
809 case POLYNOMIAL_CHREC:
810 res = extract_affine_chrec (s, e, space);
811 break;
813 case MULT_EXPR:
814 res = extract_affine_mul (s, e, space);
815 break;
817 case PLUS_EXPR:
818 case POINTER_PLUS_EXPR:
819 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
820 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
821 res = isl_pw_aff_add (lhs, rhs);
822 break;
824 case MINUS_EXPR:
825 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
826 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
827 res = isl_pw_aff_sub (lhs, rhs);
828 break;
830 case NEGATE_EXPR:
831 case BIT_NOT_EXPR:
832 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
833 rhs = extract_affine (s, integer_minus_one_node, space);
834 res = isl_pw_aff_mul (lhs, rhs);
835 break;
837 case SSA_NAME:
838 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
839 res = extract_affine_name (s, e, space);
840 break;
842 case INTEGER_CST:
843 res = extract_affine_int (e, space);
844 /* No need to wrap a single integer. */
845 return res;
847 CASE_CONVERT:
848 case NON_LVALUE_EXPR:
849 res = extract_affine (s, TREE_OPERAND (e, 0), space);
850 break;
852 default:
853 gcc_unreachable ();
854 break;
857 type = TREE_TYPE (e);
858 if (TYPE_UNSIGNED (type))
859 res = wrap (res, TYPE_PRECISION (type));
861 return res;
864 /* In the context of sese S, scan the expression E and translate it to
865 a linear expression C. When parsing a symbolic multiplication, K
866 represents the constant multiplier of an expression containing
867 parameters. */
869 static void
870 scan_tree_for_params (sese s, tree e)
872 if (e == chrec_dont_know)
873 return;
875 switch (TREE_CODE (e))
877 case POLYNOMIAL_CHREC:
878 scan_tree_for_params (s, CHREC_LEFT (e));
879 break;
881 case MULT_EXPR:
882 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
883 scan_tree_for_params (s, TREE_OPERAND (e, 0));
884 else
885 scan_tree_for_params (s, TREE_OPERAND (e, 1));
886 break;
888 case PLUS_EXPR:
889 case POINTER_PLUS_EXPR:
890 case MINUS_EXPR:
891 scan_tree_for_params (s, TREE_OPERAND (e, 0));
892 scan_tree_for_params (s, TREE_OPERAND (e, 1));
893 break;
895 case NEGATE_EXPR:
896 case BIT_NOT_EXPR:
897 CASE_CONVERT:
898 case NON_LVALUE_EXPR:
899 scan_tree_for_params (s, TREE_OPERAND (e, 0));
900 break;
902 case SSA_NAME:
903 parameter_index_in_region (e, s);
904 break;
906 case INTEGER_CST:
907 case ADDR_EXPR:
908 break;
910 default:
911 gcc_unreachable ();
912 break;
916 /* Find parameters with respect to REGION in BB. We are looking in memory
917 access functions, conditions and loop bounds. */
919 static void
920 find_params_in_bb (sese region, gimple_bb_p gbb)
922 int i;
923 unsigned j;
924 data_reference_p dr;
925 gimple stmt;
926 loop_p loop = GBB_BB (gbb)->loop_father;
928 /* Find parameters in the access functions of data references. */
929 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
930 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
931 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
933 /* Find parameters in conditional statements. */
934 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
936 tree lhs = scalar_evolution_in_region (region, loop,
937 gimple_cond_lhs (stmt));
938 tree rhs = scalar_evolution_in_region (region, loop,
939 gimple_cond_rhs (stmt));
941 scan_tree_for_params (region, lhs);
942 scan_tree_for_params (region, rhs);
946 /* Record the parameters used in the SCOP. A variable is a parameter
947 in a scop if it does not vary during the execution of that scop. */
949 static void
950 find_scop_parameters (scop_p scop)
952 poly_bb_p pbb;
953 unsigned i;
954 sese region = SCOP_REGION (scop);
955 struct loop *loop;
956 int nbp;
958 /* Find the parameters used in the loop bounds. */
959 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
961 tree nb_iters = number_of_latch_executions (loop);
963 if (!chrec_contains_symbols (nb_iters))
964 continue;
966 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
967 scan_tree_for_params (region, nb_iters);
970 /* Find the parameters used in data accesses. */
971 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
972 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
974 nbp = sese_nb_params (region);
975 scop_set_nb_params (scop, nbp);
976 SESE_ADD_PARAMS (region) = false;
979 tree e;
980 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
982 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
983 space = isl_space_set_dim_id (space, isl_dim_param, i,
984 isl_id_for_ssa_name (scop, e));
986 scop->context = isl_set_universe (space);
990 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
991 the constraints for the surrounding loops. */
993 static void
994 build_loop_iteration_domains (scop_p scop, struct loop *loop,
995 int nb,
996 isl_set *outer, isl_set **doms)
998 tree nb_iters = number_of_latch_executions (loop);
999 sese region = SCOP_REGION (scop);
1001 isl_set *inner = isl_set_copy (outer);
1002 isl_space *space;
1003 isl_constraint *c;
1004 int pos = isl_set_dim (outer, isl_dim_set);
1005 isl_val *v;
1006 mpz_t g;
1008 mpz_init (g);
1010 inner = isl_set_add_dims (inner, isl_dim_set, 1);
1011 space = isl_set_get_space (inner);
1013 /* 0 <= loop_i */
1014 c = isl_inequality_alloc
1015 (isl_local_space_from_space (isl_space_copy (space)));
1016 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
1017 inner = isl_set_add_constraint (inner, c);
1019 /* loop_i <= cst_nb_iters */
1020 if (TREE_CODE (nb_iters) == INTEGER_CST)
1022 c = isl_inequality_alloc
1023 (isl_local_space_from_space (isl_space_copy (space)));
1024 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1025 tree_int_to_gmp (nb_iters, g);
1026 v = isl_val_int_from_gmp (the_isl_ctx, g);
1027 c = isl_constraint_set_constant_val (c, v);
1028 inner = isl_set_add_constraint (inner, c);
1031 /* loop_i <= expr_nb_iters */
1032 else if (!chrec_contains_undetermined (nb_iters))
1034 widest_int nit;
1035 isl_pw_aff *aff;
1036 isl_set *valid;
1037 isl_local_space *ls;
1038 isl_aff *al;
1039 isl_set *le;
1041 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1043 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1044 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1045 valid = isl_set_project_out (valid, isl_dim_set, 0,
1046 isl_set_dim (valid, isl_dim_set));
1047 scop->context = isl_set_intersect (scop->context, valid);
1049 ls = isl_local_space_from_space (isl_space_copy (space));
1050 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1051 isl_dim_in, pos, 1);
1052 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1053 isl_pw_aff_copy (aff));
1054 inner = isl_set_intersect (inner, le);
1056 if (max_stmt_executions (loop, &nit))
1058 /* Insert in the context the constraints from the
1059 estimation of the number of iterations NIT and the
1060 symbolic number of iterations (involving parameter
1061 names) NB_ITERS. First, build the affine expression
1062 "NIT - NB_ITERS" and then say that it is positive,
1063 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1064 isl_pw_aff *approx;
1065 mpz_t g;
1066 isl_set *x;
1067 isl_constraint *c;
1069 mpz_init (g);
1070 wi::to_mpz (nit, g, SIGNED);
1071 mpz_sub_ui (g, g, 1);
1072 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1073 x = isl_pw_aff_ge_set (approx, aff);
1074 x = isl_set_project_out (x, isl_dim_set, 0,
1075 isl_set_dim (x, isl_dim_set));
1076 scop->context = isl_set_intersect (scop->context, x);
1078 c = isl_inequality_alloc
1079 (isl_local_space_from_space (isl_space_copy (space)));
1080 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1081 v = isl_val_int_from_gmp (the_isl_ctx, g);
1082 mpz_clear (g);
1083 c = isl_constraint_set_constant_val (c, v);
1084 inner = isl_set_add_constraint (inner, c);
1086 else
1087 isl_pw_aff_free (aff);
1089 else
1090 gcc_unreachable ();
1092 if (loop->inner && loop_in_sese_p (loop->inner, region))
1093 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1094 isl_set_copy (inner), doms);
1096 if (nb != 0
1097 && loop->next
1098 && loop_in_sese_p (loop->next, region))
1099 build_loop_iteration_domains (scop, loop->next, nb,
1100 isl_set_copy (outer), doms);
1102 doms[loop->num] = inner;
1104 isl_set_free (outer);
1105 isl_space_free (space);
1106 mpz_clear (g);
1109 /* Returns a linear expression for tree T evaluated in PBB. */
1111 static isl_pw_aff *
1112 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1114 scop_p scop = PBB_SCOP (pbb);
1116 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1117 gcc_assert (!automatically_generated_chrec_p (t));
1119 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1122 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1123 operator. This allows us to invert the condition or to handle
1124 inequalities. */
1126 static void
1127 add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
1129 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1130 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1131 isl_set *cond;
1133 switch (code)
1135 case LT_EXPR:
1136 cond = isl_pw_aff_lt_set (lhs, rhs);
1137 break;
1139 case GT_EXPR:
1140 cond = isl_pw_aff_gt_set (lhs, rhs);
1141 break;
1143 case LE_EXPR:
1144 cond = isl_pw_aff_le_set (lhs, rhs);
1145 break;
1147 case GE_EXPR:
1148 cond = isl_pw_aff_ge_set (lhs, rhs);
1149 break;
1151 case EQ_EXPR:
1152 cond = isl_pw_aff_eq_set (lhs, rhs);
1153 break;
1155 case NE_EXPR:
1156 cond = isl_pw_aff_ne_set (lhs, rhs);
1157 break;
1159 default:
1160 isl_pw_aff_free (lhs);
1161 isl_pw_aff_free (rhs);
1162 return;
1165 cond = isl_set_coalesce (cond);
1166 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1167 pbb->domain = isl_set_intersect (pbb->domain, cond);
1170 /* Add conditions to the domain of PBB. */
1172 static void
1173 add_conditions_to_domain (poly_bb_p pbb)
1175 unsigned int i;
1176 gimple stmt;
1177 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1179 if (GBB_CONDITIONS (gbb).is_empty ())
1180 return;
1182 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1183 switch (gimple_code (stmt))
1185 case GIMPLE_COND:
1187 gcond *cond_stmt = as_a <gcond *> (stmt);
1188 enum tree_code code = gimple_cond_code (cond_stmt);
1190 /* The conditions for ELSE-branches are inverted. */
1191 if (!GBB_CONDITION_CASES (gbb)[i])
1192 code = invert_tree_comparison (code, false);
1194 add_condition_to_pbb (pbb, cond_stmt, code);
1195 break;
1198 case GIMPLE_SWITCH:
1199 /* Switch statements are not supported right now - fall through. */
1201 default:
1202 gcc_unreachable ();
1203 break;
1207 /* Traverses all the GBBs of the SCOP and add their constraints to the
1208 iteration domains. */
1210 static void
1211 add_conditions_to_constraints (scop_p scop)
1213 int i;
1214 poly_bb_p pbb;
1216 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1217 add_conditions_to_domain (pbb);
1220 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1221 edge between BB and its predecessor is not a loop exit edge, and
1222 the last statement of the single predecessor is a COND_EXPR. */
1224 static gcond *
1225 single_pred_cond_non_loop_exit (basic_block bb)
1227 if (single_pred_p (bb))
1229 edge e = single_pred_edge (bb);
1230 basic_block pred = e->src;
1231 gimple stmt;
1233 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1234 return NULL;
1236 stmt = last_stmt (pred);
1238 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1239 return as_a <gcond *> (stmt);
1242 return NULL;
1245 class sese_dom_walker : public dom_walker
1247 public:
1248 sese_dom_walker (cdi_direction, sese);
1250 virtual void before_dom_children (basic_block);
1251 virtual void after_dom_children (basic_block);
1253 private:
1254 auto_vec<gimple, 3> m_conditions, m_cases;
1255 sese m_region;
1258 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1259 : dom_walker (direction), m_region (region)
1263 /* Call-back for dom_walk executed before visiting the dominated
1264 blocks. */
1266 void
1267 sese_dom_walker::before_dom_children (basic_block bb)
1269 gimple_bb_p gbb;
1270 gcond *stmt;
1272 if (!bb_in_sese_p (bb, m_region))
1273 return;
1275 stmt = single_pred_cond_non_loop_exit (bb);
1277 if (stmt)
1279 edge e = single_pred_edge (bb);
1281 m_conditions.safe_push (stmt);
1283 if (e->flags & EDGE_TRUE_VALUE)
1284 m_cases.safe_push (stmt);
1285 else
1286 m_cases.safe_push (NULL);
1289 gbb = gbb_from_bb (bb);
1291 if (gbb)
1293 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1294 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1298 /* Call-back for dom_walk executed after visiting the dominated
1299 blocks. */
1301 void
1302 sese_dom_walker::after_dom_children (basic_block bb)
1304 if (!bb_in_sese_p (bb, m_region))
1305 return;
1307 if (single_pred_cond_non_loop_exit (bb))
1309 m_conditions.pop ();
1310 m_cases.pop ();
1314 /* Add constraints on the possible values of parameter P from the type
1315 of P. */
1317 static void
1318 add_param_constraints (scop_p scop, graphite_dim_t p)
1320 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1321 tree type = TREE_TYPE (parameter);
1322 tree lb = NULL_TREE;
1323 tree ub = NULL_TREE;
1325 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1326 lb = lower_bound_in_type (type, type);
1327 else
1328 lb = TYPE_MIN_VALUE (type);
1330 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1331 ub = upper_bound_in_type (type, type);
1332 else
1333 ub = TYPE_MAX_VALUE (type);
1335 if (lb)
1337 isl_space *space = isl_set_get_space (scop->context);
1338 isl_constraint *c;
1339 mpz_t g;
1340 isl_val *v;
1342 c = isl_inequality_alloc (isl_local_space_from_space (space));
1343 mpz_init (g);
1344 tree_int_to_gmp (lb, g);
1345 v = isl_val_int_from_gmp (the_isl_ctx, g);
1346 v = isl_val_neg (v);
1347 mpz_clear (g);
1348 c = isl_constraint_set_constant_val (c, v);
1349 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1351 scop->context = isl_set_add_constraint (scop->context, c);
1354 if (ub)
1356 isl_space *space = isl_set_get_space (scop->context);
1357 isl_constraint *c;
1358 mpz_t g;
1359 isl_val *v;
1361 c = isl_inequality_alloc (isl_local_space_from_space (space));
1363 mpz_init (g);
1364 tree_int_to_gmp (ub, g);
1365 v = isl_val_int_from_gmp (the_isl_ctx, g);
1366 mpz_clear (g);
1367 c = isl_constraint_set_constant_val (c, v);
1368 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1370 scop->context = isl_set_add_constraint (scop->context, c);
1374 /* Build the context of the SCOP. The context usually contains extra
1375 constraints that are added to the iteration domains that constrain
1376 some parameters. */
1378 static void
1379 build_scop_context (scop_p scop)
1381 graphite_dim_t p, n = scop_nb_params (scop);
1383 for (p = 0; p < n; p++)
1384 add_param_constraints (scop, p);
1387 /* Build the iteration domains: the loops belonging to the current
1388 SCOP, and that vary for the execution of the current basic block.
1389 Returns false if there is no loop in SCOP. */
1391 static void
1392 build_scop_iteration_domain (scop_p scop)
1394 struct loop *loop;
1395 sese region = SCOP_REGION (scop);
1396 int i;
1397 poly_bb_p pbb;
1398 int nb_loops = number_of_loops (cfun);
1399 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1401 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1402 if (!loop_in_sese_p (loop_outer (loop), region))
1403 build_loop_iteration_domains (scop, loop, 0,
1404 isl_set_copy (scop->context), doms);
1406 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1408 loop = pbb_loop (pbb);
1410 if (doms[loop->num])
1411 pbb->domain = isl_set_copy (doms[loop->num]);
1412 else
1413 pbb->domain = isl_set_copy (scop->context);
1415 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1416 isl_id_for_pbb (scop, pbb));
1419 for (i = 0; i < nb_loops; i++)
1420 if (doms[i])
1421 isl_set_free (doms[i]);
1423 free (doms);
1426 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1427 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1428 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1429 domain. */
1431 static isl_map *
1432 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1434 isl_constraint *c;
1435 int alias_set_num = 0;
1436 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1438 if (bap && bap->alias_set)
1439 alias_set_num = *(bap->alias_set);
1441 c = isl_equality_alloc
1442 (isl_local_space_from_space (isl_map_get_space (acc)));
1443 c = isl_constraint_set_constant_si (c, -alias_set_num);
1444 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1446 return isl_map_add_constraint (acc, c);
1449 /* Assign the affine expression INDEX to the output dimension POS of
1450 MAP and return the result. */
1452 static isl_map *
1453 set_index (isl_map *map, int pos, isl_pw_aff *index)
1455 isl_map *index_map;
1456 int len = isl_map_dim (map, isl_dim_out);
1457 isl_id *id;
1459 index_map = isl_map_from_pw_aff (index);
1460 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1461 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1463 id = isl_map_get_tuple_id (map, isl_dim_out);
1464 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1465 id = isl_map_get_tuple_id (map, isl_dim_in);
1466 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1468 return isl_map_intersect (map, index_map);
1471 /* Add to ACCESSES polyhedron equalities defining the access functions
1472 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1473 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1474 PBB is the poly_bb_p that contains the data reference DR. */
1476 static isl_map *
1477 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1479 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1480 scop_p scop = PBB_SCOP (pbb);
1482 for (i = 0; i < nb_subscripts; i++)
1484 isl_pw_aff *aff;
1485 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1487 aff = extract_affine (scop, afn,
1488 isl_space_domain (isl_map_get_space (acc)));
1489 acc = set_index (acc, i + 1, aff);
1492 return acc;
1495 /* Add constrains representing the size of the accessed data to the
1496 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1497 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1498 domain. */
1500 static isl_set *
1501 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1503 tree ref = DR_REF (dr);
1504 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1506 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1508 tree low, high;
1510 if (TREE_CODE (ref) != ARRAY_REF)
1511 break;
1513 low = array_ref_low_bound (ref);
1514 high = array_ref_up_bound (ref);
1516 /* XXX The PPL code dealt separately with
1517 subscript - low >= 0 and high - subscript >= 0 in case one of
1518 the two bounds isn't known. Do the same here? */
1520 if (tree_fits_shwi_p (low)
1521 && high
1522 && tree_fits_shwi_p (high)
1523 /* 1-element arrays at end of structures may extend over
1524 their declared size. */
1525 && !(array_at_struct_end_p (ref)
1526 && operand_equal_p (low, high, 0)))
1528 isl_id *id;
1529 isl_aff *aff;
1530 isl_set *univ, *lbs, *ubs;
1531 isl_pw_aff *index;
1532 isl_space *space;
1533 isl_set *valid;
1534 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1535 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1537 /* high >= 0 */
1538 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1539 valid = isl_set_project_out (valid, isl_dim_set, 0,
1540 isl_set_dim (valid, isl_dim_set));
1541 scop->context = isl_set_intersect (scop->context, valid);
1543 space = isl_set_get_space (extent);
1544 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1545 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1546 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1547 index = isl_pw_aff_alloc (univ, aff);
1549 id = isl_set_get_tuple_id (extent);
1550 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1551 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1553 /* low <= sub_i <= high */
1554 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1555 ubs = isl_pw_aff_le_set (index, ub);
1556 extent = isl_set_intersect (extent, lbs);
1557 extent = isl_set_intersect (extent, ubs);
1561 return extent;
1564 /* Build data accesses for DR in PBB. */
1566 static void
1567 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1569 int dr_base_object_set;
1570 isl_map *acc;
1571 isl_set *extent;
1572 scop_p scop = PBB_SCOP (pbb);
1575 isl_space *dc = isl_set_get_space (pbb->domain);
1576 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1577 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1578 isl_dim_out, nb_out);
1580 acc = isl_map_universe (space);
1581 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1584 acc = pdr_add_alias_set (acc, dr);
1585 acc = pdr_add_memory_accesses (acc, dr, pbb);
1588 isl_id *id = isl_id_for_dr (scop, dr);
1589 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1590 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1591 int alias_set_num = 0;
1592 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1594 if (bap && bap->alias_set)
1595 alias_set_num = *(bap->alias_set);
1597 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1598 extent = isl_set_nat_universe (space);
1599 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1600 extent = pdr_add_data_dimensions (extent, scop, dr);
1603 gcc_assert (dr->aux);
1604 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1606 new_poly_dr (pbb, dr_base_object_set,
1607 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1608 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1611 /* Write to FILE the alias graph of data references in DIMACS format. */
1613 static inline bool
1614 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1615 vec<data_reference_p> drs)
1617 int num_vertex = drs.length ();
1618 int edge_num = 0;
1619 data_reference_p dr1, dr2;
1620 int i, j;
1622 if (num_vertex == 0)
1623 return true;
1625 FOR_EACH_VEC_ELT (drs, i, dr1)
1626 for (j = i + 1; drs.iterate (j, &dr2); j++)
1627 if (dr_may_alias_p (dr1, dr2, true))
1628 edge_num++;
1630 fprintf (file, "$\n");
1632 if (comment)
1633 fprintf (file, "c %s\n", comment);
1635 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1637 FOR_EACH_VEC_ELT (drs, i, dr1)
1638 for (j = i + 1; drs.iterate (j, &dr2); j++)
1639 if (dr_may_alias_p (dr1, dr2, true))
1640 fprintf (file, "e %d %d\n", i + 1, j + 1);
1642 return true;
1645 /* Write to FILE the alias graph of data references in DOT format. */
1647 static inline bool
1648 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1649 vec<data_reference_p> drs)
1651 int num_vertex = drs.length ();
1652 data_reference_p dr1, dr2;
1653 int i, j;
1655 if (num_vertex == 0)
1656 return true;
1658 fprintf (file, "$\n");
1660 if (comment)
1661 fprintf (file, "c %s\n", comment);
1663 /* First print all the vertices. */
1664 FOR_EACH_VEC_ELT (drs, i, dr1)
1665 fprintf (file, "n%d;\n", i);
1667 FOR_EACH_VEC_ELT (drs, i, dr1)
1668 for (j = i + 1; drs.iterate (j, &dr2); j++)
1669 if (dr_may_alias_p (dr1, dr2, true))
1670 fprintf (file, "n%d n%d\n", i, j);
1672 return true;
1675 /* Write to FILE the alias graph of data references in ECC format. */
1677 static inline bool
1678 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1679 vec<data_reference_p> drs)
1681 int num_vertex = drs.length ();
1682 data_reference_p dr1, dr2;
1683 int i, j;
1685 if (num_vertex == 0)
1686 return true;
1688 fprintf (file, "$\n");
1690 if (comment)
1691 fprintf (file, "c %s\n", comment);
1693 FOR_EACH_VEC_ELT (drs, i, dr1)
1694 for (j = i + 1; drs.iterate (j, &dr2); j++)
1695 if (dr_may_alias_p (dr1, dr2, true))
1696 fprintf (file, "%d %d\n", i, j);
1698 return true;
1701 /* Check if DR1 and DR2 are in the same object set. */
1703 static bool
1704 dr_same_base_object_p (const struct data_reference *dr1,
1705 const struct data_reference *dr2)
1707 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1710 /* Uses DFS component number as representative of alias-sets. Also tests for
1711 optimality by verifying if every connected component is a clique. Returns
1712 true (1) if the above test is true, and false (0) otherwise. */
1714 static int
1715 build_alias_set_optimal_p (vec<data_reference_p> drs)
1717 int num_vertices = drs.length ();
1718 struct graph *g = new_graph (num_vertices);
1719 data_reference_p dr1, dr2;
1720 int i, j;
1721 int num_connected_components;
1722 int v_indx1, v_indx2, num_vertices_in_component;
1723 int *all_vertices;
1724 int *vertices;
1725 struct graph_edge *e;
1726 int this_component_is_clique;
1727 int all_components_are_cliques = 1;
1729 FOR_EACH_VEC_ELT (drs, i, dr1)
1730 for (j = i+1; drs.iterate (j, &dr2); j++)
1731 if (dr_may_alias_p (dr1, dr2, true))
1733 add_edge (g, i, j);
1734 add_edge (g, j, i);
1737 all_vertices = XNEWVEC (int, num_vertices);
1738 vertices = XNEWVEC (int, num_vertices);
1739 for (i = 0; i < num_vertices; i++)
1740 all_vertices[i] = i;
1742 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1743 NULL, true, NULL);
1744 for (i = 0; i < g->n_vertices; i++)
1746 data_reference_p dr = drs[i];
1747 base_alias_pair *bap;
1749 gcc_assert (dr->aux);
1750 bap = (base_alias_pair *)(dr->aux);
1752 bap->alias_set = XNEW (int);
1753 *(bap->alias_set) = g->vertices[i].component + 1;
1756 /* Verify if the DFS numbering results in optimal solution. */
1757 for (i = 0; i < num_connected_components; i++)
1759 num_vertices_in_component = 0;
1760 /* Get all vertices whose DFS component number is the same as i. */
1761 for (j = 0; j < num_vertices; j++)
1762 if (g->vertices[j].component == i)
1763 vertices[num_vertices_in_component++] = j;
1765 /* Now test if the vertices in 'vertices' form a clique, by testing
1766 for edges among each pair. */
1767 this_component_is_clique = 1;
1768 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1770 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1772 /* Check if the two vertices are connected by iterating
1773 through all the edges which have one of these are source. */
1774 e = g->vertices[vertices[v_indx2]].pred;
1775 while (e)
1777 if (e->src == vertices[v_indx1])
1778 break;
1779 e = e->pred_next;
1781 if (!e)
1783 this_component_is_clique = 0;
1784 break;
1787 if (!this_component_is_clique)
1788 all_components_are_cliques = 0;
1792 free (all_vertices);
1793 free (vertices);
1794 free_graph (g);
1795 return all_components_are_cliques;
1798 /* Group each data reference in DRS with its base object set num. */
1800 static void
1801 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1803 int num_vertex = drs.length ();
1804 struct graph *g = new_graph (num_vertex);
1805 data_reference_p dr1, dr2;
1806 int i, j;
1807 int *queue;
1809 FOR_EACH_VEC_ELT (drs, i, dr1)
1810 for (j = i + 1; drs.iterate (j, &dr2); j++)
1811 if (dr_same_base_object_p (dr1, dr2))
1813 add_edge (g, i, j);
1814 add_edge (g, j, i);
1817 queue = XNEWVEC (int, num_vertex);
1818 for (i = 0; i < num_vertex; i++)
1819 queue[i] = i;
1821 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1823 for (i = 0; i < g->n_vertices; i++)
1825 data_reference_p dr = drs[i];
1826 base_alias_pair *bap;
1828 gcc_assert (dr->aux);
1829 bap = (base_alias_pair *)(dr->aux);
1831 bap->base_obj_set = g->vertices[i].component + 1;
1834 free (queue);
1835 free_graph (g);
1838 /* Build the data references for PBB. */
1840 static void
1841 build_pbb_drs (poly_bb_p pbb)
1843 int j;
1844 data_reference_p dr;
1845 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1847 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1848 build_poly_dr (dr, pbb);
1851 /* Dump to file the alias graphs for the data references in DRS. */
1853 static void
1854 dump_alias_graphs (vec<data_reference_p> drs)
1856 char comment[100];
1857 FILE *file_dimacs, *file_ecc, *file_dot;
1859 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1860 if (file_dimacs)
1862 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1863 current_function_name ());
1864 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1865 fclose (file_dimacs);
1868 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1869 if (file_ecc)
1871 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1872 current_function_name ());
1873 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1874 fclose (file_ecc);
1877 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1878 if (file_dot)
1880 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1881 current_function_name ());
1882 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1883 fclose (file_dot);
1887 /* Build data references in SCOP. */
1889 static void
1890 build_scop_drs (scop_p scop)
1892 int i, j;
1893 poly_bb_p pbb;
1894 data_reference_p dr;
1895 auto_vec<data_reference_p, 3> drs;
1897 /* Remove all the PBBs that do not have data references: these basic
1898 blocks are not handled in the polyhedral representation. */
1899 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1900 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1902 free_gimple_bb (PBB_BLACK_BOX (pbb));
1903 free_poly_bb (pbb);
1904 SCOP_BBS (scop).ordered_remove (i);
1905 i--;
1908 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1909 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1910 drs.safe_push (dr);
1912 FOR_EACH_VEC_ELT (drs, i, dr)
1913 dr->aux = XNEW (base_alias_pair);
1915 if (!build_alias_set_optimal_p (drs))
1917 /* TODO: Add support when building alias set is not optimal. */
1921 build_base_obj_set_for_drs (drs);
1923 /* When debugging, enable the following code. This cannot be used
1924 in production compilers. */
1925 if (0)
1926 dump_alias_graphs (drs);
1928 drs.release ();
1930 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1931 build_pbb_drs (pbb);
1934 /* Return a gsi at the position of the phi node STMT. */
1936 static gphi_iterator
1937 gsi_for_phi_node (gphi *stmt)
1939 gphi_iterator psi;
1940 basic_block bb = gimple_bb (stmt);
1942 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1943 if (stmt == psi.phi ())
1944 return psi;
1946 gcc_unreachable ();
1947 return psi;
1950 /* Analyze all the data references of STMTS and add them to the
1951 GBB_DATA_REFS vector of BB. */
1953 static void
1954 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1956 loop_p nest;
1957 gimple_bb_p gbb;
1958 gimple stmt;
1959 int i;
1960 sese region = SCOP_REGION (scop);
1962 if (!bb_in_sese_p (bb, region))
1963 return;
1965 nest = outermost_loop_in_sese_1 (region, bb);
1966 gbb = gbb_from_bb (bb);
1968 FOR_EACH_VEC_ELT (stmts, i, stmt)
1970 loop_p loop;
1972 if (is_gimple_debug (stmt))
1973 continue;
1975 loop = loop_containing_stmt (stmt);
1976 if (!loop_in_sese_p (loop, region))
1977 loop = nest;
1979 graphite_find_data_references_in_stmt (nest, loop, stmt,
1980 &GBB_DATA_REFS (gbb));
1984 /* Insert STMT at the end of the STMTS sequence and then insert the
1985 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1986 on STMTS. */
1988 static void
1989 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
1990 gimple_stmt_iterator insert_gsi)
1992 gimple_stmt_iterator gsi;
1993 auto_vec<gimple, 3> x;
1995 gimple_seq_add_stmt (&stmts, stmt);
1996 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1997 x.safe_push (gsi_stmt (gsi));
1999 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2000 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2003 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2005 static void
2006 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2008 gimple_seq stmts;
2009 gimple_stmt_iterator gsi;
2010 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2011 gassign *stmt = gimple_build_assign (unshare_expr (res), var);
2012 auto_vec<gimple, 3> x;
2014 gimple_seq_add_stmt (&stmts, stmt);
2015 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2016 x.safe_push (gsi_stmt (gsi));
2018 if (gimple_code (after_stmt) == GIMPLE_PHI)
2020 gsi = gsi_after_labels (gimple_bb (after_stmt));
2021 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2023 else
2025 gsi = gsi_for_stmt (after_stmt);
2026 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2029 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2032 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2034 static void
2035 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2037 vec<data_reference_p> drs;
2038 drs.create (3);
2039 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2040 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2041 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2042 int index, n = SCOP_BBS (scop).length ();
2044 /* The INDEX of PBB in SCOP_BBS. */
2045 for (index = 0; index < n; index++)
2046 if (SCOP_BBS (scop)[index] == pbb)
2047 break;
2049 pbb1->domain = isl_set_copy (pbb->domain);
2050 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
2051 isl_id_for_pbb (scop, pbb1));
2053 GBB_PBB (gbb1) = pbb1;
2054 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2055 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2056 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2059 /* Insert on edge E the assignment "RES := EXPR". */
2061 static void
2062 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2064 gimple_stmt_iterator gsi;
2065 gimple_seq stmts = NULL;
2066 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2067 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2068 basic_block bb;
2069 auto_vec<gimple, 3> x;
2071 gimple_seq_add_stmt (&stmts, stmt);
2072 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2073 x.safe_push (gsi_stmt (gsi));
2075 gsi_insert_seq_on_edge (e, stmts);
2076 gsi_commit_edge_inserts ();
2077 bb = gimple_bb (stmt);
2079 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2080 return;
2082 if (!gbb_from_bb (bb))
2083 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2085 analyze_drs_in_stmts (scop, bb, x);
2088 /* Creates a zero dimension array of the same type as VAR. */
2090 static tree
2091 create_zero_dim_array (tree var, const char *base_name)
2093 tree index_type = build_index_type (integer_zero_node);
2094 tree elt_type = TREE_TYPE (var);
2095 tree array_type = build_array_type (elt_type, index_type);
2096 tree base = create_tmp_var (array_type, base_name);
2098 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2099 NULL_TREE);
2102 /* Returns true when PHI is a loop close phi node. */
2104 static bool
2105 scalar_close_phi_node_p (gimple phi)
2107 if (gimple_code (phi) != GIMPLE_PHI
2108 || virtual_operand_p (gimple_phi_result (phi)))
2109 return false;
2111 /* Note that loop close phi nodes should have a single argument
2112 because we translated the representation into a canonical form
2113 before Graphite: see canonicalize_loop_closed_ssa_form. */
2114 return (gimple_phi_num_args (phi) == 1);
2117 /* For a definition DEF in REGION, propagates the expression EXPR in
2118 all the uses of DEF outside REGION. */
2120 static void
2121 propagate_expr_outside_region (tree def, tree expr, sese region)
2123 imm_use_iterator imm_iter;
2124 gimple use_stmt;
2125 gimple_seq stmts;
2126 bool replaced_once = false;
2128 gcc_assert (TREE_CODE (def) == SSA_NAME);
2130 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2131 NULL_TREE);
2133 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2134 if (!is_gimple_debug (use_stmt)
2135 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2137 ssa_op_iter iter;
2138 use_operand_p use_p;
2140 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2141 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2142 && (replaced_once = true))
2143 replace_exp (use_p, expr);
2145 update_stmt (use_stmt);
2148 if (replaced_once)
2150 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2151 gsi_commit_edge_inserts ();
2155 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2156 dimension array for it. */
2158 static void
2159 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2161 sese region = SCOP_REGION (scop);
2162 gimple phi = gsi_stmt (*psi);
2163 tree res = gimple_phi_result (phi);
2164 basic_block bb = gimple_bb (phi);
2165 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2166 tree arg = gimple_phi_arg_def (phi, 0);
2167 gimple stmt;
2169 /* Note that loop close phi nodes should have a single argument
2170 because we translated the representation into a canonical form
2171 before Graphite: see canonicalize_loop_closed_ssa_form. */
2172 gcc_assert (gimple_phi_num_args (phi) == 1);
2174 /* The phi node can be a non close phi node, when its argument is
2175 invariant, or a default definition. */
2176 if (is_gimple_min_invariant (arg)
2177 || SSA_NAME_IS_DEFAULT_DEF (arg))
2179 propagate_expr_outside_region (res, arg, region);
2180 gsi_next (psi);
2181 return;
2184 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2186 propagate_expr_outside_region (res, arg, region);
2187 stmt = gimple_build_assign (res, arg);
2188 remove_phi_node (psi, false);
2189 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2190 return;
2193 /* If res is scev analyzable and is not a scalar value, it is safe
2194 to ignore the close phi node: it will be code generated in the
2195 out of Graphite pass. */
2196 else if (scev_analyzable_p (res, region))
2198 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2199 tree scev;
2201 if (!loop_in_sese_p (loop, region))
2203 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2204 scev = scalar_evolution_in_region (region, loop, arg);
2205 scev = compute_overall_effect_of_inner_loop (loop, scev);
2207 else
2208 scev = scalar_evolution_in_region (region, loop, res);
2210 if (tree_does_not_contain_chrecs (scev))
2211 propagate_expr_outside_region (res, scev, region);
2213 gsi_next (psi);
2214 return;
2216 else
2218 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2220 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2222 if (TREE_CODE (arg) == SSA_NAME)
2223 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2224 SSA_NAME_DEF_STMT (arg));
2225 else
2226 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2227 zero_dim_array, arg);
2230 remove_phi_node (psi, false);
2231 SSA_NAME_DEF_STMT (res) = stmt;
2233 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2236 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2237 dimension array for it. */
2239 static void
2240 rewrite_phi_out_of_ssa (scop_p scop, gphi_iterator *psi)
2242 size_t i;
2243 gphi *phi = psi->phi ();
2244 basic_block bb = gimple_bb (phi);
2245 tree res = gimple_phi_result (phi);
2246 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2247 gimple stmt;
2249 for (i = 0; i < gimple_phi_num_args (phi); i++)
2251 tree arg = gimple_phi_arg_def (phi, i);
2252 edge e = gimple_phi_arg_edge (phi, i);
2254 /* Avoid the insertion of code in the loop latch to please the
2255 pattern matching of the vectorizer. */
2256 if (TREE_CODE (arg) == SSA_NAME
2257 && !SSA_NAME_IS_DEFAULT_DEF (arg)
2258 && e->src == bb->loop_father->latch)
2259 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2260 SSA_NAME_DEF_STMT (arg));
2261 else
2262 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2265 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2266 remove_phi_node (psi, false);
2267 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2270 /* Rewrite the degenerate phi node at position PSI from the degenerate
2271 form "x = phi (y, y, ..., y)" to "x = y". */
2273 static void
2274 rewrite_degenerate_phi (gphi_iterator *psi)
2276 tree rhs;
2277 gimple stmt;
2278 gimple_stmt_iterator gsi;
2279 gphi *phi = psi->phi ();
2280 tree res = gimple_phi_result (phi);
2281 basic_block bb;
2283 bb = gimple_bb (phi);
2284 rhs = degenerate_phi_result (phi);
2285 gcc_assert (rhs);
2287 stmt = gimple_build_assign (res, rhs);
2288 remove_phi_node (psi, false);
2290 gsi = gsi_after_labels (bb);
2291 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2294 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2296 static void
2297 rewrite_reductions_out_of_ssa (scop_p scop)
2299 basic_block bb;
2300 gphi_iterator psi;
2301 sese region = SCOP_REGION (scop);
2303 FOR_EACH_BB_FN (bb, cfun)
2304 if (bb_in_sese_p (bb, region))
2305 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2307 gphi *phi = psi.phi ();
2309 if (virtual_operand_p (gimple_phi_result (phi)))
2311 gsi_next (&psi);
2312 continue;
2315 if (gimple_phi_num_args (phi) > 1
2316 && degenerate_phi_result (phi))
2317 rewrite_degenerate_phi (&psi);
2319 else if (scalar_close_phi_node_p (phi))
2320 rewrite_close_phi_out_of_ssa (scop, &psi);
2322 else if (reduction_phi_p (region, &psi))
2323 rewrite_phi_out_of_ssa (scop, &psi);
2326 update_ssa (TODO_update_ssa);
2327 #ifdef ENABLE_CHECKING
2328 verify_loop_closed_ssa (true);
2329 #endif
2332 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2333 read from ZERO_DIM_ARRAY. */
2335 static void
2336 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2337 tree def, gimple use_stmt)
2339 gimple name_stmt;
2340 tree name;
2341 ssa_op_iter iter;
2342 use_operand_p use_p;
2344 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2346 name = copy_ssa_name (def);
2347 name_stmt = gimple_build_assign (name, zero_dim_array);
2349 gimple_assign_set_lhs (name_stmt, name);
2350 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2352 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2353 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2354 replace_exp (use_p, name);
2356 update_stmt (use_stmt);
2359 /* For every definition DEF in the SCOP that is used outside the scop,
2360 insert a closing-scop definition in the basic block just after this
2361 SCOP. */
2363 static void
2364 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2366 tree var = create_tmp_reg (TREE_TYPE (def));
2367 tree new_name = make_ssa_name (var, stmt);
2368 bool needs_copy = false;
2369 use_operand_p use_p;
2370 imm_use_iterator imm_iter;
2371 gimple use_stmt;
2372 sese region = SCOP_REGION (scop);
2374 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2376 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2378 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2380 SET_USE (use_p, new_name);
2382 update_stmt (use_stmt);
2383 needs_copy = true;
2387 /* Insert in the empty BB just after the scop a use of DEF such
2388 that the rewrite of cross_bb_scalar_dependences won't insert
2389 arrays everywhere else. */
2390 if (needs_copy)
2392 gimple assign = gimple_build_assign (new_name, def);
2393 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2395 update_stmt (assign);
2396 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2400 /* Rewrite the scalar dependences crossing the boundary of the BB
2401 containing STMT with an array. Return true when something has been
2402 changed. */
2404 static bool
2405 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2407 sese region = SCOP_REGION (scop);
2408 gimple stmt = gsi_stmt (*gsi);
2409 imm_use_iterator imm_iter;
2410 tree def;
2411 basic_block def_bb;
2412 tree zero_dim_array = NULL_TREE;
2413 gimple use_stmt;
2414 bool res = false;
2416 switch (gimple_code (stmt))
2418 case GIMPLE_ASSIGN:
2419 def = gimple_assign_lhs (stmt);
2420 break;
2422 case GIMPLE_CALL:
2423 def = gimple_call_lhs (stmt);
2424 break;
2426 default:
2427 return false;
2430 if (!def
2431 || !is_gimple_reg (def))
2432 return false;
2434 if (scev_analyzable_p (def, region))
2436 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2437 tree scev = scalar_evolution_in_region (region, loop, def);
2439 if (tree_contains_chrecs (scev, NULL))
2440 return false;
2442 propagate_expr_outside_region (def, scev, region);
2443 return true;
2446 def_bb = gimple_bb (stmt);
2448 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2450 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2451 if (gimple_code (use_stmt) == GIMPLE_PHI
2452 && (res = true))
2454 gphi_iterator psi = gsi_start_phis (gimple_bb (use_stmt));
2456 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2457 rewrite_close_phi_out_of_ssa (scop, &psi);
2458 else
2459 rewrite_phi_out_of_ssa (scop, &psi);
2462 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2463 if (gimple_code (use_stmt) != GIMPLE_PHI
2464 && def_bb != gimple_bb (use_stmt)
2465 && !is_gimple_debug (use_stmt)
2466 && (res = true))
2468 if (!zero_dim_array)
2470 zero_dim_array = create_zero_dim_array
2471 (def, "Cross_BB_scalar_dependence");
2472 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2473 SSA_NAME_DEF_STMT (def));
2474 gsi_next (gsi);
2477 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
2478 def, use_stmt);
2481 return res;
2484 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2486 static void
2487 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2489 basic_block bb;
2490 gimple_stmt_iterator psi;
2491 sese region = SCOP_REGION (scop);
2492 bool changed = false;
2494 /* Create an extra empty BB after the scop. */
2495 split_edge (SESE_EXIT (region));
2497 FOR_EACH_BB_FN (bb, cfun)
2498 if (bb_in_sese_p (bb, region))
2499 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2500 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2502 if (changed)
2504 scev_reset_htab ();
2505 update_ssa (TODO_update_ssa);
2506 #ifdef ENABLE_CHECKING
2507 verify_loop_closed_ssa (true);
2508 #endif
2512 /* Returns the number of pbbs that are in loops contained in SCOP. */
2514 static int
2515 nb_pbbs_in_loops (scop_p scop)
2517 int i;
2518 poly_bb_p pbb;
2519 int res = 0;
2521 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2522 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2523 res++;
2525 return res;
2528 /* Return the number of data references in BB that write in
2529 memory. */
2531 static int
2532 nb_data_writes_in_bb (basic_block bb)
2534 int res = 0;
2535 gimple_stmt_iterator gsi;
2537 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2538 if (gimple_vdef (gsi_stmt (gsi)))
2539 res++;
2541 return res;
2544 /* Splits at STMT the basic block BB represented as PBB in the
2545 polyhedral form. */
2547 static edge
2548 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2550 edge e1 = split_block (bb, stmt);
2551 new_pbb_from_pbb (scop, pbb, e1->dest);
2552 return e1;
2555 /* Splits STMT out of its current BB. This is done for reduction
2556 statements for which we want to ignore data dependences. */
2558 static basic_block
2559 split_reduction_stmt (scop_p scop, gimple stmt)
2561 basic_block bb = gimple_bb (stmt);
2562 poly_bb_p pbb = pbb_from_bb (bb);
2563 gimple_bb_p gbb = gbb_from_bb (bb);
2564 edge e1;
2565 int i;
2566 data_reference_p dr;
2568 /* Do not split basic blocks with no writes to memory: the reduction
2569 will be the only write to memory. */
2570 if (nb_data_writes_in_bb (bb) == 0
2571 /* Or if we have already marked BB as a reduction. */
2572 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2573 return bb;
2575 e1 = split_pbb (scop, pbb, bb, stmt);
2577 /* Split once more only when the reduction stmt is not the only one
2578 left in the original BB. */
2579 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2581 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2582 gsi_prev (&gsi);
2583 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2586 /* A part of the data references will end in a different basic block
2587 after the split: move the DRs from the original GBB to the newly
2588 created GBB1. */
2589 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2591 basic_block bb1 = gimple_bb (DR_STMT (dr));
2593 if (bb1 != bb)
2595 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2596 GBB_DATA_REFS (gbb1).safe_push (dr);
2597 GBB_DATA_REFS (gbb).ordered_remove (i);
2598 i--;
2602 return e1->dest;
2605 /* Return true when stmt is a reduction operation. */
2607 static inline bool
2608 is_reduction_operation_p (gimple stmt)
2610 enum tree_code code;
2612 gcc_assert (is_gimple_assign (stmt));
2613 code = gimple_assign_rhs_code (stmt);
2615 return flag_associative_math
2616 && commutative_tree_code (code)
2617 && associative_tree_code (code);
2620 /* Returns true when PHI contains an argument ARG. */
2622 static bool
2623 phi_contains_arg (gphi *phi, tree arg)
2625 size_t i;
2627 for (i = 0; i < gimple_phi_num_args (phi); i++)
2628 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2629 return true;
2631 return false;
2634 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2636 static gphi *
2637 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2639 gimple stmt;
2641 if (TREE_CODE (arg) != SSA_NAME)
2642 return NULL;
2644 stmt = SSA_NAME_DEF_STMT (arg);
2646 if (gimple_code (stmt) == GIMPLE_NOP
2647 || gimple_code (stmt) == GIMPLE_CALL)
2648 return NULL;
2650 if (gphi *phi = dyn_cast <gphi *> (stmt))
2652 if (phi_contains_arg (phi, lhs))
2653 return phi;
2654 return NULL;
2657 if (!is_gimple_assign (stmt))
2658 return NULL;
2660 if (gimple_num_ops (stmt) == 2)
2661 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2663 if (is_reduction_operation_p (stmt))
2665 gphi *res
2666 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2668 return res ? res :
2669 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2672 return NULL;
2675 /* Detect commutative and associative scalar reductions starting at
2676 the STMT. Return the phi node of the reduction cycle, or NULL. */
2678 static gphi *
2679 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2680 vec<gimple> *in,
2681 vec<gimple> *out)
2683 gphi *phi = follow_ssa_with_commutative_ops (arg, lhs);
2685 if (!phi)
2686 return NULL;
2688 in->safe_push (stmt);
2689 out->safe_push (stmt);
2690 return phi;
2693 /* Detect commutative and associative scalar reductions starting at
2694 STMT. Return the phi node of the reduction cycle, or NULL. */
2696 static gphi *
2697 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2698 vec<gimple> *out)
2700 tree lhs = gimple_assign_lhs (stmt);
2702 if (gimple_num_ops (stmt) == 2)
2703 return detect_commutative_reduction_arg (lhs, stmt,
2704 gimple_assign_rhs1 (stmt),
2705 in, out);
2707 if (is_reduction_operation_p (stmt))
2709 gphi *res = detect_commutative_reduction_arg (lhs, stmt,
2710 gimple_assign_rhs1 (stmt),
2711 in, out);
2712 return res ? res
2713 : detect_commutative_reduction_arg (lhs, stmt,
2714 gimple_assign_rhs2 (stmt),
2715 in, out);
2718 return NULL;
2721 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2723 static gphi *
2724 follow_inital_value_to_phi (tree arg, tree lhs)
2726 gimple stmt;
2728 if (!arg || TREE_CODE (arg) != SSA_NAME)
2729 return NULL;
2731 stmt = SSA_NAME_DEF_STMT (arg);
2733 if (gphi *phi = dyn_cast <gphi *> (stmt))
2734 if (phi_contains_arg (phi, lhs))
2735 return phi;
2737 return NULL;
2741 /* Return the argument of the loop PHI that is the initial value coming
2742 from outside the loop. */
2744 static edge
2745 edge_initial_value_for_loop_phi (gphi *phi)
2747 size_t i;
2749 for (i = 0; i < gimple_phi_num_args (phi); i++)
2751 edge e = gimple_phi_arg_edge (phi, i);
2753 if (loop_depth (e->src->loop_father)
2754 < loop_depth (e->dest->loop_father))
2755 return e;
2758 return NULL;
2761 /* Return the argument of the loop PHI that is the initial value coming
2762 from outside the loop. */
2764 static tree
2765 initial_value_for_loop_phi (gphi *phi)
2767 size_t i;
2769 for (i = 0; i < gimple_phi_num_args (phi); i++)
2771 edge e = gimple_phi_arg_edge (phi, i);
2773 if (loop_depth (e->src->loop_father)
2774 < loop_depth (e->dest->loop_father))
2775 return gimple_phi_arg_def (phi, i);
2778 return NULL_TREE;
2781 /* Returns true when DEF is used outside the reduction cycle of
2782 LOOP_PHI. */
2784 static bool
2785 used_outside_reduction (tree def, gimple loop_phi)
2787 use_operand_p use_p;
2788 imm_use_iterator imm_iter;
2789 loop_p loop = loop_containing_stmt (loop_phi);
2791 /* In LOOP, DEF should be used only in LOOP_PHI. */
2792 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2794 gimple stmt = USE_STMT (use_p);
2796 if (stmt != loop_phi
2797 && !is_gimple_debug (stmt)
2798 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2799 return true;
2802 return false;
2805 /* Detect commutative and associative scalar reductions belonging to
2806 the SCOP starting at the loop closed phi node STMT. Return the phi
2807 node of the reduction cycle, or NULL. */
2809 static gphi *
2810 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2811 vec<gimple> *out)
2813 if (scalar_close_phi_node_p (stmt))
2815 gimple def;
2816 gphi *loop_phi, *phi, *close_phi = as_a <gphi *> (stmt);
2817 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2819 if (TREE_CODE (arg) != SSA_NAME)
2820 return NULL;
2822 /* Note that loop close phi nodes should have a single argument
2823 because we translated the representation into a canonical form
2824 before Graphite: see canonicalize_loop_closed_ssa_form. */
2825 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2827 def = SSA_NAME_DEF_STMT (arg);
2828 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2829 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2830 return NULL;
2832 lhs = gimple_phi_result (close_phi);
2833 init = initial_value_for_loop_phi (loop_phi);
2834 phi = follow_inital_value_to_phi (init, lhs);
2836 if (phi && (used_outside_reduction (lhs, phi)
2837 || !has_single_use (gimple_phi_result (phi))))
2838 return NULL;
2840 in->safe_push (loop_phi);
2841 out->safe_push (close_phi);
2842 return phi;
2845 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2846 return detect_commutative_reduction_assign (stmt, in, out);
2848 return NULL;
2851 /* Translate the scalar reduction statement STMT to an array RED
2852 knowing that its recursive phi node is LOOP_PHI. */
2854 static void
2855 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2856 gimple stmt, gphi *loop_phi)
2858 tree res = gimple_phi_result (loop_phi);
2859 gassign *assign = gimple_build_assign (res, unshare_expr (red));
2860 gimple_stmt_iterator gsi;
2862 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2864 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2865 gsi = gsi_for_stmt (stmt);
2866 gsi_next (&gsi);
2867 insert_stmts (scop, assign, NULL, gsi);
2870 /* Removes the PHI node and resets all the debug stmts that are using
2871 the PHI_RESULT. */
2873 static void
2874 remove_phi (gphi *phi)
2876 imm_use_iterator imm_iter;
2877 tree def;
2878 use_operand_p use_p;
2879 gimple_stmt_iterator gsi;
2880 auto_vec<gimple, 3> update;
2881 unsigned int i;
2882 gimple stmt;
2884 def = PHI_RESULT (phi);
2885 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2887 stmt = USE_STMT (use_p);
2889 if (is_gimple_debug (stmt))
2891 gimple_debug_bind_reset_value (stmt);
2892 update.safe_push (stmt);
2896 FOR_EACH_VEC_ELT (update, i, stmt)
2897 update_stmt (stmt);
2899 gsi = gsi_for_phi_node (phi);
2900 remove_phi_node (&gsi, false);
2903 /* Helper function for for_each_index. For each INDEX of the data
2904 reference REF, returns true when its indices are valid in the loop
2905 nest LOOP passed in as DATA. */
2907 static bool
2908 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2910 loop_p loop;
2911 basic_block header, def_bb;
2912 gimple stmt;
2914 if (TREE_CODE (*index) != SSA_NAME)
2915 return true;
2917 loop = *((loop_p *) data);
2918 header = loop->header;
2919 stmt = SSA_NAME_DEF_STMT (*index);
2921 if (!stmt)
2922 return true;
2924 def_bb = gimple_bb (stmt);
2926 if (!def_bb)
2927 return true;
2929 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2932 /* When the result of a CLOSE_PHI is written to a memory location,
2933 return a pointer to that memory reference, otherwise return
2934 NULL_TREE. */
2936 static tree
2937 close_phi_written_to_memory (gphi *close_phi)
2939 imm_use_iterator imm_iter;
2940 use_operand_p use_p;
2941 gimple stmt;
2942 tree res, def = gimple_phi_result (close_phi);
2944 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2945 if ((stmt = USE_STMT (use_p))
2946 && gimple_code (stmt) == GIMPLE_ASSIGN
2947 && (res = gimple_assign_lhs (stmt)))
2949 switch (TREE_CODE (res))
2951 case VAR_DECL:
2952 case PARM_DECL:
2953 case RESULT_DECL:
2954 return res;
2956 case ARRAY_REF:
2957 case MEM_REF:
2959 tree arg = gimple_phi_arg_def (close_phi, 0);
2960 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2962 /* FIXME: this restriction is for id-{24,25}.f and
2963 could be handled by duplicating the computation of
2964 array indices before the loop of the close_phi. */
2965 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2966 return res;
2968 /* Fallthru. */
2970 default:
2971 continue;
2974 return NULL_TREE;
2977 /* Rewrite out of SSA the reduction described by the loop phi nodes
2978 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2979 levels like this:
2981 IN: stmt, loop_n, ..., loop_0
2982 OUT: stmt, close_n, ..., close_0
2984 the first element is the reduction statement, and the next elements
2985 are the loop and close phi nodes of each of the outer loops. */
2987 static void
2988 translate_scalar_reduction_to_array (scop_p scop,
2989 vec<gimple> in,
2990 vec<gimple> out)
2992 gimple loop_stmt;
2993 unsigned int i = out.length () - 1;
2994 tree red = close_phi_written_to_memory (as_a <gphi *> (out[i]));
2996 FOR_EACH_VEC_ELT (in, i, loop_stmt)
2998 gimple close_stmt = out[i];
3000 if (i == 0)
3002 basic_block bb = split_reduction_stmt (scop, loop_stmt);
3003 poly_bb_p pbb = pbb_from_bb (bb);
3004 PBB_IS_REDUCTION (pbb) = true;
3005 gcc_assert (close_stmt == loop_stmt);
3007 if (!red)
3008 red = create_zero_dim_array
3009 (gimple_assign_lhs (loop_stmt), "Commutative_Associative_Reduction");
3011 translate_scalar_reduction_to_array_for_stmt (scop, red, loop_stmt,
3012 as_a <gphi *> (in[1]));
3013 continue;
3016 gphi *loop_phi = as_a <gphi *> (loop_stmt);
3017 gphi *close_phi = as_a <gphi *> (close_stmt);
3019 if (i == in.length () - 1)
3021 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3022 unshare_expr (red), close_phi);
3023 insert_out_of_ssa_copy_on_edge
3024 (scop, edge_initial_value_for_loop_phi (loop_phi),
3025 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3028 remove_phi (loop_phi);
3029 remove_phi (close_phi);
3033 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3034 true when something has been changed. */
3036 static bool
3037 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3038 gphi *close_phi)
3040 bool res;
3041 auto_vec<gimple, 10> in;
3042 auto_vec<gimple, 10> out;
3044 detect_commutative_reduction (scop, close_phi, &in, &out);
3045 res = in.length () > 1;
3046 if (res)
3047 translate_scalar_reduction_to_array (scop, in, out);
3049 return res;
3052 /* Rewrites all the commutative reductions from LOOP out of SSA.
3053 Returns true when something has been changed. */
3055 static bool
3056 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3057 loop_p loop)
3059 gphi_iterator gsi;
3060 edge exit = single_exit (loop);
3061 tree res;
3062 bool changed = false;
3064 if (!exit)
3065 return false;
3067 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3068 if ((res = gimple_phi_result (gsi.phi ()))
3069 && !virtual_operand_p (res)
3070 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3071 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3072 (scop, gsi.phi ());
3074 return changed;
3077 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3079 static void
3080 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3082 loop_p loop;
3083 bool changed = false;
3084 sese region = SCOP_REGION (scop);
3086 FOR_EACH_LOOP (loop, 0)
3087 if (loop_in_sese_p (loop, region))
3088 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3090 if (changed)
3092 scev_reset_htab ();
3093 gsi_commit_edge_inserts ();
3094 update_ssa (TODO_update_ssa);
3095 #ifdef ENABLE_CHECKING
3096 verify_loop_closed_ssa (true);
3097 #endif
3101 /* Can all ivs be represented by a signed integer?
3102 As CLooG might generate negative values in its expressions, signed loop ivs
3103 are required in the backend. */
3105 static bool
3106 scop_ivs_can_be_represented (scop_p scop)
3108 loop_p loop;
3109 gphi_iterator psi;
3110 bool result = true;
3112 FOR_EACH_LOOP (loop, 0)
3114 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3115 continue;
3117 for (psi = gsi_start_phis (loop->header);
3118 !gsi_end_p (psi); gsi_next (&psi))
3120 gphi *phi = psi.phi ();
3121 tree res = PHI_RESULT (phi);
3122 tree type = TREE_TYPE (res);
3124 if (TYPE_UNSIGNED (type)
3125 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3127 result = false;
3128 break;
3131 if (!result)
3132 break;
3135 return result;
3138 /* Builds the polyhedral representation for a SESE region. */
3140 void
3141 build_poly_scop (scop_p scop)
3143 sese region = SCOP_REGION (scop);
3144 graphite_dim_t max_dim;
3146 build_scop_bbs (scop);
3148 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3149 Once CLooG is fixed, remove this guard. Anyways, it makes no
3150 sense to optimize a scop containing only PBBs that do not belong
3151 to any loops. */
3152 if (nb_pbbs_in_loops (scop) == 0)
3153 return;
3155 if (!scop_ivs_can_be_represented (scop))
3156 return;
3158 if (flag_associative_math)
3159 rewrite_commutative_reductions_out_of_ssa (scop);
3161 build_sese_loop_nests (region);
3162 /* Record all conditions in REGION. */
3163 sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
3164 find_scop_parameters (scop);
3166 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3167 if (scop_nb_params (scop) > max_dim)
3168 return;
3170 build_scop_iteration_domain (scop);
3171 build_scop_context (scop);
3172 add_conditions_to_constraints (scop);
3174 /* Rewrite out of SSA only after having translated the
3175 representation to the polyhedral representation to avoid scev
3176 analysis failures. That means that these functions will insert
3177 new data references that they create in the right place. */
3178 rewrite_reductions_out_of_ssa (scop);
3179 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3181 build_scop_drs (scop);
3182 scop_to_lst (scop);
3183 build_scop_scattering (scop);
3185 /* This SCoP has been translated to the polyhedral
3186 representation. */
3187 POLY_SCOP_P (scop) = true;
3189 #endif