2013-10-11 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / gcc / graphite-sese-to-poly.c
blob3e5541ab8349fc4fa765f66f29edabb30ad85dac
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009-2013 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_cloog
24 #include <isl/set.h>
25 #include <isl/map.h>
26 #include <isl/union_map.h>
27 #include <isl/constraint.h>
28 #include <isl/aff.h>
29 #include <cloog/cloog.h>
30 #include <cloog/cloog.h>
31 #include <cloog/isl/domain.h>
32 #endif
34 #include "system.h"
35 #include "coretypes.h"
36 #include "tree-ssa.h"
37 #include "tree-pass.h"
38 #include "cfgloop.h"
39 #include "tree-chrec.h"
40 #include "tree-data-ref.h"
41 #include "tree-scalar-evolution.h"
42 #include "domwalk.h"
43 #include "sese.h"
44 #include "tree-ssa-propagate.h"
46 #ifdef HAVE_cloog
47 #include "graphite-poly.h"
48 #include "graphite-sese-to-poly.h"
51 /* Assigns to RES the value of the INTEGER_CST T. */
53 static inline void
54 tree_int_to_gmp (tree t, mpz_t res)
56 double_int di = tree_to_double_int (t);
57 mpz_set_double_int (res, di, TYPE_UNSIGNED (TREE_TYPE (t)));
60 /* Returns the index of the PHI argument defined in the outermost
61 loop. */
63 static size_t
64 phi_arg_in_outermost_loop (gimple phi)
66 loop_p loop = gimple_bb (phi)->loop_father;
67 size_t i, res = 0;
69 for (i = 0; i < gimple_phi_num_args (phi); i++)
70 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
72 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
73 res = i;
76 return res;
79 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
80 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
82 static void
83 remove_simple_copy_phi (gimple_stmt_iterator *psi)
85 gimple phi = gsi_stmt (*psi);
86 tree res = gimple_phi_result (phi);
87 size_t entry = phi_arg_in_outermost_loop (phi);
88 tree init = gimple_phi_arg_def (phi, entry);
89 gimple stmt = gimple_build_assign (res, init);
90 edge e = gimple_phi_arg_edge (phi, entry);
92 remove_phi_node (psi, false);
93 gsi_insert_on_edge_immediate (e, stmt);
94 SSA_NAME_DEF_STMT (res) = stmt;
97 /* Removes an invariant phi node at position PSI by inserting on the
98 loop ENTRY edge the assignment RES = INIT. */
100 static void
101 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
103 gimple phi = gsi_stmt (*psi);
104 loop_p loop = loop_containing_stmt (phi);
105 tree res = gimple_phi_result (phi);
106 tree scev = scalar_evolution_in_region (region, loop, res);
107 size_t entry = phi_arg_in_outermost_loop (phi);
108 edge e = gimple_phi_arg_edge (phi, entry);
109 tree var;
110 gimple stmt;
111 gimple_seq stmts = NULL;
113 if (tree_contains_chrecs (scev, NULL))
114 scev = gimple_phi_arg_def (phi, entry);
116 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
117 stmt = gimple_build_assign (res, var);
118 remove_phi_node (psi, false);
120 gimple_seq_add_stmt (&stmts, stmt);
121 gsi_insert_seq_on_edge (e, stmts);
122 gsi_commit_edge_inserts ();
123 SSA_NAME_DEF_STMT (res) = stmt;
126 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
128 static inline bool
129 simple_copy_phi_p (gimple phi)
131 tree res;
133 if (gimple_phi_num_args (phi) != 2)
134 return false;
136 res = gimple_phi_result (phi);
137 return (res == gimple_phi_arg_def (phi, 0)
138 || res == gimple_phi_arg_def (phi, 1));
141 /* Returns true when the phi node at position PSI is a reduction phi
142 node in REGION. Otherwise moves the pointer PSI to the next phi to
143 be considered. */
145 static bool
146 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
148 loop_p loop;
149 gimple phi = gsi_stmt (*psi);
150 tree res = gimple_phi_result (phi);
152 loop = loop_containing_stmt (phi);
154 if (simple_copy_phi_p (phi))
156 /* PRE introduces phi nodes like these, for an example,
157 see id-5.f in the fortran graphite testsuite:
159 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
161 remove_simple_copy_phi (psi);
162 return false;
165 if (scev_analyzable_p (res, region))
167 tree scev = scalar_evolution_in_region (region, loop, res);
169 if (evolution_function_is_invariant_p (scev, loop->num))
170 remove_invariant_phi (region, psi);
171 else
172 gsi_next (psi);
174 return false;
177 /* All the other cases are considered reductions. */
178 return true;
181 /* Store the GRAPHITE representation of BB. */
183 static gimple_bb_p
184 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
186 struct gimple_bb *gbb;
188 gbb = XNEW (struct gimple_bb);
189 bb->aux = gbb;
190 GBB_BB (gbb) = bb;
191 GBB_DATA_REFS (gbb) = drs;
192 GBB_CONDITIONS (gbb).create (0);
193 GBB_CONDITION_CASES (gbb).create (0);
195 return gbb;
198 static void
199 free_data_refs_aux (vec<data_reference_p> datarefs)
201 unsigned int i;
202 struct data_reference *dr;
204 FOR_EACH_VEC_ELT (datarefs, i, dr)
205 if (dr->aux)
207 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
209 free (bap->alias_set);
211 free (bap);
212 dr->aux = NULL;
215 /* Frees GBB. */
217 static void
218 free_gimple_bb (struct gimple_bb *gbb)
220 free_data_refs_aux (GBB_DATA_REFS (gbb));
221 free_data_refs (GBB_DATA_REFS (gbb));
223 GBB_CONDITIONS (gbb).release ();
224 GBB_CONDITION_CASES (gbb).release ();
225 GBB_BB (gbb)->aux = 0;
226 XDELETE (gbb);
229 /* Deletes all gimple bbs in SCOP. */
231 static void
232 remove_gbbs_in_scop (scop_p scop)
234 int i;
235 poly_bb_p pbb;
237 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
238 free_gimple_bb (PBB_BLACK_BOX (pbb));
241 /* Deletes all scops in SCOPS. */
243 void
244 free_scops (vec<scop_p> scops)
246 int i;
247 scop_p scop;
249 FOR_EACH_VEC_ELT (scops, i, scop)
251 remove_gbbs_in_scop (scop);
252 free_sese (SCOP_REGION (scop));
253 free_scop (scop);
256 scops.release ();
259 /* Same as outermost_loop_in_sese, returns the outermost loop
260 containing BB in REGION, but makes sure that the returned loop
261 belongs to the REGION, and so this returns the first loop in the
262 REGION when the loop containing BB does not belong to REGION. */
264 static loop_p
265 outermost_loop_in_sese_1 (sese region, basic_block bb)
267 loop_p nest = outermost_loop_in_sese (region, bb);
269 if (loop_in_sese_p (nest, region))
270 return nest;
272 /* When the basic block BB does not belong to a loop in the region,
273 return the first loop in the region. */
274 nest = nest->inner;
275 while (nest)
276 if (loop_in_sese_p (nest, region))
277 break;
278 else
279 nest = nest->next;
281 gcc_assert (nest);
282 return nest;
285 /* Generates a polyhedral black box only if the bb contains interesting
286 information. */
288 static gimple_bb_p
289 try_generate_gimple_bb (scop_p scop, basic_block bb)
291 vec<data_reference_p> drs;
292 drs.create (5);
293 sese region = SCOP_REGION (scop);
294 loop_p nest = outermost_loop_in_sese_1 (region, bb);
295 gimple_stmt_iterator gsi;
297 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
299 gimple stmt = gsi_stmt (gsi);
300 loop_p loop;
302 if (is_gimple_debug (stmt))
303 continue;
305 loop = loop_containing_stmt (stmt);
306 if (!loop_in_sese_p (loop, region))
307 loop = nest;
309 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
312 return new_gimple_bb (bb, drs);
315 /* Returns true if all predecessors of BB, that are not dominated by BB, are
316 marked in MAP. The predecessors dominated by BB are loop latches and will
317 be handled after BB. */
319 static bool
320 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
322 edge e;
323 edge_iterator ei;
325 FOR_EACH_EDGE (e, ei, bb->preds)
326 if (!bitmap_bit_p (map, e->src->index)
327 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
328 return false;
330 return true;
333 /* Compare the depth of two basic_block's P1 and P2. */
335 static int
336 compare_bb_depths (const void *p1, const void *p2)
338 const_basic_block const bb1 = *(const_basic_block const*)p1;
339 const_basic_block const bb2 = *(const_basic_block const*)p2;
340 int d1 = loop_depth (bb1->loop_father);
341 int d2 = loop_depth (bb2->loop_father);
343 if (d1 < d2)
344 return 1;
346 if (d1 > d2)
347 return -1;
349 return 0;
352 /* Sort the basic blocks from DOM such that the first are the ones at
353 a deepest loop level. */
355 static void
356 graphite_sort_dominated_info (vec<basic_block> dom)
358 dom.qsort (compare_bb_depths);
361 /* Recursive helper function for build_scops_bbs. */
363 static void
364 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
366 sese region = SCOP_REGION (scop);
367 vec<basic_block> dom;
368 poly_bb_p pbb;
370 if (bitmap_bit_p (visited, bb->index)
371 || !bb_in_sese_p (bb, region))
372 return;
374 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
375 SCOP_BBS (scop).safe_push (pbb);
376 bitmap_set_bit (visited, bb->index);
378 dom = get_dominated_by (CDI_DOMINATORS, bb);
380 if (!dom.exists ())
381 return;
383 graphite_sort_dominated_info (dom);
385 while (!dom.is_empty ())
387 int i;
388 basic_block dom_bb;
390 FOR_EACH_VEC_ELT (dom, i, dom_bb)
391 if (all_non_dominated_preds_marked_p (dom_bb, visited))
393 build_scop_bbs_1 (scop, visited, dom_bb);
394 dom.unordered_remove (i);
395 break;
399 dom.release ();
402 /* Gather the basic blocks belonging to the SCOP. */
404 static void
405 build_scop_bbs (scop_p scop)
407 sbitmap visited = sbitmap_alloc (last_basic_block);
408 sese region = SCOP_REGION (scop);
410 bitmap_clear (visited);
411 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
412 sbitmap_free (visited);
415 /* Return an ISL identifier for the polyhedral basic block PBB. */
417 static isl_id *
418 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
420 char name[50];
421 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
422 return isl_id_alloc (s->ctx, name, pbb);
425 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
426 We generate SCATTERING_DIMENSIONS scattering dimensions.
428 CLooG 0.15.0 and previous versions require, that all
429 scattering functions of one CloogProgram have the same number of
430 scattering dimensions, therefore we allow to specify it. This
431 should be removed in future versions of CLooG.
433 The scattering polyhedron consists of these dimensions: scattering,
434 loop_iterators, parameters.
436 Example:
438 | scattering_dimensions = 5
439 | used_scattering_dimensions = 3
440 | nb_iterators = 1
441 | scop_nb_params = 2
443 | Schedule:
445 | 4 5
447 | Scattering polyhedron:
449 | scattering: {s1, s2, s3, s4, s5}
450 | loop_iterators: {i}
451 | parameters: {p1, p2}
453 | s1 s2 s3 s4 s5 i p1 p2 1
454 | 1 0 0 0 0 0 0 0 -4 = 0
455 | 0 1 0 0 0 -1 0 0 0 = 0
456 | 0 0 1 0 0 0 0 0 -5 = 0 */
458 static void
459 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
460 poly_bb_p pbb, int scattering_dimensions)
462 int i;
463 int nb_iterators = pbb_dim_iter_domain (pbb);
464 int used_scattering_dimensions = nb_iterators * 2 + 1;
465 isl_int val;
466 isl_space *dc, *dm;
468 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
470 isl_int_init (val);
472 dc = isl_set_get_space (pbb->domain);
473 dm = isl_space_add_dims (isl_space_from_domain (dc),
474 isl_dim_out, scattering_dimensions);
475 pbb->schedule = isl_map_universe (dm);
477 for (i = 0; i < scattering_dimensions; i++)
479 /* Textual order inside this loop. */
480 if ((i % 2) == 0)
482 isl_constraint *c = isl_equality_alloc
483 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
485 if (0 != isl_aff_get_coefficient (static_sched, isl_dim_in,
486 i / 2, &val))
487 gcc_unreachable ();
489 isl_int_neg (val, val);
490 c = isl_constraint_set_constant (c, val);
491 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
492 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
495 /* Iterations of this loop. */
496 else /* if ((i % 2) == 1) */
498 int loop = (i - 1) / 2;
499 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
500 isl_dim_out, i);
504 isl_int_clear (val);
506 pbb->transformed = isl_map_copy (pbb->schedule);
509 /* Build for BB the static schedule.
511 The static schedule is a Dewey numbering of the abstract syntax
512 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
514 The following example informally defines the static schedule:
517 for (i: ...)
519 for (j: ...)
525 for (k: ...)
533 Static schedules for A to F:
535 DEPTH
536 0 1 2
538 B 1 0 0
539 C 1 0 1
540 D 1 1 0
541 E 1 1 1
545 static void
546 build_scop_scattering (scop_p scop)
548 int i;
549 poly_bb_p pbb;
550 gimple_bb_p previous_gbb = NULL;
551 isl_space *dc = isl_set_get_space (scop->context);
552 isl_aff *static_sched;
554 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
555 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
557 /* We have to start schedules at 0 on the first component and
558 because we cannot compare_prefix_loops against a previous loop,
559 prefix will be equal to zero, and that index will be
560 incremented before copying. */
561 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
563 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
565 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
566 int prefix;
567 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
569 if (previous_gbb)
570 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
571 else
572 prefix = 0;
574 previous_gbb = gbb;
576 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
577 prefix, 1);
578 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
581 isl_aff_free (static_sched);
584 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
586 /* Extract an affine expression from the chain of recurrence E. */
588 static isl_pw_aff *
589 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
591 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
592 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
593 isl_local_space *ls = isl_local_space_from_space (space);
594 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
595 isl_aff *loop = isl_aff_set_coefficient_si
596 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
597 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
599 /* Before multiplying, make sure that the result is affine. */
600 gcc_assert (isl_pw_aff_is_cst (rhs)
601 || isl_pw_aff_is_cst (l));
603 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
606 /* Extract an affine expression from the mult_expr E. */
608 static isl_pw_aff *
609 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
611 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
612 isl_space_copy (space));
613 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
615 if (!isl_pw_aff_is_cst (lhs)
616 && !isl_pw_aff_is_cst (rhs))
618 isl_pw_aff_free (lhs);
619 isl_pw_aff_free (rhs);
620 return NULL;
623 return isl_pw_aff_mul (lhs, rhs);
626 /* Return an ISL identifier from the name of the ssa_name E. */
628 static isl_id *
629 isl_id_for_ssa_name (scop_p s, tree e)
631 const char *name = get_name (e);
632 isl_id *id;
634 if (name)
635 id = isl_id_alloc (s->ctx, name, e);
636 else
638 char name1[50];
639 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
640 id = isl_id_alloc (s->ctx, name1, e);
643 return id;
646 /* Return an ISL identifier for the data reference DR. */
648 static isl_id *
649 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
651 /* Data references all get the same isl_id. They need to be comparable
652 and are distinguished through the first dimension, which contains the
653 alias set number. */
654 return isl_id_alloc (s->ctx, "", 0);
657 /* Extract an affine expression from the ssa_name E. */
659 static isl_pw_aff *
660 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
662 isl_aff *aff;
663 isl_set *dom;
664 isl_id *id;
665 int dimension;
667 id = isl_id_for_ssa_name (s, e);
668 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
669 isl_id_free (id);
670 dom = isl_set_universe (isl_space_copy (space));
671 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
672 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
673 return isl_pw_aff_alloc (dom, aff);
676 /* Extract an affine expression from the gmp constant G. */
678 static isl_pw_aff *
679 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
681 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
682 isl_aff *aff = isl_aff_zero_on_domain (ls);
683 isl_set *dom = isl_set_universe (space);
684 isl_int v;
686 isl_int_init (v);
687 isl_int_set_gmp (v, g);
688 aff = isl_aff_add_constant (aff, v);
689 isl_int_clear (v);
691 return isl_pw_aff_alloc (dom, aff);
694 /* Extract an affine expression from the integer_cst E. */
696 static isl_pw_aff *
697 extract_affine_int (tree e, __isl_take isl_space *space)
699 isl_pw_aff *res;
700 mpz_t g;
702 mpz_init (g);
703 tree_int_to_gmp (e, g);
704 res = extract_affine_gmp (g, space);
705 mpz_clear (g);
707 return res;
710 /* Compute pwaff mod 2^width. */
712 static isl_pw_aff *
713 wrap (isl_pw_aff *pwaff, unsigned width)
715 isl_int mod;
717 isl_int_init (mod);
718 isl_int_set_si (mod, 1);
719 isl_int_mul_2exp (mod, mod, width);
721 pwaff = isl_pw_aff_mod (pwaff, mod);
723 isl_int_clear (mod);
725 return pwaff;
728 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
729 Otherwise returns -1. */
731 static inline int
732 parameter_index_in_region_1 (tree name, sese region)
734 int i;
735 tree p;
737 gcc_assert (TREE_CODE (name) == SSA_NAME);
739 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
740 if (p == name)
741 return i;
743 return -1;
746 /* When the parameter NAME is in REGION, returns its index in
747 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
748 and returns the index of NAME. */
750 static int
751 parameter_index_in_region (tree name, sese region)
753 int i;
755 gcc_assert (TREE_CODE (name) == SSA_NAME);
757 i = parameter_index_in_region_1 (name, region);
758 if (i != -1)
759 return i;
761 gcc_assert (SESE_ADD_PARAMS (region));
763 i = SESE_PARAMS (region).length ();
764 SESE_PARAMS (region).safe_push (name);
765 return i;
768 /* Extract an affine expression from the tree E in the scop S. */
770 static isl_pw_aff *
771 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
773 isl_pw_aff *lhs, *rhs, *res;
774 tree type;
776 if (e == chrec_dont_know) {
777 isl_space_free (space);
778 return NULL;
781 switch (TREE_CODE (e))
783 case POLYNOMIAL_CHREC:
784 res = extract_affine_chrec (s, e, space);
785 break;
787 case MULT_EXPR:
788 res = extract_affine_mul (s, e, space);
789 break;
791 case PLUS_EXPR:
792 case POINTER_PLUS_EXPR:
793 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
794 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
795 res = isl_pw_aff_add (lhs, rhs);
796 break;
798 case MINUS_EXPR:
799 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
800 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
801 res = isl_pw_aff_sub (lhs, rhs);
802 break;
804 case NEGATE_EXPR:
805 case BIT_NOT_EXPR:
806 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
807 rhs = extract_affine (s, integer_minus_one_node, space);
808 res = isl_pw_aff_mul (lhs, rhs);
809 break;
811 case SSA_NAME:
812 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
813 res = extract_affine_name (s, e, space);
814 break;
816 case INTEGER_CST:
817 res = extract_affine_int (e, space);
818 /* No need to wrap a single integer. */
819 return res;
821 CASE_CONVERT:
822 case NON_LVALUE_EXPR:
823 res = extract_affine (s, TREE_OPERAND (e, 0), space);
824 break;
826 default:
827 gcc_unreachable ();
828 break;
831 type = TREE_TYPE (e);
832 if (TYPE_UNSIGNED (type))
833 res = wrap (res, TYPE_PRECISION (type));
835 return res;
838 /* In the context of sese S, scan the expression E and translate it to
839 a linear expression C. When parsing a symbolic multiplication, K
840 represents the constant multiplier of an expression containing
841 parameters. */
843 static void
844 scan_tree_for_params (sese s, tree e)
846 if (e == chrec_dont_know)
847 return;
849 switch (TREE_CODE (e))
851 case POLYNOMIAL_CHREC:
852 scan_tree_for_params (s, CHREC_LEFT (e));
853 break;
855 case MULT_EXPR:
856 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
857 scan_tree_for_params (s, TREE_OPERAND (e, 0));
858 else
859 scan_tree_for_params (s, TREE_OPERAND (e, 1));
860 break;
862 case PLUS_EXPR:
863 case POINTER_PLUS_EXPR:
864 case MINUS_EXPR:
865 scan_tree_for_params (s, TREE_OPERAND (e, 0));
866 scan_tree_for_params (s, TREE_OPERAND (e, 1));
867 break;
869 case NEGATE_EXPR:
870 case BIT_NOT_EXPR:
871 CASE_CONVERT:
872 case NON_LVALUE_EXPR:
873 scan_tree_for_params (s, TREE_OPERAND (e, 0));
874 break;
876 case SSA_NAME:
877 parameter_index_in_region (e, s);
878 break;
880 case INTEGER_CST:
881 case ADDR_EXPR:
882 break;
884 default:
885 gcc_unreachable ();
886 break;
890 /* Find parameters with respect to REGION in BB. We are looking in memory
891 access functions, conditions and loop bounds. */
893 static void
894 find_params_in_bb (sese region, gimple_bb_p gbb)
896 int i;
897 unsigned j;
898 data_reference_p dr;
899 gimple stmt;
900 loop_p loop = GBB_BB (gbb)->loop_father;
902 /* Find parameters in the access functions of data references. */
903 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
904 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
905 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
907 /* Find parameters in conditional statements. */
908 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
910 tree lhs = scalar_evolution_in_region (region, loop,
911 gimple_cond_lhs (stmt));
912 tree rhs = scalar_evolution_in_region (region, loop,
913 gimple_cond_rhs (stmt));
915 scan_tree_for_params (region, lhs);
916 scan_tree_for_params (region, rhs);
920 /* Record the parameters used in the SCOP. A variable is a parameter
921 in a scop if it does not vary during the execution of that scop. */
923 static void
924 find_scop_parameters (scop_p scop)
926 poly_bb_p pbb;
927 unsigned i;
928 sese region = SCOP_REGION (scop);
929 struct loop *loop;
930 int nbp;
932 /* Find the parameters used in the loop bounds. */
933 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
935 tree nb_iters = number_of_latch_executions (loop);
937 if (!chrec_contains_symbols (nb_iters))
938 continue;
940 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
941 scan_tree_for_params (region, nb_iters);
944 /* Find the parameters used in data accesses. */
945 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
946 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
948 nbp = sese_nb_params (region);
949 scop_set_nb_params (scop, nbp);
950 SESE_ADD_PARAMS (region) = false;
953 tree e;
954 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
956 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
957 space = isl_space_set_dim_id (space, isl_dim_param, i,
958 isl_id_for_ssa_name (scop, e));
960 scop->context = isl_set_universe (space);
964 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
965 the constraints for the surrounding loops. */
967 static void
968 build_loop_iteration_domains (scop_p scop, struct loop *loop,
969 int nb,
970 isl_set *outer, isl_set **doms)
972 tree nb_iters = number_of_latch_executions (loop);
973 sese region = SCOP_REGION (scop);
975 isl_set *inner = isl_set_copy (outer);
976 isl_space *space;
977 isl_constraint *c;
978 int pos = isl_set_dim (outer, isl_dim_set);
979 isl_int v;
980 mpz_t g;
982 mpz_init (g);
983 isl_int_init (v);
985 inner = isl_set_add_dims (inner, isl_dim_set, 1);
986 space = isl_set_get_space (inner);
988 /* 0 <= loop_i */
989 c = isl_inequality_alloc
990 (isl_local_space_from_space (isl_space_copy (space)));
991 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
992 inner = isl_set_add_constraint (inner, c);
994 /* loop_i <= cst_nb_iters */
995 if (TREE_CODE (nb_iters) == INTEGER_CST)
997 c = isl_inequality_alloc
998 (isl_local_space_from_space (isl_space_copy (space)));
999 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1000 tree_int_to_gmp (nb_iters, g);
1001 isl_int_set_gmp (v, g);
1002 c = isl_constraint_set_constant (c, v);
1003 inner = isl_set_add_constraint (inner, c);
1006 /* loop_i <= expr_nb_iters */
1007 else if (!chrec_contains_undetermined (nb_iters))
1009 double_int nit;
1010 isl_pw_aff *aff;
1011 isl_set *valid;
1012 isl_local_space *ls;
1013 isl_aff *al;
1014 isl_set *le;
1016 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1018 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1019 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1020 valid = isl_set_project_out (valid, isl_dim_set, 0,
1021 isl_set_dim (valid, isl_dim_set));
1022 scop->context = isl_set_intersect (scop->context, valid);
1024 ls = isl_local_space_from_space (isl_space_copy (space));
1025 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1026 isl_dim_in, pos, 1);
1027 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1028 isl_pw_aff_copy (aff));
1029 inner = isl_set_intersect (inner, le);
1031 if (max_stmt_executions (loop, &nit))
1033 /* Insert in the context the constraints from the
1034 estimation of the number of iterations NIT and the
1035 symbolic number of iterations (involving parameter
1036 names) NB_ITERS. First, build the affine expression
1037 "NIT - NB_ITERS" and then say that it is positive,
1038 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1039 isl_pw_aff *approx;
1040 mpz_t g;
1041 isl_set *x;
1042 isl_constraint *c;
1044 mpz_init (g);
1045 mpz_set_double_int (g, nit, false);
1046 mpz_sub_ui (g, g, 1);
1047 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1048 x = isl_pw_aff_ge_set (approx, aff);
1049 x = isl_set_project_out (x, isl_dim_set, 0,
1050 isl_set_dim (x, isl_dim_set));
1051 scop->context = isl_set_intersect (scop->context, x);
1053 c = isl_inequality_alloc
1054 (isl_local_space_from_space (isl_space_copy (space)));
1055 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1056 isl_int_set_gmp (v, g);
1057 mpz_clear (g);
1058 c = isl_constraint_set_constant (c, v);
1059 inner = isl_set_add_constraint (inner, c);
1061 else
1062 isl_pw_aff_free (aff);
1064 else
1065 gcc_unreachable ();
1067 if (loop->inner && loop_in_sese_p (loop->inner, region))
1068 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1069 isl_set_copy (inner), doms);
1071 if (nb != 0
1072 && loop->next
1073 && loop_in_sese_p (loop->next, region))
1074 build_loop_iteration_domains (scop, loop->next, nb,
1075 isl_set_copy (outer), doms);
1077 doms[loop->num] = inner;
1079 isl_set_free (outer);
1080 isl_space_free (space);
1081 isl_int_clear (v);
1082 mpz_clear (g);
1085 /* Returns a linear expression for tree T evaluated in PBB. */
1087 static isl_pw_aff *
1088 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1090 scop_p scop = PBB_SCOP (pbb);
1092 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1093 gcc_assert (!automatically_generated_chrec_p (t));
1095 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1098 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1099 operator. This allows us to invert the condition or to handle
1100 inequalities. */
1102 static void
1103 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1105 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1106 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1107 isl_set *cond;
1109 switch (code)
1111 case LT_EXPR:
1112 cond = isl_pw_aff_lt_set (lhs, rhs);
1113 break;
1115 case GT_EXPR:
1116 cond = isl_pw_aff_gt_set (lhs, rhs);
1117 break;
1119 case LE_EXPR:
1120 cond = isl_pw_aff_le_set (lhs, rhs);
1121 break;
1123 case GE_EXPR:
1124 cond = isl_pw_aff_ge_set (lhs, rhs);
1125 break;
1127 case EQ_EXPR:
1128 cond = isl_pw_aff_eq_set (lhs, rhs);
1129 break;
1131 case NE_EXPR:
1132 cond = isl_pw_aff_ne_set (lhs, rhs);
1133 break;
1135 default:
1136 isl_pw_aff_free (lhs);
1137 isl_pw_aff_free (rhs);
1138 return;
1141 cond = isl_set_coalesce (cond);
1142 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1143 pbb->domain = isl_set_intersect (pbb->domain, cond);
1146 /* Add conditions to the domain of PBB. */
1148 static void
1149 add_conditions_to_domain (poly_bb_p pbb)
1151 unsigned int i;
1152 gimple stmt;
1153 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1155 if (GBB_CONDITIONS (gbb).is_empty ())
1156 return;
1158 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1159 switch (gimple_code (stmt))
1161 case GIMPLE_COND:
1163 enum tree_code code = gimple_cond_code (stmt);
1165 /* The conditions for ELSE-branches are inverted. */
1166 if (!GBB_CONDITION_CASES (gbb)[i])
1167 code = invert_tree_comparison (code, false);
1169 add_condition_to_pbb (pbb, stmt, code);
1170 break;
1173 case GIMPLE_SWITCH:
1174 /* Switch statements are not supported right now - fall through. */
1176 default:
1177 gcc_unreachable ();
1178 break;
1182 /* Traverses all the GBBs of the SCOP and add their constraints to the
1183 iteration domains. */
1185 static void
1186 add_conditions_to_constraints (scop_p scop)
1188 int i;
1189 poly_bb_p pbb;
1191 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1192 add_conditions_to_domain (pbb);
1195 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1196 edge between BB and its predecessor is not a loop exit edge, and
1197 the last statement of the single predecessor is a COND_EXPR. */
1199 static gimple
1200 single_pred_cond_non_loop_exit (basic_block bb)
1202 if (single_pred_p (bb))
1204 edge e = single_pred_edge (bb);
1205 basic_block pred = e->src;
1206 gimple stmt;
1208 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1209 return NULL;
1211 stmt = last_stmt (pred);
1213 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1214 return stmt;
1217 return NULL;
1220 class sese_dom_walker : public dom_walker
1222 public:
1223 sese_dom_walker (cdi_direction, sese);
1224 ~sese_dom_walker ();
1226 virtual void before_dom_children (basic_block);
1227 virtual void after_dom_children (basic_block);
1229 private:
1230 vec<gimple> m_conditions, m_cases;
1231 sese m_region;
1234 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1235 : dom_walker (direction), m_region (region)
1237 m_conditions.create (3);
1238 m_cases.create (3);
1241 sese_dom_walker::~sese_dom_walker ()
1243 m_conditions.release ();
1244 m_cases.release ();
1247 /* Call-back for dom_walk executed before visiting the dominated
1248 blocks. */
1250 void
1251 sese_dom_walker::before_dom_children (basic_block bb)
1253 gimple_bb_p gbb;
1254 gimple stmt;
1256 if (!bb_in_sese_p (bb, m_region))
1257 return;
1259 stmt = single_pred_cond_non_loop_exit (bb);
1261 if (stmt)
1263 edge e = single_pred_edge (bb);
1265 m_conditions.safe_push (stmt);
1267 if (e->flags & EDGE_TRUE_VALUE)
1268 m_cases.safe_push (stmt);
1269 else
1270 m_cases.safe_push (NULL);
1273 gbb = gbb_from_bb (bb);
1275 if (gbb)
1277 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1278 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1282 /* Call-back for dom_walk executed after visiting the dominated
1283 blocks. */
1285 void
1286 sese_dom_walker::after_dom_children (basic_block bb)
1288 if (!bb_in_sese_p (bb, m_region))
1289 return;
1291 if (single_pred_cond_non_loop_exit (bb))
1293 m_conditions.pop ();
1294 m_cases.pop ();
1298 /* Add constraints on the possible values of parameter P from the type
1299 of P. */
1301 static void
1302 add_param_constraints (scop_p scop, graphite_dim_t p)
1304 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1305 tree type = TREE_TYPE (parameter);
1306 tree lb = NULL_TREE;
1307 tree ub = NULL_TREE;
1309 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1310 lb = lower_bound_in_type (type, type);
1311 else
1312 lb = TYPE_MIN_VALUE (type);
1314 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1315 ub = upper_bound_in_type (type, type);
1316 else
1317 ub = TYPE_MAX_VALUE (type);
1319 if (lb)
1321 isl_space *space = isl_set_get_space (scop->context);
1322 isl_constraint *c;
1323 mpz_t g;
1324 isl_int v;
1326 c = isl_inequality_alloc (isl_local_space_from_space (space));
1327 mpz_init (g);
1328 isl_int_init (v);
1329 tree_int_to_gmp (lb, g);
1330 isl_int_set_gmp (v, g);
1331 isl_int_neg (v, v);
1332 mpz_clear (g);
1333 c = isl_constraint_set_constant (c, v);
1334 isl_int_clear (v);
1335 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1337 scop->context = isl_set_add_constraint (scop->context, c);
1340 if (ub)
1342 isl_space *space = isl_set_get_space (scop->context);
1343 isl_constraint *c;
1344 mpz_t g;
1345 isl_int v;
1347 c = isl_inequality_alloc (isl_local_space_from_space (space));
1349 mpz_init (g);
1350 isl_int_init (v);
1351 tree_int_to_gmp (ub, g);
1352 isl_int_set_gmp (v, g);
1353 mpz_clear (g);
1354 c = isl_constraint_set_constant (c, v);
1355 isl_int_clear (v);
1356 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1358 scop->context = isl_set_add_constraint (scop->context, c);
1362 /* Build the context of the SCOP. The context usually contains extra
1363 constraints that are added to the iteration domains that constrain
1364 some parameters. */
1366 static void
1367 build_scop_context (scop_p scop)
1369 graphite_dim_t p, n = scop_nb_params (scop);
1371 for (p = 0; p < n; p++)
1372 add_param_constraints (scop, p);
1375 /* Build the iteration domains: the loops belonging to the current
1376 SCOP, and that vary for the execution of the current basic block.
1377 Returns false if there is no loop in SCOP. */
1379 static void
1380 build_scop_iteration_domain (scop_p scop)
1382 struct loop *loop;
1383 sese region = SCOP_REGION (scop);
1384 int i;
1385 poly_bb_p pbb;
1386 int nb_loops = number_of_loops (cfun);
1387 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1389 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1390 if (!loop_in_sese_p (loop_outer (loop), region))
1391 build_loop_iteration_domains (scop, loop, 0,
1392 isl_set_copy (scop->context), doms);
1394 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1396 loop = pbb_loop (pbb);
1398 if (doms[loop->num])
1399 pbb->domain = isl_set_copy (doms[loop->num]);
1400 else
1401 pbb->domain = isl_set_copy (scop->context);
1403 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1404 isl_id_for_pbb (scop, pbb));
1407 for (i = 0; i < nb_loops; i++)
1408 if (doms[i])
1409 isl_set_free (doms[i]);
1411 free (doms);
1414 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1415 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1416 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1417 domain. */
1419 static isl_map *
1420 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1422 isl_constraint *c;
1423 int alias_set_num = 0;
1424 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1426 if (bap && bap->alias_set)
1427 alias_set_num = *(bap->alias_set);
1429 c = isl_equality_alloc
1430 (isl_local_space_from_space (isl_map_get_space (acc)));
1431 c = isl_constraint_set_constant_si (c, -alias_set_num);
1432 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1434 return isl_map_add_constraint (acc, c);
1437 /* Assign the affine expression INDEX to the output dimension POS of
1438 MAP and return the result. */
1440 static isl_map *
1441 set_index (isl_map *map, int pos, isl_pw_aff *index)
1443 isl_map *index_map;
1444 int len = isl_map_dim (map, isl_dim_out);
1445 isl_id *id;
1447 index_map = isl_map_from_pw_aff (index);
1448 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1449 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1451 id = isl_map_get_tuple_id (map, isl_dim_out);
1452 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1453 id = isl_map_get_tuple_id (map, isl_dim_in);
1454 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1456 return isl_map_intersect (map, index_map);
1459 /* Add to ACCESSES polyhedron equalities defining the access functions
1460 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1461 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1462 PBB is the poly_bb_p that contains the data reference DR. */
1464 static isl_map *
1465 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1467 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1468 scop_p scop = PBB_SCOP (pbb);
1470 for (i = 0; i < nb_subscripts; i++)
1472 isl_pw_aff *aff;
1473 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1475 aff = extract_affine (scop, afn,
1476 isl_space_domain (isl_map_get_space (acc)));
1477 acc = set_index (acc, i + 1, aff);
1480 return acc;
1483 /* Add constrains representing the size of the accessed data to the
1484 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1485 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1486 domain. */
1488 static isl_set *
1489 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1491 tree ref = DR_REF (dr);
1492 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1494 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1496 tree low, high;
1498 if (TREE_CODE (ref) != ARRAY_REF)
1499 break;
1501 low = array_ref_low_bound (ref);
1502 high = array_ref_up_bound (ref);
1504 /* XXX The PPL code dealt separately with
1505 subscript - low >= 0 and high - subscript >= 0 in case one of
1506 the two bounds isn't known. Do the same here? */
1508 if (host_integerp (low, 0)
1509 && high
1510 && host_integerp (high, 0)
1511 /* 1-element arrays at end of structures may extend over
1512 their declared size. */
1513 && !(array_at_struct_end_p (ref)
1514 && operand_equal_p (low, high, 0)))
1516 isl_id *id;
1517 isl_aff *aff;
1518 isl_set *univ, *lbs, *ubs;
1519 isl_pw_aff *index;
1520 isl_space *space;
1521 isl_set *valid;
1522 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1523 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1525 /* high >= 0 */
1526 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1527 valid = isl_set_project_out (valid, isl_dim_set, 0,
1528 isl_set_dim (valid, isl_dim_set));
1529 scop->context = isl_set_intersect (scop->context, valid);
1531 space = isl_set_get_space (extent);
1532 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1533 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1534 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1535 index = isl_pw_aff_alloc (univ, aff);
1537 id = isl_set_get_tuple_id (extent);
1538 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1539 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1541 /* low <= sub_i <= high */
1542 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1543 ubs = isl_pw_aff_le_set (index, ub);
1544 extent = isl_set_intersect (extent, lbs);
1545 extent = isl_set_intersect (extent, ubs);
1549 return extent;
1552 /* Build data accesses for DR in PBB. */
1554 static void
1555 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1557 int dr_base_object_set;
1558 isl_map *acc;
1559 isl_set *extent;
1560 scop_p scop = PBB_SCOP (pbb);
1563 isl_space *dc = isl_set_get_space (pbb->domain);
1564 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1565 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1566 isl_dim_out, nb_out);
1568 acc = isl_map_universe (space);
1569 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1572 acc = pdr_add_alias_set (acc, dr);
1573 acc = pdr_add_memory_accesses (acc, dr, pbb);
1576 isl_id *id = isl_id_for_dr (scop, dr);
1577 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1578 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1579 int alias_set_num = 0;
1580 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1582 if (bap && bap->alias_set)
1583 alias_set_num = *(bap->alias_set);
1585 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1586 extent = isl_set_nat_universe (space);
1587 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1588 extent = pdr_add_data_dimensions (extent, scop, dr);
1591 gcc_assert (dr->aux);
1592 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1594 new_poly_dr (pbb, dr_base_object_set,
1595 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1596 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1599 /* Write to FILE the alias graph of data references in DIMACS format. */
1601 static inline bool
1602 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1603 vec<data_reference_p> drs)
1605 int num_vertex = drs.length ();
1606 int edge_num = 0;
1607 data_reference_p dr1, dr2;
1608 int i, j;
1610 if (num_vertex == 0)
1611 return true;
1613 FOR_EACH_VEC_ELT (drs, i, dr1)
1614 for (j = i + 1; drs.iterate (j, &dr2); j++)
1615 if (dr_may_alias_p (dr1, dr2, true))
1616 edge_num++;
1618 fprintf (file, "$\n");
1620 if (comment)
1621 fprintf (file, "c %s\n", comment);
1623 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1625 FOR_EACH_VEC_ELT (drs, i, dr1)
1626 for (j = i + 1; drs.iterate (j, &dr2); j++)
1627 if (dr_may_alias_p (dr1, dr2, true))
1628 fprintf (file, "e %d %d\n", i + 1, j + 1);
1630 return true;
1633 /* Write to FILE the alias graph of data references in DOT format. */
1635 static inline bool
1636 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1637 vec<data_reference_p> drs)
1639 int num_vertex = drs.length ();
1640 data_reference_p dr1, dr2;
1641 int i, j;
1643 if (num_vertex == 0)
1644 return true;
1646 fprintf (file, "$\n");
1648 if (comment)
1649 fprintf (file, "c %s\n", comment);
1651 /* First print all the vertices. */
1652 FOR_EACH_VEC_ELT (drs, i, dr1)
1653 fprintf (file, "n%d;\n", i);
1655 FOR_EACH_VEC_ELT (drs, i, dr1)
1656 for (j = i + 1; drs.iterate (j, &dr2); j++)
1657 if (dr_may_alias_p (dr1, dr2, true))
1658 fprintf (file, "n%d n%d\n", i, j);
1660 return true;
1663 /* Write to FILE the alias graph of data references in ECC format. */
1665 static inline bool
1666 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1667 vec<data_reference_p> drs)
1669 int num_vertex = drs.length ();
1670 data_reference_p dr1, dr2;
1671 int i, j;
1673 if (num_vertex == 0)
1674 return true;
1676 fprintf (file, "$\n");
1678 if (comment)
1679 fprintf (file, "c %s\n", comment);
1681 FOR_EACH_VEC_ELT (drs, i, dr1)
1682 for (j = i + 1; drs.iterate (j, &dr2); j++)
1683 if (dr_may_alias_p (dr1, dr2, true))
1684 fprintf (file, "%d %d\n", i, j);
1686 return true;
1689 /* Check if DR1 and DR2 are in the same object set. */
1691 static bool
1692 dr_same_base_object_p (const struct data_reference *dr1,
1693 const struct data_reference *dr2)
1695 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1698 /* Uses DFS component number as representative of alias-sets. Also tests for
1699 optimality by verifying if every connected component is a clique. Returns
1700 true (1) if the above test is true, and false (0) otherwise. */
1702 static int
1703 build_alias_set_optimal_p (vec<data_reference_p> drs)
1705 int num_vertices = drs.length ();
1706 struct graph *g = new_graph (num_vertices);
1707 data_reference_p dr1, dr2;
1708 int i, j;
1709 int num_connected_components;
1710 int v_indx1, v_indx2, num_vertices_in_component;
1711 int *all_vertices;
1712 int *vertices;
1713 struct graph_edge *e;
1714 int this_component_is_clique;
1715 int all_components_are_cliques = 1;
1717 FOR_EACH_VEC_ELT (drs, i, dr1)
1718 for (j = i+1; drs.iterate (j, &dr2); j++)
1719 if (dr_may_alias_p (dr1, dr2, true))
1721 add_edge (g, i, j);
1722 add_edge (g, j, i);
1725 all_vertices = XNEWVEC (int, num_vertices);
1726 vertices = XNEWVEC (int, num_vertices);
1727 for (i = 0; i < num_vertices; i++)
1728 all_vertices[i] = i;
1730 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1731 NULL, true, NULL);
1732 for (i = 0; i < g->n_vertices; i++)
1734 data_reference_p dr = drs[i];
1735 base_alias_pair *bap;
1737 gcc_assert (dr->aux);
1738 bap = (base_alias_pair *)(dr->aux);
1740 bap->alias_set = XNEW (int);
1741 *(bap->alias_set) = g->vertices[i].component + 1;
1744 /* Verify if the DFS numbering results in optimal solution. */
1745 for (i = 0; i < num_connected_components; i++)
1747 num_vertices_in_component = 0;
1748 /* Get all vertices whose DFS component number is the same as i. */
1749 for (j = 0; j < num_vertices; j++)
1750 if (g->vertices[j].component == i)
1751 vertices[num_vertices_in_component++] = j;
1753 /* Now test if the vertices in 'vertices' form a clique, by testing
1754 for edges among each pair. */
1755 this_component_is_clique = 1;
1756 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1758 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1760 /* Check if the two vertices are connected by iterating
1761 through all the edges which have one of these are source. */
1762 e = g->vertices[vertices[v_indx2]].pred;
1763 while (e)
1765 if (e->src == vertices[v_indx1])
1766 break;
1767 e = e->pred_next;
1769 if (!e)
1771 this_component_is_clique = 0;
1772 break;
1775 if (!this_component_is_clique)
1776 all_components_are_cliques = 0;
1780 free (all_vertices);
1781 free (vertices);
1782 free_graph (g);
1783 return all_components_are_cliques;
1786 /* Group each data reference in DRS with its base object set num. */
1788 static void
1789 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1791 int num_vertex = drs.length ();
1792 struct graph *g = new_graph (num_vertex);
1793 data_reference_p dr1, dr2;
1794 int i, j;
1795 int *queue;
1797 FOR_EACH_VEC_ELT (drs, i, dr1)
1798 for (j = i + 1; drs.iterate (j, &dr2); j++)
1799 if (dr_same_base_object_p (dr1, dr2))
1801 add_edge (g, i, j);
1802 add_edge (g, j, i);
1805 queue = XNEWVEC (int, num_vertex);
1806 for (i = 0; i < num_vertex; i++)
1807 queue[i] = i;
1809 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1811 for (i = 0; i < g->n_vertices; i++)
1813 data_reference_p dr = drs[i];
1814 base_alias_pair *bap;
1816 gcc_assert (dr->aux);
1817 bap = (base_alias_pair *)(dr->aux);
1819 bap->base_obj_set = g->vertices[i].component + 1;
1822 free (queue);
1823 free_graph (g);
1826 /* Build the data references for PBB. */
1828 static void
1829 build_pbb_drs (poly_bb_p pbb)
1831 int j;
1832 data_reference_p dr;
1833 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1835 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1836 build_poly_dr (dr, pbb);
1839 /* Dump to file the alias graphs for the data references in DRS. */
1841 static void
1842 dump_alias_graphs (vec<data_reference_p> drs)
1844 char comment[100];
1845 FILE *file_dimacs, *file_ecc, *file_dot;
1847 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1848 if (file_dimacs)
1850 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1851 current_function_name ());
1852 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1853 fclose (file_dimacs);
1856 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1857 if (file_ecc)
1859 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1860 current_function_name ());
1861 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1862 fclose (file_ecc);
1865 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1866 if (file_dot)
1868 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1869 current_function_name ());
1870 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1871 fclose (file_dot);
1875 /* Build data references in SCOP. */
1877 static void
1878 build_scop_drs (scop_p scop)
1880 int i, j;
1881 poly_bb_p pbb;
1882 data_reference_p dr;
1883 vec<data_reference_p> drs;
1884 drs.create (3);
1886 /* Remove all the PBBs that do not have data references: these basic
1887 blocks are not handled in the polyhedral representation. */
1888 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1889 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1891 free_gimple_bb (PBB_BLACK_BOX (pbb));
1892 free_poly_bb (pbb);
1893 SCOP_BBS (scop).ordered_remove (i);
1894 i--;
1897 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1898 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1899 drs.safe_push (dr);
1901 FOR_EACH_VEC_ELT (drs, i, dr)
1902 dr->aux = XNEW (base_alias_pair);
1904 if (!build_alias_set_optimal_p (drs))
1906 /* TODO: Add support when building alias set is not optimal. */
1910 build_base_obj_set_for_drs (drs);
1912 /* When debugging, enable the following code. This cannot be used
1913 in production compilers. */
1914 if (0)
1915 dump_alias_graphs (drs);
1917 drs.release ();
1919 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1920 build_pbb_drs (pbb);
1923 /* Return a gsi at the position of the phi node STMT. */
1925 static gimple_stmt_iterator
1926 gsi_for_phi_node (gimple stmt)
1928 gimple_stmt_iterator psi;
1929 basic_block bb = gimple_bb (stmt);
1931 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1932 if (stmt == gsi_stmt (psi))
1933 return psi;
1935 gcc_unreachable ();
1936 return psi;
1939 /* Analyze all the data references of STMTS and add them to the
1940 GBB_DATA_REFS vector of BB. */
1942 static void
1943 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1945 loop_p nest;
1946 gimple_bb_p gbb;
1947 gimple stmt;
1948 int i;
1949 sese region = SCOP_REGION (scop);
1951 if (!bb_in_sese_p (bb, region))
1952 return;
1954 nest = outermost_loop_in_sese_1 (region, bb);
1955 gbb = gbb_from_bb (bb);
1957 FOR_EACH_VEC_ELT (stmts, i, stmt)
1959 loop_p loop;
1961 if (is_gimple_debug (stmt))
1962 continue;
1964 loop = loop_containing_stmt (stmt);
1965 if (!loop_in_sese_p (loop, region))
1966 loop = nest;
1968 graphite_find_data_references_in_stmt (nest, loop, stmt,
1969 &GBB_DATA_REFS (gbb));
1973 /* Insert STMT at the end of the STMTS sequence and then insert the
1974 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1975 on STMTS. */
1977 static void
1978 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
1979 gimple_stmt_iterator insert_gsi)
1981 gimple_stmt_iterator gsi;
1982 vec<gimple> x;
1983 x.create (3);
1985 gimple_seq_add_stmt (&stmts, stmt);
1986 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
1987 x.safe_push (gsi_stmt (gsi));
1989 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
1990 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1991 x.release ();
1994 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
1996 static void
1997 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
1999 gimple_seq stmts;
2000 gimple_stmt_iterator gsi;
2001 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2002 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2003 vec<gimple> x;
2004 x.create (3);
2006 gimple_seq_add_stmt (&stmts, stmt);
2007 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2008 x.safe_push (gsi_stmt (gsi));
2010 if (gimple_code (after_stmt) == GIMPLE_PHI)
2012 gsi = gsi_after_labels (gimple_bb (after_stmt));
2013 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2015 else
2017 gsi = gsi_for_stmt (after_stmt);
2018 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2021 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2022 x.release ();
2025 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2027 static void
2028 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2030 vec<data_reference_p> drs;
2031 drs.create (3);
2032 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2033 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2034 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2035 int index, n = SCOP_BBS (scop).length ();
2037 /* The INDEX of PBB in SCOP_BBS. */
2038 for (index = 0; index < n; index++)
2039 if (SCOP_BBS (scop)[index] == pbb)
2040 break;
2042 pbb1->domain = isl_set_copy (pbb->domain);
2044 GBB_PBB (gbb1) = pbb1;
2045 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2046 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2047 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2050 /* Insert on edge E the assignment "RES := EXPR". */
2052 static void
2053 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2055 gimple_stmt_iterator gsi;
2056 gimple_seq stmts = NULL;
2057 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2058 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2059 basic_block bb;
2060 vec<gimple> x;
2061 x.create (3);
2063 gimple_seq_add_stmt (&stmts, stmt);
2064 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2065 x.safe_push (gsi_stmt (gsi));
2067 gsi_insert_seq_on_edge (e, stmts);
2068 gsi_commit_edge_inserts ();
2069 bb = gimple_bb (stmt);
2071 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2072 return;
2074 if (!gbb_from_bb (bb))
2075 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2077 analyze_drs_in_stmts (scop, bb, x);
2078 x.release ();
2081 /* Creates a zero dimension array of the same type as VAR. */
2083 static tree
2084 create_zero_dim_array (tree var, const char *base_name)
2086 tree index_type = build_index_type (integer_zero_node);
2087 tree elt_type = TREE_TYPE (var);
2088 tree array_type = build_array_type (elt_type, index_type);
2089 tree base = create_tmp_var (array_type, base_name);
2091 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2092 NULL_TREE);
2095 /* Returns true when PHI is a loop close phi node. */
2097 static bool
2098 scalar_close_phi_node_p (gimple phi)
2100 if (gimple_code (phi) != GIMPLE_PHI
2101 || virtual_operand_p (gimple_phi_result (phi)))
2102 return false;
2104 /* Note that loop close phi nodes should have a single argument
2105 because we translated the representation into a canonical form
2106 before Graphite: see canonicalize_loop_closed_ssa_form. */
2107 return (gimple_phi_num_args (phi) == 1);
2110 /* For a definition DEF in REGION, propagates the expression EXPR in
2111 all the uses of DEF outside REGION. */
2113 static void
2114 propagate_expr_outside_region (tree def, tree expr, sese region)
2116 imm_use_iterator imm_iter;
2117 gimple use_stmt;
2118 gimple_seq stmts;
2119 bool replaced_once = false;
2121 gcc_assert (TREE_CODE (def) == SSA_NAME);
2123 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2124 NULL_TREE);
2126 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2127 if (!is_gimple_debug (use_stmt)
2128 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2130 ssa_op_iter iter;
2131 use_operand_p use_p;
2133 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2134 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2135 && (replaced_once = true))
2136 replace_exp (use_p, expr);
2138 update_stmt (use_stmt);
2141 if (replaced_once)
2143 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2144 gsi_commit_edge_inserts ();
2148 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2149 dimension array for it. */
2151 static void
2152 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2154 sese region = SCOP_REGION (scop);
2155 gimple phi = gsi_stmt (*psi);
2156 tree res = gimple_phi_result (phi);
2157 basic_block bb = gimple_bb (phi);
2158 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2159 tree arg = gimple_phi_arg_def (phi, 0);
2160 gimple stmt;
2162 /* Note that loop close phi nodes should have a single argument
2163 because we translated the representation into a canonical form
2164 before Graphite: see canonicalize_loop_closed_ssa_form. */
2165 gcc_assert (gimple_phi_num_args (phi) == 1);
2167 /* The phi node can be a non close phi node, when its argument is
2168 invariant, or a default definition. */
2169 if (is_gimple_min_invariant (arg)
2170 || SSA_NAME_IS_DEFAULT_DEF (arg))
2172 propagate_expr_outside_region (res, arg, region);
2173 gsi_next (psi);
2174 return;
2177 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2179 propagate_expr_outside_region (res, arg, region);
2180 stmt = gimple_build_assign (res, arg);
2181 remove_phi_node (psi, false);
2182 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2183 SSA_NAME_DEF_STMT (res) = stmt;
2184 return;
2187 /* If res is scev analyzable and is not a scalar value, it is safe
2188 to ignore the close phi node: it will be code generated in the
2189 out of Graphite pass. */
2190 else if (scev_analyzable_p (res, region))
2192 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2193 tree scev;
2195 if (!loop_in_sese_p (loop, region))
2197 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2198 scev = scalar_evolution_in_region (region, loop, arg);
2199 scev = compute_overall_effect_of_inner_loop (loop, scev);
2201 else
2202 scev = scalar_evolution_in_region (region, loop, res);
2204 if (tree_does_not_contain_chrecs (scev))
2205 propagate_expr_outside_region (res, scev, region);
2207 gsi_next (psi);
2208 return;
2210 else
2212 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2214 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2216 if (TREE_CODE (arg) == SSA_NAME)
2217 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2218 SSA_NAME_DEF_STMT (arg));
2219 else
2220 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2221 zero_dim_array, arg);
2224 remove_phi_node (psi, false);
2225 SSA_NAME_DEF_STMT (res) = stmt;
2227 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2230 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2231 dimension array for it. */
2233 static void
2234 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2236 size_t i;
2237 gimple phi = gsi_stmt (*psi);
2238 basic_block bb = gimple_bb (phi);
2239 tree res = gimple_phi_result (phi);
2240 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2241 gimple stmt;
2243 for (i = 0; i < gimple_phi_num_args (phi); i++)
2245 tree arg = gimple_phi_arg_def (phi, i);
2246 edge e = gimple_phi_arg_edge (phi, i);
2248 /* Avoid the insertion of code in the loop latch to please the
2249 pattern matching of the vectorizer. */
2250 if (TREE_CODE (arg) == SSA_NAME
2251 && e->src == bb->loop_father->latch)
2252 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2253 SSA_NAME_DEF_STMT (arg));
2254 else
2255 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2258 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2259 remove_phi_node (psi, false);
2260 SSA_NAME_DEF_STMT (res) = stmt;
2261 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2264 /* Rewrite the degenerate phi node at position PSI from the degenerate
2265 form "x = phi (y, y, ..., y)" to "x = y". */
2267 static void
2268 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2270 tree rhs;
2271 gimple stmt;
2272 gimple_stmt_iterator gsi;
2273 gimple phi = gsi_stmt (*psi);
2274 tree res = gimple_phi_result (phi);
2275 basic_block bb;
2277 bb = gimple_bb (phi);
2278 rhs = degenerate_phi_result (phi);
2279 gcc_assert (rhs);
2281 stmt = gimple_build_assign (res, rhs);
2282 remove_phi_node (psi, false);
2283 SSA_NAME_DEF_STMT (res) = stmt;
2285 gsi = gsi_after_labels (bb);
2286 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2289 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2291 static void
2292 rewrite_reductions_out_of_ssa (scop_p scop)
2294 basic_block bb;
2295 gimple_stmt_iterator psi;
2296 sese region = SCOP_REGION (scop);
2298 FOR_EACH_BB (bb)
2299 if (bb_in_sese_p (bb, region))
2300 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2302 gimple phi = gsi_stmt (psi);
2304 if (virtual_operand_p (gimple_phi_result (phi)))
2306 gsi_next (&psi);
2307 continue;
2310 if (gimple_phi_num_args (phi) > 1
2311 && degenerate_phi_result (phi))
2312 rewrite_degenerate_phi (&psi);
2314 else if (scalar_close_phi_node_p (phi))
2315 rewrite_close_phi_out_of_ssa (scop, &psi);
2317 else if (reduction_phi_p (region, &psi))
2318 rewrite_phi_out_of_ssa (scop, &psi);
2321 update_ssa (TODO_update_ssa);
2322 #ifdef ENABLE_CHECKING
2323 verify_loop_closed_ssa (true);
2324 #endif
2327 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2328 read from ZERO_DIM_ARRAY. */
2330 static void
2331 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2332 tree def, gimple use_stmt)
2334 gimple name_stmt;
2335 tree name;
2336 ssa_op_iter iter;
2337 use_operand_p use_p;
2339 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2341 name = copy_ssa_name (def, NULL);
2342 name_stmt = gimple_build_assign (name, zero_dim_array);
2344 gimple_assign_set_lhs (name_stmt, name);
2345 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2347 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2348 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2349 replace_exp (use_p, name);
2351 update_stmt (use_stmt);
2354 /* For every definition DEF in the SCOP that is used outside the scop,
2355 insert a closing-scop definition in the basic block just after this
2356 SCOP. */
2358 static void
2359 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2361 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2362 tree new_name = make_ssa_name (var, stmt);
2363 bool needs_copy = false;
2364 use_operand_p use_p;
2365 imm_use_iterator imm_iter;
2366 gimple use_stmt;
2367 sese region = SCOP_REGION (scop);
2369 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2371 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2373 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2375 SET_USE (use_p, new_name);
2377 update_stmt (use_stmt);
2378 needs_copy = true;
2382 /* Insert in the empty BB just after the scop a use of DEF such
2383 that the rewrite of cross_bb_scalar_dependences won't insert
2384 arrays everywhere else. */
2385 if (needs_copy)
2387 gimple assign = gimple_build_assign (new_name, def);
2388 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2390 SSA_NAME_DEF_STMT (new_name) = assign;
2391 update_stmt (assign);
2392 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2396 /* Rewrite the scalar dependences crossing the boundary of the BB
2397 containing STMT with an array. Return true when something has been
2398 changed. */
2400 static bool
2401 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2403 sese region = SCOP_REGION (scop);
2404 gimple stmt = gsi_stmt (*gsi);
2405 imm_use_iterator imm_iter;
2406 tree def;
2407 basic_block def_bb;
2408 tree zero_dim_array = NULL_TREE;
2409 gimple use_stmt;
2410 bool res = false;
2412 switch (gimple_code (stmt))
2414 case GIMPLE_ASSIGN:
2415 def = gimple_assign_lhs (stmt);
2416 break;
2418 case GIMPLE_CALL:
2419 def = gimple_call_lhs (stmt);
2420 break;
2422 default:
2423 return false;
2426 if (!def
2427 || !is_gimple_reg (def))
2428 return false;
2430 if (scev_analyzable_p (def, region))
2432 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2433 tree scev = scalar_evolution_in_region (region, loop, def);
2435 if (tree_contains_chrecs (scev, NULL))
2436 return false;
2438 propagate_expr_outside_region (def, scev, region);
2439 return true;
2442 def_bb = gimple_bb (stmt);
2444 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2446 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2447 if (gimple_code (use_stmt) == GIMPLE_PHI
2448 && (res = true))
2450 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2452 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2453 rewrite_close_phi_out_of_ssa (scop, &psi);
2454 else
2455 rewrite_phi_out_of_ssa (scop, &psi);
2458 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2459 if (gimple_code (use_stmt) != GIMPLE_PHI
2460 && def_bb != gimple_bb (use_stmt)
2461 && !is_gimple_debug (use_stmt)
2462 && (res = true))
2464 if (!zero_dim_array)
2466 zero_dim_array = create_zero_dim_array
2467 (def, "Cross_BB_scalar_dependence");
2468 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2469 SSA_NAME_DEF_STMT (def));
2470 gsi_next (gsi);
2473 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2474 def, use_stmt);
2477 return res;
2480 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2482 static void
2483 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2485 basic_block bb;
2486 gimple_stmt_iterator psi;
2487 sese region = SCOP_REGION (scop);
2488 bool changed = false;
2490 /* Create an extra empty BB after the scop. */
2491 split_edge (SESE_EXIT (region));
2493 FOR_EACH_BB (bb)
2494 if (bb_in_sese_p (bb, region))
2495 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2496 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2498 if (changed)
2500 scev_reset_htab ();
2501 update_ssa (TODO_update_ssa);
2502 #ifdef ENABLE_CHECKING
2503 verify_loop_closed_ssa (true);
2504 #endif
2508 /* Returns the number of pbbs that are in loops contained in SCOP. */
2510 static int
2511 nb_pbbs_in_loops (scop_p scop)
2513 int i;
2514 poly_bb_p pbb;
2515 int res = 0;
2517 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2518 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2519 res++;
2521 return res;
2524 /* Return the number of data references in BB that write in
2525 memory. */
2527 static int
2528 nb_data_writes_in_bb (basic_block bb)
2530 int res = 0;
2531 gimple_stmt_iterator gsi;
2533 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2534 if (gimple_vdef (gsi_stmt (gsi)))
2535 res++;
2537 return res;
2540 /* Splits at STMT the basic block BB represented as PBB in the
2541 polyhedral form. */
2543 static edge
2544 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2546 edge e1 = split_block (bb, stmt);
2547 new_pbb_from_pbb (scop, pbb, e1->dest);
2548 return e1;
2551 /* Splits STMT out of its current BB. This is done for reduction
2552 statements for which we want to ignore data dependences. */
2554 static basic_block
2555 split_reduction_stmt (scop_p scop, gimple stmt)
2557 basic_block bb = gimple_bb (stmt);
2558 poly_bb_p pbb = pbb_from_bb (bb);
2559 gimple_bb_p gbb = gbb_from_bb (bb);
2560 edge e1;
2561 int i;
2562 data_reference_p dr;
2564 /* Do not split basic blocks with no writes to memory: the reduction
2565 will be the only write to memory. */
2566 if (nb_data_writes_in_bb (bb) == 0
2567 /* Or if we have already marked BB as a reduction. */
2568 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2569 return bb;
2571 e1 = split_pbb (scop, pbb, bb, stmt);
2573 /* Split once more only when the reduction stmt is not the only one
2574 left in the original BB. */
2575 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2577 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2578 gsi_prev (&gsi);
2579 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2582 /* A part of the data references will end in a different basic block
2583 after the split: move the DRs from the original GBB to the newly
2584 created GBB1. */
2585 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2587 basic_block bb1 = gimple_bb (DR_STMT (dr));
2589 if (bb1 != bb)
2591 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2592 GBB_DATA_REFS (gbb1).safe_push (dr);
2593 GBB_DATA_REFS (gbb).ordered_remove (i);
2594 i--;
2598 return e1->dest;
2601 /* Return true when stmt is a reduction operation. */
2603 static inline bool
2604 is_reduction_operation_p (gimple stmt)
2606 enum tree_code code;
2608 gcc_assert (is_gimple_assign (stmt));
2609 code = gimple_assign_rhs_code (stmt);
2611 return flag_associative_math
2612 && commutative_tree_code (code)
2613 && associative_tree_code (code);
2616 /* Returns true when PHI contains an argument ARG. */
2618 static bool
2619 phi_contains_arg (gimple phi, tree arg)
2621 size_t i;
2623 for (i = 0; i < gimple_phi_num_args (phi); i++)
2624 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2625 return true;
2627 return false;
2630 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2632 static gimple
2633 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2635 gimple stmt;
2637 if (TREE_CODE (arg) != SSA_NAME)
2638 return NULL;
2640 stmt = SSA_NAME_DEF_STMT (arg);
2642 if (gimple_code (stmt) == GIMPLE_NOP
2643 || gimple_code (stmt) == GIMPLE_CALL)
2644 return NULL;
2646 if (gimple_code (stmt) == GIMPLE_PHI)
2648 if (phi_contains_arg (stmt, lhs))
2649 return stmt;
2650 return NULL;
2653 if (!is_gimple_assign (stmt))
2654 return NULL;
2656 if (gimple_num_ops (stmt) == 2)
2657 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2659 if (is_reduction_operation_p (stmt))
2661 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2663 return res ? res :
2664 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2667 return NULL;
2670 /* Detect commutative and associative scalar reductions starting at
2671 the STMT. Return the phi node of the reduction cycle, or NULL. */
2673 static gimple
2674 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2675 vec<gimple> *in,
2676 vec<gimple> *out)
2678 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2680 if (!phi)
2681 return NULL;
2683 in->safe_push (stmt);
2684 out->safe_push (stmt);
2685 return phi;
2688 /* Detect commutative and associative scalar reductions starting at
2689 STMT. Return the phi node of the reduction cycle, or NULL. */
2691 static gimple
2692 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2693 vec<gimple> *out)
2695 tree lhs = gimple_assign_lhs (stmt);
2697 if (gimple_num_ops (stmt) == 2)
2698 return detect_commutative_reduction_arg (lhs, stmt,
2699 gimple_assign_rhs1 (stmt),
2700 in, out);
2702 if (is_reduction_operation_p (stmt))
2704 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2705 gimple_assign_rhs1 (stmt),
2706 in, out);
2707 return res ? res
2708 : detect_commutative_reduction_arg (lhs, stmt,
2709 gimple_assign_rhs2 (stmt),
2710 in, out);
2713 return NULL;
2716 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2718 static gimple
2719 follow_inital_value_to_phi (tree arg, tree lhs)
2721 gimple stmt;
2723 if (!arg || TREE_CODE (arg) != SSA_NAME)
2724 return NULL;
2726 stmt = SSA_NAME_DEF_STMT (arg);
2728 if (gimple_code (stmt) == GIMPLE_PHI
2729 && phi_contains_arg (stmt, lhs))
2730 return stmt;
2732 return NULL;
2736 /* Return the argument of the loop PHI that is the initial value coming
2737 from outside the loop. */
2739 static edge
2740 edge_initial_value_for_loop_phi (gimple phi)
2742 size_t i;
2744 for (i = 0; i < gimple_phi_num_args (phi); i++)
2746 edge e = gimple_phi_arg_edge (phi, i);
2748 if (loop_depth (e->src->loop_father)
2749 < loop_depth (e->dest->loop_father))
2750 return e;
2753 return NULL;
2756 /* Return the argument of the loop PHI that is the initial value coming
2757 from outside the loop. */
2759 static tree
2760 initial_value_for_loop_phi (gimple phi)
2762 size_t i;
2764 for (i = 0; i < gimple_phi_num_args (phi); i++)
2766 edge e = gimple_phi_arg_edge (phi, i);
2768 if (loop_depth (e->src->loop_father)
2769 < loop_depth (e->dest->loop_father))
2770 return gimple_phi_arg_def (phi, i);
2773 return NULL_TREE;
2776 /* Returns true when DEF is used outside the reduction cycle of
2777 LOOP_PHI. */
2779 static bool
2780 used_outside_reduction (tree def, gimple loop_phi)
2782 use_operand_p use_p;
2783 imm_use_iterator imm_iter;
2784 loop_p loop = loop_containing_stmt (loop_phi);
2786 /* In LOOP, DEF should be used only in LOOP_PHI. */
2787 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2789 gimple stmt = USE_STMT (use_p);
2791 if (stmt != loop_phi
2792 && !is_gimple_debug (stmt)
2793 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2794 return true;
2797 return false;
2800 /* Detect commutative and associative scalar reductions belonging to
2801 the SCOP starting at the loop closed phi node STMT. Return the phi
2802 node of the reduction cycle, or NULL. */
2804 static gimple
2805 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2806 vec<gimple> *out)
2808 if (scalar_close_phi_node_p (stmt))
2810 gimple def, loop_phi, phi, close_phi = stmt;
2811 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2813 if (TREE_CODE (arg) != SSA_NAME)
2814 return NULL;
2816 /* Note that loop close phi nodes should have a single argument
2817 because we translated the representation into a canonical form
2818 before Graphite: see canonicalize_loop_closed_ssa_form. */
2819 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2821 def = SSA_NAME_DEF_STMT (arg);
2822 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2823 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2824 return NULL;
2826 lhs = gimple_phi_result (close_phi);
2827 init = initial_value_for_loop_phi (loop_phi);
2828 phi = follow_inital_value_to_phi (init, lhs);
2830 if (phi && (used_outside_reduction (lhs, phi)
2831 || !has_single_use (gimple_phi_result (phi))))
2832 return NULL;
2834 in->safe_push (loop_phi);
2835 out->safe_push (close_phi);
2836 return phi;
2839 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2840 return detect_commutative_reduction_assign (stmt, in, out);
2842 return NULL;
2845 /* Translate the scalar reduction statement STMT to an array RED
2846 knowing that its recursive phi node is LOOP_PHI. */
2848 static void
2849 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2850 gimple stmt, gimple loop_phi)
2852 tree res = gimple_phi_result (loop_phi);
2853 gimple assign = gimple_build_assign (res, unshare_expr (red));
2854 gimple_stmt_iterator gsi;
2856 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2858 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2859 gsi = gsi_for_stmt (stmt);
2860 gsi_next (&gsi);
2861 insert_stmts (scop, assign, NULL, gsi);
2864 /* Removes the PHI node and resets all the debug stmts that are using
2865 the PHI_RESULT. */
2867 static void
2868 remove_phi (gimple phi)
2870 imm_use_iterator imm_iter;
2871 tree def;
2872 use_operand_p use_p;
2873 gimple_stmt_iterator gsi;
2874 vec<gimple> update;
2875 update.create (3);
2876 unsigned int i;
2877 gimple stmt;
2879 def = PHI_RESULT (phi);
2880 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2882 stmt = USE_STMT (use_p);
2884 if (is_gimple_debug (stmt))
2886 gimple_debug_bind_reset_value (stmt);
2887 update.safe_push (stmt);
2891 FOR_EACH_VEC_ELT (update, i, stmt)
2892 update_stmt (stmt);
2894 update.release ();
2896 gsi = gsi_for_phi_node (phi);
2897 remove_phi_node (&gsi, false);
2900 /* Helper function for for_each_index. For each INDEX of the data
2901 reference REF, returns true when its indices are valid in the loop
2902 nest LOOP passed in as DATA. */
2904 static bool
2905 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2907 loop_p loop;
2908 basic_block header, def_bb;
2909 gimple stmt;
2911 if (TREE_CODE (*index) != SSA_NAME)
2912 return true;
2914 loop = *((loop_p *) data);
2915 header = loop->header;
2916 stmt = SSA_NAME_DEF_STMT (*index);
2918 if (!stmt)
2919 return true;
2921 def_bb = gimple_bb (stmt);
2923 if (!def_bb)
2924 return true;
2926 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2929 /* When the result of a CLOSE_PHI is written to a memory location,
2930 return a pointer to that memory reference, otherwise return
2931 NULL_TREE. */
2933 static tree
2934 close_phi_written_to_memory (gimple close_phi)
2936 imm_use_iterator imm_iter;
2937 use_operand_p use_p;
2938 gimple stmt;
2939 tree res, def = gimple_phi_result (close_phi);
2941 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2942 if ((stmt = USE_STMT (use_p))
2943 && gimple_code (stmt) == GIMPLE_ASSIGN
2944 && (res = gimple_assign_lhs (stmt)))
2946 switch (TREE_CODE (res))
2948 case VAR_DECL:
2949 case PARM_DECL:
2950 case RESULT_DECL:
2951 return res;
2953 case ARRAY_REF:
2954 case MEM_REF:
2956 tree arg = gimple_phi_arg_def (close_phi, 0);
2957 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2959 /* FIXME: this restriction is for id-{24,25}.f and
2960 could be handled by duplicating the computation of
2961 array indices before the loop of the close_phi. */
2962 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2963 return res;
2965 /* Fallthru. */
2967 default:
2968 continue;
2971 return NULL_TREE;
2974 /* Rewrite out of SSA the reduction described by the loop phi nodes
2975 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2976 levels like this:
2978 IN: stmt, loop_n, ..., loop_0
2979 OUT: stmt, close_n, ..., close_0
2981 the first element is the reduction statement, and the next elements
2982 are the loop and close phi nodes of each of the outer loops. */
2984 static void
2985 translate_scalar_reduction_to_array (scop_p scop,
2986 vec<gimple> in,
2987 vec<gimple> out)
2989 gimple loop_phi;
2990 unsigned int i = out.length () - 1;
2991 tree red = close_phi_written_to_memory (out[i]);
2993 FOR_EACH_VEC_ELT (in, i, loop_phi)
2995 gimple close_phi = out[i];
2997 if (i == 0)
2999 gimple stmt = loop_phi;
3000 basic_block bb = split_reduction_stmt (scop, stmt);
3001 poly_bb_p pbb = pbb_from_bb (bb);
3002 PBB_IS_REDUCTION (pbb) = true;
3003 gcc_assert (close_phi == loop_phi);
3005 if (!red)
3006 red = create_zero_dim_array
3007 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3009 translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
3010 continue;
3013 if (i == in.length () - 1)
3015 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3016 unshare_expr (red), close_phi);
3017 insert_out_of_ssa_copy_on_edge
3018 (scop, edge_initial_value_for_loop_phi (loop_phi),
3019 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3022 remove_phi (loop_phi);
3023 remove_phi (close_phi);
3027 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3028 true when something has been changed. */
3030 static bool
3031 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3032 gimple close_phi)
3034 bool res;
3035 vec<gimple> in;
3036 in.create (10);
3037 vec<gimple> out;
3038 out.create (10);
3040 detect_commutative_reduction (scop, close_phi, &in, &out);
3041 res = in.length () > 1;
3042 if (res)
3043 translate_scalar_reduction_to_array (scop, in, out);
3045 in.release ();
3046 out.release ();
3047 return res;
3050 /* Rewrites all the commutative reductions from LOOP out of SSA.
3051 Returns true when something has been changed. */
3053 static bool
3054 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3055 loop_p loop)
3057 gimple_stmt_iterator gsi;
3058 edge exit = single_exit (loop);
3059 tree res;
3060 bool changed = false;
3062 if (!exit)
3063 return false;
3065 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3066 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3067 && !virtual_operand_p (res)
3068 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3069 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3070 (scop, gsi_stmt (gsi));
3072 return changed;
3075 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3077 static void
3078 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3080 loop_iterator li;
3081 loop_p loop;
3082 bool changed = false;
3083 sese region = SCOP_REGION (scop);
3085 FOR_EACH_LOOP (li, loop, 0)
3086 if (loop_in_sese_p (loop, region))
3087 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3089 if (changed)
3091 scev_reset_htab ();
3092 gsi_commit_edge_inserts ();
3093 update_ssa (TODO_update_ssa);
3094 #ifdef ENABLE_CHECKING
3095 verify_loop_closed_ssa (true);
3096 #endif
3100 /* Can all ivs be represented by a signed integer?
3101 As CLooG might generate negative values in its expressions, signed loop ivs
3102 are required in the backend. */
3104 static bool
3105 scop_ivs_can_be_represented (scop_p scop)
3107 loop_iterator li;
3108 loop_p loop;
3109 gimple_stmt_iterator psi;
3110 bool result = true;
3112 FOR_EACH_LOOP (li, 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 gimple phi = gsi_stmt (psi);
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 FOR_EACH_LOOP_BREAK (li);
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