2012-12-01 Alessandro Fanfarillo <alessandro.fanfarillo@gmail.com>
[official-gcc.git] / gcc / graphite-sese-to-poly.c
blob4e95f78bbfab454547947949f823a6f5c3e457f1
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009, 2010, 2011 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-flow.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"
45 #ifdef HAVE_cloog
46 #include "graphite-poly.h"
47 #include "graphite-sese-to-poly.h"
50 /* Assigns to RES the value of the INTEGER_CST T. */
52 static inline void
53 tree_int_to_gmp (tree t, mpz_t res)
55 double_int di = tree_to_double_int (t);
56 mpz_set_double_int (res, di, TYPE_UNSIGNED (TREE_TYPE (t)));
59 /* Returns the index of the PHI argument defined in the outermost
60 loop. */
62 static size_t
63 phi_arg_in_outermost_loop (gimple phi)
65 loop_p loop = gimple_bb (phi)->loop_father;
66 size_t i, res = 0;
68 for (i = 0; i < gimple_phi_num_args (phi); i++)
69 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
71 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
72 res = i;
75 return res;
78 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
79 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
81 static void
82 remove_simple_copy_phi (gimple_stmt_iterator *psi)
84 gimple phi = gsi_stmt (*psi);
85 tree res = gimple_phi_result (phi);
86 size_t entry = phi_arg_in_outermost_loop (phi);
87 tree init = gimple_phi_arg_def (phi, entry);
88 gimple stmt = gimple_build_assign (res, init);
89 edge e = gimple_phi_arg_edge (phi, entry);
91 remove_phi_node (psi, false);
92 gsi_insert_on_edge_immediate (e, stmt);
93 SSA_NAME_DEF_STMT (res) = stmt;
96 /* Removes an invariant phi node at position PSI by inserting on the
97 loop ENTRY edge the assignment RES = INIT. */
99 static void
100 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
102 gimple phi = gsi_stmt (*psi);
103 loop_p loop = loop_containing_stmt (phi);
104 tree res = gimple_phi_result (phi);
105 tree scev = scalar_evolution_in_region (region, loop, res);
106 size_t entry = phi_arg_in_outermost_loop (phi);
107 edge e = gimple_phi_arg_edge (phi, entry);
108 tree var;
109 gimple stmt;
110 gimple_seq stmts = NULL;
112 if (tree_contains_chrecs (scev, NULL))
113 scev = gimple_phi_arg_def (phi, entry);
115 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
116 stmt = gimple_build_assign (res, var);
117 remove_phi_node (psi, false);
119 gimple_seq_add_stmt (&stmts, stmt);
120 gsi_insert_seq_on_edge (e, stmts);
121 gsi_commit_edge_inserts ();
122 SSA_NAME_DEF_STMT (res) = stmt;
125 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
127 static inline bool
128 simple_copy_phi_p (gimple phi)
130 tree res;
132 if (gimple_phi_num_args (phi) != 2)
133 return false;
135 res = gimple_phi_result (phi);
136 return (res == gimple_phi_arg_def (phi, 0)
137 || res == gimple_phi_arg_def (phi, 1));
140 /* Returns true when the phi node at position PSI is a reduction phi
141 node in REGION. Otherwise moves the pointer PSI to the next phi to
142 be considered. */
144 static bool
145 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
147 loop_p loop;
148 gimple phi = gsi_stmt (*psi);
149 tree res = gimple_phi_result (phi);
151 loop = loop_containing_stmt (phi);
153 if (simple_copy_phi_p (phi))
155 /* PRE introduces phi nodes like these, for an example,
156 see id-5.f in the fortran graphite testsuite:
158 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
160 remove_simple_copy_phi (psi);
161 return false;
164 if (scev_analyzable_p (res, region))
166 tree scev = scalar_evolution_in_region (region, loop, res);
168 if (evolution_function_is_invariant_p (scev, loop->num))
169 remove_invariant_phi (region, psi);
170 else
171 gsi_next (psi);
173 return false;
176 /* All the other cases are considered reductions. */
177 return true;
180 /* Store the GRAPHITE representation of BB. */
182 static gimple_bb_p
183 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
185 struct gimple_bb *gbb;
187 gbb = XNEW (struct gimple_bb);
188 bb->aux = gbb;
189 GBB_BB (gbb) = bb;
190 GBB_DATA_REFS (gbb) = drs;
191 GBB_CONDITIONS (gbb).create (0);
192 GBB_CONDITION_CASES (gbb).create (0);
194 return gbb;
197 static void
198 free_data_refs_aux (vec<data_reference_p> datarefs)
200 unsigned int i;
201 struct data_reference *dr;
203 FOR_EACH_VEC_ELT (datarefs, i, dr)
204 if (dr->aux)
206 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
208 free (bap->alias_set);
210 free (bap);
211 dr->aux = NULL;
214 /* Frees GBB. */
216 static void
217 free_gimple_bb (struct gimple_bb *gbb)
219 free_data_refs_aux (GBB_DATA_REFS (gbb));
220 free_data_refs (GBB_DATA_REFS (gbb));
222 GBB_CONDITIONS (gbb).release ();
223 GBB_CONDITION_CASES (gbb).release ();
224 GBB_BB (gbb)->aux = 0;
225 XDELETE (gbb);
228 /* Deletes all gimple bbs in SCOP. */
230 static void
231 remove_gbbs_in_scop (scop_p scop)
233 int i;
234 poly_bb_p pbb;
236 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
237 free_gimple_bb (PBB_BLACK_BOX (pbb));
240 /* Deletes all scops in SCOPS. */
242 void
243 free_scops (vec<scop_p> scops)
245 int i;
246 scop_p scop;
248 FOR_EACH_VEC_ELT (scops, i, scop)
250 remove_gbbs_in_scop (scop);
251 free_sese (SCOP_REGION (scop));
252 free_scop (scop);
255 scops.release ();
258 /* Same as outermost_loop_in_sese, returns the outermost loop
259 containing BB in REGION, but makes sure that the returned loop
260 belongs to the REGION, and so this returns the first loop in the
261 REGION when the loop containing BB does not belong to REGION. */
263 static loop_p
264 outermost_loop_in_sese_1 (sese region, basic_block bb)
266 loop_p nest = outermost_loop_in_sese (region, bb);
268 if (loop_in_sese_p (nest, region))
269 return nest;
271 /* When the basic block BB does not belong to a loop in the region,
272 return the first loop in the region. */
273 nest = nest->inner;
274 while (nest)
275 if (loop_in_sese_p (nest, region))
276 break;
277 else
278 nest = nest->next;
280 gcc_assert (nest);
281 return nest;
284 /* Generates a polyhedral black box only if the bb contains interesting
285 information. */
287 static gimple_bb_p
288 try_generate_gimple_bb (scop_p scop, basic_block bb)
290 vec<data_reference_p> drs;
291 drs.create (5);
292 sese region = SCOP_REGION (scop);
293 loop_p nest = outermost_loop_in_sese_1 (region, bb);
294 gimple_stmt_iterator gsi;
296 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
298 gimple stmt = gsi_stmt (gsi);
299 loop_p loop;
301 if (is_gimple_debug (stmt))
302 continue;
304 loop = loop_containing_stmt (stmt);
305 if (!loop_in_sese_p (loop, region))
306 loop = nest;
308 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
311 return new_gimple_bb (bb, drs);
314 /* Returns true if all predecessors of BB, that are not dominated by BB, are
315 marked in MAP. The predecessors dominated by BB are loop latches and will
316 be handled after BB. */
318 static bool
319 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
321 edge e;
322 edge_iterator ei;
324 FOR_EACH_EDGE (e, ei, bb->preds)
325 if (!bitmap_bit_p (map, e->src->index)
326 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
327 return false;
329 return true;
332 /* Compare the depth of two basic_block's P1 and P2. */
334 static int
335 compare_bb_depths (const void *p1, const void *p2)
337 const_basic_block const bb1 = *(const_basic_block const*)p1;
338 const_basic_block const bb2 = *(const_basic_block const*)p2;
339 int d1 = loop_depth (bb1->loop_father);
340 int d2 = loop_depth (bb2->loop_father);
342 if (d1 < d2)
343 return 1;
345 if (d1 > d2)
346 return -1;
348 return 0;
351 /* Sort the basic blocks from DOM such that the first are the ones at
352 a deepest loop level. */
354 static void
355 graphite_sort_dominated_info (vec<basic_block> dom)
357 dom.qsort (compare_bb_depths);
360 /* Recursive helper function for build_scops_bbs. */
362 static void
363 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
365 sese region = SCOP_REGION (scop);
366 vec<basic_block> dom;
367 poly_bb_p pbb;
369 if (bitmap_bit_p (visited, bb->index)
370 || !bb_in_sese_p (bb, region))
371 return;
373 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
374 SCOP_BBS (scop).safe_push (pbb);
375 bitmap_set_bit (visited, bb->index);
377 dom = get_dominated_by (CDI_DOMINATORS, bb);
379 if (!dom.exists ())
380 return;
382 graphite_sort_dominated_info (dom);
384 while (!dom.is_empty ())
386 int i;
387 basic_block dom_bb;
389 FOR_EACH_VEC_ELT (dom, i, dom_bb)
390 if (all_non_dominated_preds_marked_p (dom_bb, visited))
392 build_scop_bbs_1 (scop, visited, dom_bb);
393 dom.unordered_remove (i);
394 break;
398 dom.release ();
401 /* Gather the basic blocks belonging to the SCOP. */
403 static void
404 build_scop_bbs (scop_p scop)
406 sbitmap visited = sbitmap_alloc (last_basic_block);
407 sese region = SCOP_REGION (scop);
409 bitmap_clear (visited);
410 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
411 sbitmap_free (visited);
414 /* Return an ISL identifier for the polyhedral basic block PBB. */
416 static isl_id *
417 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
419 char name[50];
420 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
421 return isl_id_alloc (s->ctx, name, pbb);
424 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
425 We generate SCATTERING_DIMENSIONS scattering dimensions.
427 CLooG 0.15.0 and previous versions require, that all
428 scattering functions of one CloogProgram have the same number of
429 scattering dimensions, therefore we allow to specify it. This
430 should be removed in future versions of CLooG.
432 The scattering polyhedron consists of these dimensions: scattering,
433 loop_iterators, parameters.
435 Example:
437 | scattering_dimensions = 5
438 | used_scattering_dimensions = 3
439 | nb_iterators = 1
440 | scop_nb_params = 2
442 | Schedule:
444 | 4 5
446 | Scattering polyhedron:
448 | scattering: {s1, s2, s3, s4, s5}
449 | loop_iterators: {i}
450 | parameters: {p1, p2}
452 | s1 s2 s3 s4 s5 i p1 p2 1
453 | 1 0 0 0 0 0 0 0 -4 = 0
454 | 0 1 0 0 0 -1 0 0 0 = 0
455 | 0 0 1 0 0 0 0 0 -5 = 0 */
457 static void
458 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
459 poly_bb_p pbb, int scattering_dimensions)
461 int i;
462 int nb_iterators = pbb_dim_iter_domain (pbb);
463 int used_scattering_dimensions = nb_iterators * 2 + 1;
464 isl_int val;
465 isl_space *dc, *dm;
467 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
469 isl_int_init (val);
471 dc = isl_set_get_space (pbb->domain);
472 dm = isl_space_add_dims (isl_space_from_domain (dc),
473 isl_dim_out, scattering_dimensions);
474 pbb->schedule = isl_map_universe (dm);
476 for (i = 0; i < scattering_dimensions; i++)
478 /* Textual order inside this loop. */
479 if ((i % 2) == 0)
481 isl_constraint *c = isl_equality_alloc
482 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
484 if (0 != isl_aff_get_coefficient (static_sched, isl_dim_in,
485 i / 2, &val))
486 gcc_unreachable ();
488 isl_int_neg (val, val);
489 c = isl_constraint_set_constant (c, val);
490 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
491 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
494 /* Iterations of this loop. */
495 else /* if ((i % 2) == 1) */
497 int loop = (i - 1) / 2;
498 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
499 isl_dim_out, i);
503 isl_int_clear (val);
505 pbb->transformed = isl_map_copy (pbb->schedule);
508 /* Build for BB the static schedule.
510 The static schedule is a Dewey numbering of the abstract syntax
511 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
513 The following example informally defines the static schedule:
516 for (i: ...)
518 for (j: ...)
524 for (k: ...)
532 Static schedules for A to F:
534 DEPTH
535 0 1 2
537 B 1 0 0
538 C 1 0 1
539 D 1 1 0
540 E 1 1 1
544 static void
545 build_scop_scattering (scop_p scop)
547 int i;
548 poly_bb_p pbb;
549 gimple_bb_p previous_gbb = NULL;
550 isl_space *dc = isl_set_get_space (scop->context);
551 isl_aff *static_sched;
553 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops());
554 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
556 /* We have to start schedules at 0 on the first component and
557 because we cannot compare_prefix_loops against a previous loop,
558 prefix will be equal to zero, and that index will be
559 incremented before copying. */
560 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
562 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
564 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
565 int prefix;
566 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
568 if (previous_gbb)
569 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
570 else
571 prefix = 0;
573 previous_gbb = gbb;
575 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
576 prefix, 1);
577 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
580 isl_aff_free (static_sched);
583 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
585 /* Extract an affine expression from the chain of recurrence E. */
587 static isl_pw_aff *
588 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
590 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
591 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
592 isl_local_space *ls = isl_local_space_from_space (space);
593 unsigned pos = sese_loop_depth ((sese) s->region,
594 get_loop (CHREC_VARIABLE (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);
1062 else
1063 gcc_unreachable ();
1065 if (loop->inner && loop_in_sese_p (loop->inner, region))
1066 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1067 isl_set_copy (inner), doms);
1069 if (nb != 0
1070 && loop->next
1071 && loop_in_sese_p (loop->next, region))
1072 build_loop_iteration_domains (scop, loop->next, nb,
1073 isl_set_copy (outer), doms);
1075 doms[loop->num] = inner;
1077 isl_set_free (outer);
1078 isl_space_free (space);
1079 isl_int_clear (v);
1080 mpz_clear (g);
1083 /* Returns a linear expression for tree T evaluated in PBB. */
1085 static isl_pw_aff *
1086 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1088 scop_p scop = PBB_SCOP (pbb);
1090 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1091 gcc_assert (!automatically_generated_chrec_p (t));
1093 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1096 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1097 operator. This allows us to invert the condition or to handle
1098 inequalities. */
1100 static void
1101 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1103 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1104 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1105 isl_set *cond;
1107 switch (code)
1109 case LT_EXPR:
1110 cond = isl_pw_aff_lt_set (lhs, rhs);
1111 break;
1113 case GT_EXPR:
1114 cond = isl_pw_aff_gt_set (lhs, rhs);
1115 break;
1117 case LE_EXPR:
1118 cond = isl_pw_aff_le_set (lhs, rhs);
1119 break;
1121 case GE_EXPR:
1122 cond = isl_pw_aff_ge_set (lhs, rhs);
1123 break;
1125 case EQ_EXPR:
1126 cond = isl_pw_aff_eq_set (lhs, rhs);
1127 break;
1129 case NE_EXPR:
1130 cond = isl_pw_aff_ne_set (lhs, rhs);
1131 break;
1133 default:
1134 isl_pw_aff_free(lhs);
1135 isl_pw_aff_free(rhs);
1136 return;
1139 cond = isl_set_coalesce (cond);
1140 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1141 pbb->domain = isl_set_intersect (pbb->domain, cond);
1144 /* Add conditions to the domain of PBB. */
1146 static void
1147 add_conditions_to_domain (poly_bb_p pbb)
1149 unsigned int i;
1150 gimple stmt;
1151 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1153 if (GBB_CONDITIONS (gbb).is_empty ())
1154 return;
1156 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1157 switch (gimple_code (stmt))
1159 case GIMPLE_COND:
1161 enum tree_code code = gimple_cond_code (stmt);
1163 /* The conditions for ELSE-branches are inverted. */
1164 if (!GBB_CONDITION_CASES (gbb)[i])
1165 code = invert_tree_comparison (code, false);
1167 add_condition_to_pbb (pbb, stmt, code);
1168 break;
1171 case GIMPLE_SWITCH:
1172 /* Switch statements are not supported right now - fall through. */
1174 default:
1175 gcc_unreachable ();
1176 break;
1180 /* Traverses all the GBBs of the SCOP and add their constraints to the
1181 iteration domains. */
1183 static void
1184 add_conditions_to_constraints (scop_p scop)
1186 int i;
1187 poly_bb_p pbb;
1189 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1190 add_conditions_to_domain (pbb);
1193 /* Structure used to pass data to dom_walk. */
1195 struct bsc
1197 vec<gimple> *conditions, *cases;
1198 sese region;
1201 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1202 edge between BB and its predecessor is not a loop exit edge, and
1203 the last statement of the single predecessor is a COND_EXPR. */
1205 static gimple
1206 single_pred_cond_non_loop_exit (basic_block bb)
1208 if (single_pred_p (bb))
1210 edge e = single_pred_edge (bb);
1211 basic_block pred = e->src;
1212 gimple stmt;
1214 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1215 return NULL;
1217 stmt = last_stmt (pred);
1219 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1220 return stmt;
1223 return NULL;
1226 /* Call-back for dom_walk executed before visiting the dominated
1227 blocks. */
1229 static void
1230 build_sese_conditions_before (struct dom_walk_data *dw_data,
1231 basic_block bb)
1233 struct bsc *data = (struct bsc *) dw_data->global_data;
1234 vec<gimple> *conditions = data->conditions;
1235 vec<gimple> *cases = data->cases;
1236 gimple_bb_p gbb;
1237 gimple stmt;
1239 if (!bb_in_sese_p (bb, data->region))
1240 return;
1242 stmt = single_pred_cond_non_loop_exit (bb);
1244 if (stmt)
1246 edge e = single_pred_edge (bb);
1248 conditions->safe_push (stmt);
1250 if (e->flags & EDGE_TRUE_VALUE)
1251 cases->safe_push (stmt);
1252 else
1253 cases->safe_push (NULL);
1256 gbb = gbb_from_bb (bb);
1258 if (gbb)
1260 GBB_CONDITIONS (gbb) = conditions->copy ();
1261 GBB_CONDITION_CASES (gbb) = cases->copy ();
1265 /* Call-back for dom_walk executed after visiting the dominated
1266 blocks. */
1268 static void
1269 build_sese_conditions_after (struct dom_walk_data *dw_data,
1270 basic_block bb)
1272 struct bsc *data = (struct bsc *) dw_data->global_data;
1273 vec<gimple> *conditions = data->conditions;
1274 vec<gimple> *cases = data->cases;
1276 if (!bb_in_sese_p (bb, data->region))
1277 return;
1279 if (single_pred_cond_non_loop_exit (bb))
1281 conditions->pop ();
1282 cases->pop ();
1286 /* Record all conditions in REGION. */
1288 static void
1289 build_sese_conditions (sese region)
1291 struct dom_walk_data walk_data;
1292 vec<gimple> conditions;
1293 conditions.create (3);
1294 vec<gimple> cases;
1295 cases.create (3);
1296 struct bsc data;
1298 data.conditions = &conditions;
1299 data.cases = &cases;
1300 data.region = region;
1302 walk_data.dom_direction = CDI_DOMINATORS;
1303 walk_data.initialize_block_local_data = NULL;
1304 walk_data.before_dom_children = build_sese_conditions_before;
1305 walk_data.after_dom_children = build_sese_conditions_after;
1306 walk_data.global_data = &data;
1307 walk_data.block_local_data_size = 0;
1309 init_walk_dominator_tree (&walk_data);
1310 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1311 fini_walk_dominator_tree (&walk_data);
1313 conditions.release ();
1314 cases.release ();
1317 /* Add constraints on the possible values of parameter P from the type
1318 of P. */
1320 static void
1321 add_param_constraints (scop_p scop, graphite_dim_t p)
1323 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1324 tree type = TREE_TYPE (parameter);
1325 tree lb = NULL_TREE;
1326 tree ub = NULL_TREE;
1328 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1329 lb = lower_bound_in_type (type, type);
1330 else
1331 lb = TYPE_MIN_VALUE (type);
1333 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1334 ub = upper_bound_in_type (type, type);
1335 else
1336 ub = TYPE_MAX_VALUE (type);
1338 if (lb)
1340 isl_space *space = isl_set_get_space (scop->context);
1341 isl_constraint *c;
1342 mpz_t g;
1343 isl_int v;
1345 c = isl_inequality_alloc (isl_local_space_from_space (space));
1346 mpz_init (g);
1347 isl_int_init (v);
1348 tree_int_to_gmp (lb, g);
1349 isl_int_set_gmp (v, g);
1350 isl_int_neg (v, v);
1351 mpz_clear (g);
1352 c = isl_constraint_set_constant (c, v);
1353 isl_int_clear (v);
1354 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1356 scop->context = isl_set_add_constraint (scop->context, c);
1359 if (ub)
1361 isl_space *space = isl_set_get_space (scop->context);
1362 isl_constraint *c;
1363 mpz_t g;
1364 isl_int v;
1366 c = isl_inequality_alloc (isl_local_space_from_space (space));
1368 mpz_init (g);
1369 isl_int_init (v);
1370 tree_int_to_gmp (ub, g);
1371 isl_int_set_gmp (v, g);
1372 mpz_clear (g);
1373 c = isl_constraint_set_constant (c, v);
1374 isl_int_clear (v);
1375 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1377 scop->context = isl_set_add_constraint (scop->context, c);
1381 /* Build the context of the SCOP. The context usually contains extra
1382 constraints that are added to the iteration domains that constrain
1383 some parameters. */
1385 static void
1386 build_scop_context (scop_p scop)
1388 graphite_dim_t p, n = scop_nb_params (scop);
1390 for (p = 0; p < n; p++)
1391 add_param_constraints (scop, p);
1394 /* Build the iteration domains: the loops belonging to the current
1395 SCOP, and that vary for the execution of the current basic block.
1396 Returns false if there is no loop in SCOP. */
1398 static void
1399 build_scop_iteration_domain (scop_p scop)
1401 struct loop *loop;
1402 sese region = SCOP_REGION (scop);
1403 int i;
1404 poly_bb_p pbb;
1405 int nb_loops = number_of_loops ();
1406 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1408 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1409 if (!loop_in_sese_p (loop_outer (loop), region))
1410 build_loop_iteration_domains (scop, loop, 0,
1411 isl_set_copy (scop->context), doms);
1413 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1415 loop = pbb_loop (pbb);
1417 if (doms[loop->num])
1418 pbb->domain = isl_set_copy (doms[loop->num]);
1419 else
1420 pbb->domain = isl_set_copy (scop->context);
1422 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1423 isl_id_for_pbb (scop, pbb));
1426 for (i = 0; i < nb_loops; i++)
1427 if (doms[i])
1428 isl_set_free (doms[i]);
1430 free (doms);
1433 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1434 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1435 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1436 domain. */
1438 static isl_map *
1439 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1441 isl_constraint *c;
1442 int alias_set_num = 0;
1443 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1445 if (bap && bap->alias_set)
1446 alias_set_num = *(bap->alias_set);
1448 c = isl_equality_alloc
1449 (isl_local_space_from_space (isl_map_get_space (acc)));
1450 c = isl_constraint_set_constant_si (c, -alias_set_num);
1451 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1453 return isl_map_add_constraint (acc, c);
1456 /* Assign the affine expression INDEX to the output dimension POS of
1457 MAP and return the result. */
1459 static isl_map *
1460 set_index (isl_map *map, int pos, isl_pw_aff *index)
1462 isl_map *index_map;
1463 int len = isl_map_dim (map, isl_dim_out);
1464 isl_id *id;
1466 index_map = isl_map_from_pw_aff (index);
1467 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1468 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1470 id = isl_map_get_tuple_id (map, isl_dim_out);
1471 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1472 id = isl_map_get_tuple_id (map, isl_dim_in);
1473 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1475 return isl_map_intersect (map, index_map);
1478 /* Add to ACCESSES polyhedron equalities defining the access functions
1479 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1480 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1481 PBB is the poly_bb_p that contains the data reference DR. */
1483 static isl_map *
1484 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1486 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1487 scop_p scop = PBB_SCOP (pbb);
1489 for (i = 0; i < nb_subscripts; i++)
1491 isl_pw_aff *aff;
1492 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1494 aff = extract_affine (scop, afn,
1495 isl_space_domain (isl_map_get_space (acc)));
1496 acc = set_index (acc, i + 1, aff);
1499 return acc;
1502 /* Add constrains representing the size of the accessed data to the
1503 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1504 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1505 domain. */
1507 static isl_set *
1508 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1510 tree ref = DR_REF (dr);
1511 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1513 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1515 tree low, high;
1517 if (TREE_CODE (ref) != ARRAY_REF)
1518 break;
1520 low = array_ref_low_bound (ref);
1521 high = array_ref_up_bound (ref);
1523 /* XXX The PPL code dealt separately with
1524 subscript - low >= 0 and high - subscript >= 0 in case one of
1525 the two bounds isn't known. Do the same here? */
1527 if (host_integerp (low, 0)
1528 && high
1529 && host_integerp (high, 0)
1530 /* 1-element arrays at end of structures may extend over
1531 their declared size. */
1532 && !(array_at_struct_end_p (ref)
1533 && operand_equal_p (low, high, 0)))
1535 isl_id *id;
1536 isl_aff *aff;
1537 isl_set *univ, *lbs, *ubs;
1538 isl_pw_aff *index;
1539 isl_space *space;
1540 isl_set *valid;
1541 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1542 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1544 /* high >= 0 */
1545 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1546 valid = isl_set_project_out (valid, isl_dim_set, 0,
1547 isl_set_dim (valid, isl_dim_set));
1548 scop->context = isl_set_intersect (scop->context, valid);
1550 space = isl_set_get_space (extent);
1551 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1552 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1553 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1554 index = isl_pw_aff_alloc (univ, aff);
1556 id = isl_set_get_tuple_id (extent);
1557 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1558 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1560 /* low <= sub_i <= high */
1561 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1562 ubs = isl_pw_aff_le_set (index, ub);
1563 extent = isl_set_intersect (extent, lbs);
1564 extent = isl_set_intersect (extent, ubs);
1568 return extent;
1571 /* Build data accesses for DR in PBB. */
1573 static void
1574 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1576 int dr_base_object_set;
1577 isl_map *acc;
1578 isl_set *extent;
1579 scop_p scop = PBB_SCOP (pbb);
1582 isl_space *dc = isl_set_get_space (pbb->domain);
1583 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1584 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1585 isl_dim_out, nb_out);
1587 acc = isl_map_universe (space);
1588 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1591 acc = pdr_add_alias_set (acc, dr);
1592 acc = pdr_add_memory_accesses (acc, dr, pbb);
1595 isl_id *id = isl_id_for_dr (scop, dr);
1596 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1597 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1598 int alias_set_num = 0;
1599 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1601 if (bap && bap->alias_set)
1602 alias_set_num = *(bap->alias_set);
1604 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1605 extent = isl_set_nat_universe (space);
1606 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1607 extent = pdr_add_data_dimensions (extent, scop, dr);
1610 gcc_assert (dr->aux);
1611 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1613 new_poly_dr (pbb, dr_base_object_set,
1614 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1615 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1618 /* Write to FILE the alias graph of data references in DIMACS format. */
1620 static inline bool
1621 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1622 vec<data_reference_p> drs)
1624 int num_vertex = drs.length ();
1625 int edge_num = 0;
1626 data_reference_p dr1, dr2;
1627 int i, j;
1629 if (num_vertex == 0)
1630 return true;
1632 FOR_EACH_VEC_ELT (drs, i, dr1)
1633 for (j = i + 1; drs.iterate (j, &dr2); j++)
1634 if (dr_may_alias_p (dr1, dr2, true))
1635 edge_num++;
1637 fprintf (file, "$\n");
1639 if (comment)
1640 fprintf (file, "c %s\n", comment);
1642 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1644 FOR_EACH_VEC_ELT (drs, i, dr1)
1645 for (j = i + 1; drs.iterate (j, &dr2); j++)
1646 if (dr_may_alias_p (dr1, dr2, true))
1647 fprintf (file, "e %d %d\n", i + 1, j + 1);
1649 return true;
1652 /* Write to FILE the alias graph of data references in DOT format. */
1654 static inline bool
1655 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1656 vec<data_reference_p> drs)
1658 int num_vertex = drs.length ();
1659 data_reference_p dr1, dr2;
1660 int i, j;
1662 if (num_vertex == 0)
1663 return true;
1665 fprintf (file, "$\n");
1667 if (comment)
1668 fprintf (file, "c %s\n", comment);
1670 /* First print all the vertices. */
1671 FOR_EACH_VEC_ELT (drs, i, dr1)
1672 fprintf (file, "n%d;\n", i);
1674 FOR_EACH_VEC_ELT (drs, i, dr1)
1675 for (j = i + 1; drs.iterate (j, &dr2); j++)
1676 if (dr_may_alias_p (dr1, dr2, true))
1677 fprintf (file, "n%d n%d\n", i, j);
1679 return true;
1682 /* Write to FILE the alias graph of data references in ECC format. */
1684 static inline bool
1685 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1686 vec<data_reference_p> drs)
1688 int num_vertex = drs.length ();
1689 data_reference_p dr1, dr2;
1690 int i, j;
1692 if (num_vertex == 0)
1693 return true;
1695 fprintf (file, "$\n");
1697 if (comment)
1698 fprintf (file, "c %s\n", comment);
1700 FOR_EACH_VEC_ELT (drs, i, dr1)
1701 for (j = i + 1; drs.iterate (j, &dr2); j++)
1702 if (dr_may_alias_p (dr1, dr2, true))
1703 fprintf (file, "%d %d\n", i, j);
1705 return true;
1708 /* Check if DR1 and DR2 are in the same object set. */
1710 static bool
1711 dr_same_base_object_p (const struct data_reference *dr1,
1712 const struct data_reference *dr2)
1714 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1717 /* Uses DFS component number as representative of alias-sets. Also tests for
1718 optimality by verifying if every connected component is a clique. Returns
1719 true (1) if the above test is true, and false (0) otherwise. */
1721 static int
1722 build_alias_set_optimal_p (vec<data_reference_p> drs)
1724 int num_vertices = drs.length ();
1725 struct graph *g = new_graph (num_vertices);
1726 data_reference_p dr1, dr2;
1727 int i, j;
1728 int num_connected_components;
1729 int v_indx1, v_indx2, num_vertices_in_component;
1730 int *all_vertices;
1731 int *vertices;
1732 struct graph_edge *e;
1733 int this_component_is_clique;
1734 int all_components_are_cliques = 1;
1736 FOR_EACH_VEC_ELT (drs, i, dr1)
1737 for (j = i+1; drs.iterate (j, &dr2); j++)
1738 if (dr_may_alias_p (dr1, dr2, true))
1740 add_edge (g, i, j);
1741 add_edge (g, j, i);
1744 all_vertices = XNEWVEC (int, num_vertices);
1745 vertices = XNEWVEC (int, num_vertices);
1746 for (i = 0; i < num_vertices; i++)
1747 all_vertices[i] = i;
1749 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1750 NULL, true, NULL);
1751 for (i = 0; i < g->n_vertices; i++)
1753 data_reference_p dr = drs[i];
1754 base_alias_pair *bap;
1756 gcc_assert (dr->aux);
1757 bap = (base_alias_pair *)(dr->aux);
1759 bap->alias_set = XNEW (int);
1760 *(bap->alias_set) = g->vertices[i].component + 1;
1763 /* Verify if the DFS numbering results in optimal solution. */
1764 for (i = 0; i < num_connected_components; i++)
1766 num_vertices_in_component = 0;
1767 /* Get all vertices whose DFS component number is the same as i. */
1768 for (j = 0; j < num_vertices; j++)
1769 if (g->vertices[j].component == i)
1770 vertices[num_vertices_in_component++] = j;
1772 /* Now test if the vertices in 'vertices' form a clique, by testing
1773 for edges among each pair. */
1774 this_component_is_clique = 1;
1775 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1777 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1779 /* Check if the two vertices are connected by iterating
1780 through all the edges which have one of these are source. */
1781 e = g->vertices[vertices[v_indx2]].pred;
1782 while (e)
1784 if (e->src == vertices[v_indx1])
1785 break;
1786 e = e->pred_next;
1788 if (!e)
1790 this_component_is_clique = 0;
1791 break;
1794 if (!this_component_is_clique)
1795 all_components_are_cliques = 0;
1799 free (all_vertices);
1800 free (vertices);
1801 free_graph (g);
1802 return all_components_are_cliques;
1805 /* Group each data reference in DRS with its base object set num. */
1807 static void
1808 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1810 int num_vertex = drs.length ();
1811 struct graph *g = new_graph (num_vertex);
1812 data_reference_p dr1, dr2;
1813 int i, j;
1814 int *queue;
1816 FOR_EACH_VEC_ELT (drs, i, dr1)
1817 for (j = i + 1; drs.iterate (j, &dr2); j++)
1818 if (dr_same_base_object_p (dr1, dr2))
1820 add_edge (g, i, j);
1821 add_edge (g, j, i);
1824 queue = XNEWVEC (int, num_vertex);
1825 for (i = 0; i < num_vertex; i++)
1826 queue[i] = i;
1828 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1830 for (i = 0; i < g->n_vertices; i++)
1832 data_reference_p dr = drs[i];
1833 base_alias_pair *bap;
1835 gcc_assert (dr->aux);
1836 bap = (base_alias_pair *)(dr->aux);
1838 bap->base_obj_set = g->vertices[i].component + 1;
1841 free (queue);
1842 free_graph (g);
1845 /* Build the data references for PBB. */
1847 static void
1848 build_pbb_drs (poly_bb_p pbb)
1850 int j;
1851 data_reference_p dr;
1852 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1854 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1855 build_poly_dr (dr, pbb);
1858 /* Dump to file the alias graphs for the data references in DRS. */
1860 static void
1861 dump_alias_graphs (vec<data_reference_p> drs)
1863 char comment[100];
1864 FILE *file_dimacs, *file_ecc, *file_dot;
1866 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1867 if (file_dimacs)
1869 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1870 current_function_name ());
1871 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1872 fclose (file_dimacs);
1875 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1876 if (file_ecc)
1878 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1879 current_function_name ());
1880 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1881 fclose (file_ecc);
1884 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1885 if (file_dot)
1887 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1888 current_function_name ());
1889 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1890 fclose (file_dot);
1894 /* Build data references in SCOP. */
1896 static void
1897 build_scop_drs (scop_p scop)
1899 int i, j;
1900 poly_bb_p pbb;
1901 data_reference_p dr;
1902 vec<data_reference_p> drs;
1903 drs.create (3);
1905 /* Remove all the PBBs that do not have data references: these basic
1906 blocks are not handled in the polyhedral representation. */
1907 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1908 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1910 free_gimple_bb (PBB_BLACK_BOX (pbb));
1911 free_poly_bb (pbb);
1912 SCOP_BBS (scop).ordered_remove (i);
1913 i--;
1916 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1917 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1918 drs.safe_push (dr);
1920 FOR_EACH_VEC_ELT (drs, i, dr)
1921 dr->aux = XNEW (base_alias_pair);
1923 if (!build_alias_set_optimal_p (drs))
1925 /* TODO: Add support when building alias set is not optimal. */
1929 build_base_obj_set_for_drs (drs);
1931 /* When debugging, enable the following code. This cannot be used
1932 in production compilers. */
1933 if (0)
1934 dump_alias_graphs (drs);
1936 drs.release ();
1938 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1939 build_pbb_drs (pbb);
1942 /* Return a gsi at the position of the phi node STMT. */
1944 static gimple_stmt_iterator
1945 gsi_for_phi_node (gimple stmt)
1947 gimple_stmt_iterator psi;
1948 basic_block bb = gimple_bb (stmt);
1950 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1951 if (stmt == gsi_stmt (psi))
1952 return psi;
1954 gcc_unreachable ();
1955 return psi;
1958 /* Analyze all the data references of STMTS and add them to the
1959 GBB_DATA_REFS vector of BB. */
1961 static void
1962 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1964 loop_p nest;
1965 gimple_bb_p gbb;
1966 gimple stmt;
1967 int i;
1968 sese region = SCOP_REGION (scop);
1970 if (!bb_in_sese_p (bb, region))
1971 return;
1973 nest = outermost_loop_in_sese_1 (region, bb);
1974 gbb = gbb_from_bb (bb);
1976 FOR_EACH_VEC_ELT (stmts, i, stmt)
1978 loop_p loop;
1980 if (is_gimple_debug (stmt))
1981 continue;
1983 loop = loop_containing_stmt (stmt);
1984 if (!loop_in_sese_p (loop, region))
1985 loop = nest;
1987 graphite_find_data_references_in_stmt (nest, loop, stmt,
1988 &GBB_DATA_REFS (gbb));
1992 /* Insert STMT at the end of the STMTS sequence and then insert the
1993 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1994 on STMTS. */
1996 static void
1997 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
1998 gimple_stmt_iterator insert_gsi)
2000 gimple_stmt_iterator gsi;
2001 vec<gimple> x;
2002 x.create (3);
2004 gimple_seq_add_stmt (&stmts, stmt);
2005 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2006 x.safe_push (gsi_stmt (gsi));
2008 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2009 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2010 x.release ();
2013 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2015 static void
2016 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2018 gimple_seq stmts;
2019 gimple_stmt_iterator gsi;
2020 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2021 gimple stmt = gimple_build_assign (res, var);
2022 vec<gimple> x;
2023 x.create (3);
2025 gimple_seq_add_stmt (&stmts, stmt);
2026 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2027 x.safe_push (gsi_stmt (gsi));
2029 if (gimple_code (after_stmt) == GIMPLE_PHI)
2031 gsi = gsi_after_labels (gimple_bb (after_stmt));
2032 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2034 else
2036 gsi = gsi_for_stmt (after_stmt);
2037 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2040 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2041 x.release ();
2044 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2046 static void
2047 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2049 vec<data_reference_p> drs;
2050 drs.create (3);
2051 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2052 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2053 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2054 int index, n = SCOP_BBS (scop).length ();
2056 /* The INDEX of PBB in SCOP_BBS. */
2057 for (index = 0; index < n; index++)
2058 if (SCOP_BBS (scop)[index] == pbb)
2059 break;
2061 pbb1->domain = isl_set_copy (pbb->domain);
2063 GBB_PBB (gbb1) = pbb1;
2064 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2065 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2066 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2069 /* Insert on edge E the assignment "RES := EXPR". */
2071 static void
2072 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2074 gimple_stmt_iterator gsi;
2075 gimple_seq stmts = NULL;
2076 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2077 gimple stmt = gimple_build_assign (res, var);
2078 basic_block bb;
2079 vec<gimple> x;
2080 x.create (3);
2082 gimple_seq_add_stmt (&stmts, stmt);
2083 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2084 x.safe_push (gsi_stmt (gsi));
2086 gsi_insert_seq_on_edge (e, stmts);
2087 gsi_commit_edge_inserts ();
2088 bb = gimple_bb (stmt);
2090 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2091 return;
2093 if (!gbb_from_bb (bb))
2094 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2096 analyze_drs_in_stmts (scop, bb, x);
2097 x.release ();
2100 /* Creates a zero dimension array of the same type as VAR. */
2102 static tree
2103 create_zero_dim_array (tree var, const char *base_name)
2105 tree index_type = build_index_type (integer_zero_node);
2106 tree elt_type = TREE_TYPE (var);
2107 tree array_type = build_array_type (elt_type, index_type);
2108 tree base = create_tmp_var (array_type, base_name);
2110 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2111 NULL_TREE);
2114 /* Returns true when PHI is a loop close phi node. */
2116 static bool
2117 scalar_close_phi_node_p (gimple phi)
2119 if (gimple_code (phi) != GIMPLE_PHI
2120 || virtual_operand_p (gimple_phi_result (phi)))
2121 return false;
2123 /* Note that loop close phi nodes should have a single argument
2124 because we translated the representation into a canonical form
2125 before Graphite: see canonicalize_loop_closed_ssa_form. */
2126 return (gimple_phi_num_args (phi) == 1);
2129 /* For a definition DEF in REGION, propagates the expression EXPR in
2130 all the uses of DEF outside REGION. */
2132 static void
2133 propagate_expr_outside_region (tree def, tree expr, sese region)
2135 imm_use_iterator imm_iter;
2136 gimple use_stmt;
2137 gimple_seq stmts;
2138 bool replaced_once = false;
2140 gcc_assert (TREE_CODE (def) == SSA_NAME);
2142 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2143 NULL_TREE);
2145 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2146 if (!is_gimple_debug (use_stmt)
2147 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2149 ssa_op_iter iter;
2150 use_operand_p use_p;
2152 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2153 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2154 && (replaced_once = true))
2155 replace_exp (use_p, expr);
2157 update_stmt (use_stmt);
2160 if (replaced_once)
2162 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2163 gsi_commit_edge_inserts ();
2167 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2168 dimension array for it. */
2170 static void
2171 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2173 sese region = SCOP_REGION (scop);
2174 gimple phi = gsi_stmt (*psi);
2175 tree res = gimple_phi_result (phi);
2176 basic_block bb = gimple_bb (phi);
2177 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2178 tree arg = gimple_phi_arg_def (phi, 0);
2179 gimple stmt;
2181 /* Note that loop close phi nodes should have a single argument
2182 because we translated the representation into a canonical form
2183 before Graphite: see canonicalize_loop_closed_ssa_form. */
2184 gcc_assert (gimple_phi_num_args (phi) == 1);
2186 /* The phi node can be a non close phi node, when its argument is
2187 invariant, or a default definition. */
2188 if (is_gimple_min_invariant (arg)
2189 || SSA_NAME_IS_DEFAULT_DEF (arg))
2191 propagate_expr_outside_region (res, arg, region);
2192 gsi_next (psi);
2193 return;
2196 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2198 propagate_expr_outside_region (res, arg, region);
2199 stmt = gimple_build_assign (res, arg);
2200 remove_phi_node (psi, false);
2201 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2202 SSA_NAME_DEF_STMT (res) = stmt;
2203 return;
2206 /* If res is scev analyzable and is not a scalar value, it is safe
2207 to ignore the close phi node: it will be code generated in the
2208 out of Graphite pass. */
2209 else if (scev_analyzable_p (res, region))
2211 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2212 tree scev;
2214 if (!loop_in_sese_p (loop, region))
2216 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2217 scev = scalar_evolution_in_region (region, loop, arg);
2218 scev = compute_overall_effect_of_inner_loop (loop, scev);
2220 else
2221 scev = scalar_evolution_in_region (region, loop, res);
2223 if (tree_does_not_contain_chrecs (scev))
2224 propagate_expr_outside_region (res, scev, region);
2226 gsi_next (psi);
2227 return;
2229 else
2231 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2233 stmt = gimple_build_assign (res, zero_dim_array);
2235 if (TREE_CODE (arg) == SSA_NAME)
2236 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2237 SSA_NAME_DEF_STMT (arg));
2238 else
2239 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2240 zero_dim_array, arg);
2243 remove_phi_node (psi, false);
2244 SSA_NAME_DEF_STMT (res) = stmt;
2246 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2249 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2250 dimension array for it. */
2252 static void
2253 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2255 size_t i;
2256 gimple phi = gsi_stmt (*psi);
2257 basic_block bb = gimple_bb (phi);
2258 tree res = gimple_phi_result (phi);
2259 tree var;
2260 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2261 gimple stmt;
2262 gimple_seq stmts;
2264 for (i = 0; i < gimple_phi_num_args (phi); i++)
2266 tree arg = gimple_phi_arg_def (phi, i);
2267 edge e = gimple_phi_arg_edge (phi, i);
2269 /* Avoid the insertion of code in the loop latch to please the
2270 pattern matching of the vectorizer. */
2271 if (TREE_CODE (arg) == SSA_NAME
2272 && e->src == bb->loop_father->latch)
2273 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2274 SSA_NAME_DEF_STMT (arg));
2275 else
2276 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2279 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2281 stmt = gimple_build_assign (res, var);
2282 remove_phi_node (psi, false);
2283 SSA_NAME_DEF_STMT (res) = stmt;
2285 insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2288 /* Rewrite the degenerate phi node at position PSI from the degenerate
2289 form "x = phi (y, y, ..., y)" to "x = y". */
2291 static void
2292 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2294 tree rhs;
2295 gimple stmt;
2296 gimple_stmt_iterator gsi;
2297 gimple phi = gsi_stmt (*psi);
2298 tree res = gimple_phi_result (phi);
2299 basic_block bb;
2301 bb = gimple_bb (phi);
2302 rhs = degenerate_phi_result (phi);
2303 gcc_assert (rhs);
2305 stmt = gimple_build_assign (res, rhs);
2306 remove_phi_node (psi, false);
2307 SSA_NAME_DEF_STMT (res) = stmt;
2309 gsi = gsi_after_labels (bb);
2310 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2313 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2315 static void
2316 rewrite_reductions_out_of_ssa (scop_p scop)
2318 basic_block bb;
2319 gimple_stmt_iterator psi;
2320 sese region = SCOP_REGION (scop);
2322 FOR_EACH_BB (bb)
2323 if (bb_in_sese_p (bb, region))
2324 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2326 gimple phi = gsi_stmt (psi);
2328 if (virtual_operand_p (gimple_phi_result (phi)))
2330 gsi_next (&psi);
2331 continue;
2334 if (gimple_phi_num_args (phi) > 1
2335 && degenerate_phi_result (phi))
2336 rewrite_degenerate_phi (&psi);
2338 else if (scalar_close_phi_node_p (phi))
2339 rewrite_close_phi_out_of_ssa (scop, &psi);
2341 else if (reduction_phi_p (region, &psi))
2342 rewrite_phi_out_of_ssa (scop, &psi);
2345 update_ssa (TODO_update_ssa);
2346 #ifdef ENABLE_CHECKING
2347 verify_loop_closed_ssa (true);
2348 #endif
2351 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2352 read from ZERO_DIM_ARRAY. */
2354 static void
2355 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2356 tree def, gimple use_stmt)
2358 gimple name_stmt;
2359 tree name;
2360 ssa_op_iter iter;
2361 use_operand_p use_p;
2363 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2365 name = copy_ssa_name (def, NULL);
2366 name_stmt = gimple_build_assign (name, zero_dim_array);
2368 gimple_assign_set_lhs (name_stmt, name);
2369 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2371 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2372 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2373 replace_exp (use_p, name);
2375 update_stmt (use_stmt);
2378 /* For every definition DEF in the SCOP that is used outside the scop,
2379 insert a closing-scop definition in the basic block just after this
2380 SCOP. */
2382 static void
2383 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2385 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2386 tree new_name = make_ssa_name (var, stmt);
2387 bool needs_copy = false;
2388 use_operand_p use_p;
2389 imm_use_iterator imm_iter;
2390 gimple use_stmt;
2391 sese region = SCOP_REGION (scop);
2393 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2395 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2397 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2399 SET_USE (use_p, new_name);
2401 update_stmt (use_stmt);
2402 needs_copy = true;
2406 /* Insert in the empty BB just after the scop a use of DEF such
2407 that the rewrite of cross_bb_scalar_dependences won't insert
2408 arrays everywhere else. */
2409 if (needs_copy)
2411 gimple assign = gimple_build_assign (new_name, def);
2412 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2414 SSA_NAME_DEF_STMT (new_name) = assign;
2415 update_stmt (assign);
2416 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2420 /* Rewrite the scalar dependences crossing the boundary of the BB
2421 containing STMT with an array. Return true when something has been
2422 changed. */
2424 static bool
2425 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2427 sese region = SCOP_REGION (scop);
2428 gimple stmt = gsi_stmt (*gsi);
2429 imm_use_iterator imm_iter;
2430 tree def;
2431 basic_block def_bb;
2432 tree zero_dim_array = NULL_TREE;
2433 gimple use_stmt;
2434 bool res = false;
2436 switch (gimple_code (stmt))
2438 case GIMPLE_ASSIGN:
2439 def = gimple_assign_lhs (stmt);
2440 break;
2442 case GIMPLE_CALL:
2443 def = gimple_call_lhs (stmt);
2444 break;
2446 default:
2447 return false;
2450 if (!def
2451 || !is_gimple_reg (def))
2452 return false;
2454 if (scev_analyzable_p (def, region))
2456 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2457 tree scev = scalar_evolution_in_region (region, loop, def);
2459 if (tree_contains_chrecs (scev, NULL))
2460 return false;
2462 propagate_expr_outside_region (def, scev, region);
2463 return true;
2466 def_bb = gimple_bb (stmt);
2468 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2470 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2471 if (gimple_code (use_stmt) == GIMPLE_PHI
2472 && (res = true))
2474 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2476 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2477 rewrite_close_phi_out_of_ssa (scop, &psi);
2478 else
2479 rewrite_phi_out_of_ssa (scop, &psi);
2482 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2483 if (gimple_code (use_stmt) != GIMPLE_PHI
2484 && def_bb != gimple_bb (use_stmt)
2485 && !is_gimple_debug (use_stmt)
2486 && (res = true))
2488 if (!zero_dim_array)
2490 zero_dim_array = create_zero_dim_array
2491 (def, "Cross_BB_scalar_dependence");
2492 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2493 SSA_NAME_DEF_STMT (def));
2494 gsi_next (gsi);
2497 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2498 def, use_stmt);
2501 return res;
2504 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2506 static void
2507 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2509 basic_block bb;
2510 gimple_stmt_iterator psi;
2511 sese region = SCOP_REGION (scop);
2512 bool changed = false;
2514 /* Create an extra empty BB after the scop. */
2515 split_edge (SESE_EXIT (region));
2517 FOR_EACH_BB (bb)
2518 if (bb_in_sese_p (bb, region))
2519 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2520 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2522 if (changed)
2524 scev_reset_htab ();
2525 update_ssa (TODO_update_ssa);
2526 #ifdef ENABLE_CHECKING
2527 verify_loop_closed_ssa (true);
2528 #endif
2532 /* Returns the number of pbbs that are in loops contained in SCOP. */
2534 static int
2535 nb_pbbs_in_loops (scop_p scop)
2537 int i;
2538 poly_bb_p pbb;
2539 int res = 0;
2541 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2542 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2543 res++;
2545 return res;
2548 /* Return the number of data references in BB that write in
2549 memory. */
2551 static int
2552 nb_data_writes_in_bb (basic_block bb)
2554 int res = 0;
2555 gimple_stmt_iterator gsi;
2557 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2558 if (gimple_vdef (gsi_stmt (gsi)))
2559 res++;
2561 return res;
2564 /* Splits at STMT the basic block BB represented as PBB in the
2565 polyhedral form. */
2567 static edge
2568 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2570 edge e1 = split_block (bb, stmt);
2571 new_pbb_from_pbb (scop, pbb, e1->dest);
2572 return e1;
2575 /* Splits STMT out of its current BB. This is done for reduction
2576 statements for which we want to ignore data dependences. */
2578 static basic_block
2579 split_reduction_stmt (scop_p scop, gimple stmt)
2581 basic_block bb = gimple_bb (stmt);
2582 poly_bb_p pbb = pbb_from_bb (bb);
2583 gimple_bb_p gbb = gbb_from_bb (bb);
2584 edge e1;
2585 int i;
2586 data_reference_p dr;
2588 /* Do not split basic blocks with no writes to memory: the reduction
2589 will be the only write to memory. */
2590 if (nb_data_writes_in_bb (bb) == 0
2591 /* Or if we have already marked BB as a reduction. */
2592 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2593 return bb;
2595 e1 = split_pbb (scop, pbb, bb, stmt);
2597 /* Split once more only when the reduction stmt is not the only one
2598 left in the original BB. */
2599 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2601 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2602 gsi_prev (&gsi);
2603 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2606 /* A part of the data references will end in a different basic block
2607 after the split: move the DRs from the original GBB to the newly
2608 created GBB1. */
2609 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2611 basic_block bb1 = gimple_bb (DR_STMT (dr));
2613 if (bb1 != bb)
2615 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2616 GBB_DATA_REFS (gbb1).safe_push (dr);
2617 GBB_DATA_REFS (gbb).ordered_remove (i);
2618 i--;
2622 return e1->dest;
2625 /* Return true when stmt is a reduction operation. */
2627 static inline bool
2628 is_reduction_operation_p (gimple stmt)
2630 enum tree_code code;
2632 gcc_assert (is_gimple_assign (stmt));
2633 code = gimple_assign_rhs_code (stmt);
2635 return flag_associative_math
2636 && commutative_tree_code (code)
2637 && associative_tree_code (code);
2640 /* Returns true when PHI contains an argument ARG. */
2642 static bool
2643 phi_contains_arg (gimple phi, tree arg)
2645 size_t i;
2647 for (i = 0; i < gimple_phi_num_args (phi); i++)
2648 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2649 return true;
2651 return false;
2654 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2656 static gimple
2657 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2659 gimple stmt;
2661 if (TREE_CODE (arg) != SSA_NAME)
2662 return NULL;
2664 stmt = SSA_NAME_DEF_STMT (arg);
2666 if (gimple_code (stmt) == GIMPLE_NOP
2667 || gimple_code (stmt) == GIMPLE_CALL)
2668 return NULL;
2670 if (gimple_code (stmt) == GIMPLE_PHI)
2672 if (phi_contains_arg (stmt, lhs))
2673 return stmt;
2674 return NULL;
2677 if (!is_gimple_assign (stmt))
2678 return NULL;
2680 if (gimple_num_ops (stmt) == 2)
2681 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2683 if (is_reduction_operation_p (stmt))
2685 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2687 return res ? res :
2688 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2691 return NULL;
2694 /* Detect commutative and associative scalar reductions starting at
2695 the STMT. Return the phi node of the reduction cycle, or NULL. */
2697 static gimple
2698 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2699 vec<gimple> *in,
2700 vec<gimple> *out)
2702 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2704 if (!phi)
2705 return NULL;
2707 in->safe_push (stmt);
2708 out->safe_push (stmt);
2709 return phi;
2712 /* Detect commutative and associative scalar reductions starting at
2713 STMT. Return the phi node of the reduction cycle, or NULL. */
2715 static gimple
2716 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2717 vec<gimple> *out)
2719 tree lhs = gimple_assign_lhs (stmt);
2721 if (gimple_num_ops (stmt) == 2)
2722 return detect_commutative_reduction_arg (lhs, stmt,
2723 gimple_assign_rhs1 (stmt),
2724 in, out);
2726 if (is_reduction_operation_p (stmt))
2728 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2729 gimple_assign_rhs1 (stmt),
2730 in, out);
2731 return res ? res
2732 : detect_commutative_reduction_arg (lhs, stmt,
2733 gimple_assign_rhs2 (stmt),
2734 in, out);
2737 return NULL;
2740 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2742 static gimple
2743 follow_inital_value_to_phi (tree arg, tree lhs)
2745 gimple stmt;
2747 if (!arg || TREE_CODE (arg) != SSA_NAME)
2748 return NULL;
2750 stmt = SSA_NAME_DEF_STMT (arg);
2752 if (gimple_code (stmt) == GIMPLE_PHI
2753 && phi_contains_arg (stmt, lhs))
2754 return stmt;
2756 return NULL;
2760 /* Return the argument of the loop PHI that is the initial value coming
2761 from outside the loop. */
2763 static edge
2764 edge_initial_value_for_loop_phi (gimple phi)
2766 size_t i;
2768 for (i = 0; i < gimple_phi_num_args (phi); i++)
2770 edge e = gimple_phi_arg_edge (phi, i);
2772 if (loop_depth (e->src->loop_father)
2773 < loop_depth (e->dest->loop_father))
2774 return e;
2777 return NULL;
2780 /* Return the argument of the loop PHI that is the initial value coming
2781 from outside the loop. */
2783 static tree
2784 initial_value_for_loop_phi (gimple phi)
2786 size_t i;
2788 for (i = 0; i < gimple_phi_num_args (phi); i++)
2790 edge e = gimple_phi_arg_edge (phi, i);
2792 if (loop_depth (e->src->loop_father)
2793 < loop_depth (e->dest->loop_father))
2794 return gimple_phi_arg_def (phi, i);
2797 return NULL_TREE;
2800 /* Returns true when DEF is used outside the reduction cycle of
2801 LOOP_PHI. */
2803 static bool
2804 used_outside_reduction (tree def, gimple loop_phi)
2806 use_operand_p use_p;
2807 imm_use_iterator imm_iter;
2808 loop_p loop = loop_containing_stmt (loop_phi);
2810 /* In LOOP, DEF should be used only in LOOP_PHI. */
2811 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2813 gimple stmt = USE_STMT (use_p);
2815 if (stmt != loop_phi
2816 && !is_gimple_debug (stmt)
2817 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2818 return true;
2821 return false;
2824 /* Detect commutative and associative scalar reductions belonging to
2825 the SCOP starting at the loop closed phi node STMT. Return the phi
2826 node of the reduction cycle, or NULL. */
2828 static gimple
2829 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2830 vec<gimple> *out)
2832 if (scalar_close_phi_node_p (stmt))
2834 gimple def, loop_phi, phi, close_phi = stmt;
2835 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2837 if (TREE_CODE (arg) != SSA_NAME)
2838 return NULL;
2840 /* Note that loop close phi nodes should have a single argument
2841 because we translated the representation into a canonical form
2842 before Graphite: see canonicalize_loop_closed_ssa_form. */
2843 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2845 def = SSA_NAME_DEF_STMT (arg);
2846 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2847 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2848 return NULL;
2850 lhs = gimple_phi_result (close_phi);
2851 init = initial_value_for_loop_phi (loop_phi);
2852 phi = follow_inital_value_to_phi (init, lhs);
2854 if (phi && (used_outside_reduction (lhs, phi)
2855 || !has_single_use (gimple_phi_result (phi))))
2856 return NULL;
2858 in->safe_push (loop_phi);
2859 out->safe_push (close_phi);
2860 return phi;
2863 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2864 return detect_commutative_reduction_assign (stmt, in, out);
2866 return NULL;
2869 /* Translate the scalar reduction statement STMT to an array RED
2870 knowing that its recursive phi node is LOOP_PHI. */
2872 static void
2873 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2874 gimple stmt, gimple loop_phi)
2876 tree res = gimple_phi_result (loop_phi);
2877 gimple assign = gimple_build_assign (res, unshare_expr (red));
2878 gimple_stmt_iterator gsi;
2880 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2882 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2883 gsi = gsi_for_stmt (stmt);
2884 gsi_next (&gsi);
2885 insert_stmts (scop, assign, NULL, gsi);
2888 /* Removes the PHI node and resets all the debug stmts that are using
2889 the PHI_RESULT. */
2891 static void
2892 remove_phi (gimple phi)
2894 imm_use_iterator imm_iter;
2895 tree def;
2896 use_operand_p use_p;
2897 gimple_stmt_iterator gsi;
2898 vec<gimple> update;
2899 update.create (3);
2900 unsigned int i;
2901 gimple stmt;
2903 def = PHI_RESULT (phi);
2904 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2906 stmt = USE_STMT (use_p);
2908 if (is_gimple_debug (stmt))
2910 gimple_debug_bind_reset_value (stmt);
2911 update.safe_push (stmt);
2915 FOR_EACH_VEC_ELT (update, i, stmt)
2916 update_stmt (stmt);
2918 update.release ();
2920 gsi = gsi_for_phi_node (phi);
2921 remove_phi_node (&gsi, false);
2924 /* Helper function for for_each_index. For each INDEX of the data
2925 reference REF, returns true when its indices are valid in the loop
2926 nest LOOP passed in as DATA. */
2928 static bool
2929 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2931 loop_p loop;
2932 basic_block header, def_bb;
2933 gimple stmt;
2935 if (TREE_CODE (*index) != SSA_NAME)
2936 return true;
2938 loop = *((loop_p *) data);
2939 header = loop->header;
2940 stmt = SSA_NAME_DEF_STMT (*index);
2942 if (!stmt)
2943 return true;
2945 def_bb = gimple_bb (stmt);
2947 if (!def_bb)
2948 return true;
2950 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2953 /* When the result of a CLOSE_PHI is written to a memory location,
2954 return a pointer to that memory reference, otherwise return
2955 NULL_TREE. */
2957 static tree
2958 close_phi_written_to_memory (gimple close_phi)
2960 imm_use_iterator imm_iter;
2961 use_operand_p use_p;
2962 gimple stmt;
2963 tree res, def = gimple_phi_result (close_phi);
2965 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2966 if ((stmt = USE_STMT (use_p))
2967 && gimple_code (stmt) == GIMPLE_ASSIGN
2968 && (res = gimple_assign_lhs (stmt)))
2970 switch (TREE_CODE (res))
2972 case VAR_DECL:
2973 case PARM_DECL:
2974 case RESULT_DECL:
2975 return res;
2977 case ARRAY_REF:
2978 case MEM_REF:
2980 tree arg = gimple_phi_arg_def (close_phi, 0);
2981 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2983 /* FIXME: this restriction is for id-{24,25}.f and
2984 could be handled by duplicating the computation of
2985 array indices before the loop of the close_phi. */
2986 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2987 return res;
2989 /* Fallthru. */
2991 default:
2992 continue;
2995 return NULL_TREE;
2998 /* Rewrite out of SSA the reduction described by the loop phi nodes
2999 IN, and the close phi nodes OUT. IN and OUT are structured by loop
3000 levels like this:
3002 IN: stmt, loop_n, ..., loop_0
3003 OUT: stmt, close_n, ..., close_0
3005 the first element is the reduction statement, and the next elements
3006 are the loop and close phi nodes of each of the outer loops. */
3008 static void
3009 translate_scalar_reduction_to_array (scop_p scop,
3010 vec<gimple> in,
3011 vec<gimple> out)
3013 gimple loop_phi;
3014 unsigned int i = out.length () - 1;
3015 tree red = close_phi_written_to_memory (out[i]);
3017 FOR_EACH_VEC_ELT (in, i, loop_phi)
3019 gimple close_phi = out[i];
3021 if (i == 0)
3023 gimple stmt = loop_phi;
3024 basic_block bb = split_reduction_stmt (scop, stmt);
3025 poly_bb_p pbb = pbb_from_bb (bb);
3026 PBB_IS_REDUCTION (pbb) = true;
3027 gcc_assert (close_phi == loop_phi);
3029 if (!red)
3030 red = create_zero_dim_array
3031 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3033 translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
3034 continue;
3037 if (i == in.length () - 1)
3039 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3040 unshare_expr (red), close_phi);
3041 insert_out_of_ssa_copy_on_edge
3042 (scop, edge_initial_value_for_loop_phi (loop_phi),
3043 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3046 remove_phi (loop_phi);
3047 remove_phi (close_phi);
3051 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3052 true when something has been changed. */
3054 static bool
3055 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3056 gimple close_phi)
3058 bool res;
3059 vec<gimple> in;
3060 in.create (10);
3061 vec<gimple> out;
3062 out.create (10);
3064 detect_commutative_reduction (scop, close_phi, &in, &out);
3065 res = in.length () > 1;
3066 if (res)
3067 translate_scalar_reduction_to_array (scop, in, out);
3069 in.release ();
3070 out.release ();
3071 return res;
3074 /* Rewrites all the commutative reductions from LOOP out of SSA.
3075 Returns true when something has been changed. */
3077 static bool
3078 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3079 loop_p loop)
3081 gimple_stmt_iterator gsi;
3082 edge exit = single_exit (loop);
3083 tree res;
3084 bool changed = false;
3086 if (!exit)
3087 return false;
3089 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3090 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3091 && !virtual_operand_p (res)
3092 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3093 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3094 (scop, gsi_stmt (gsi));
3096 return changed;
3099 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3101 static void
3102 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3104 loop_iterator li;
3105 loop_p loop;
3106 bool changed = false;
3107 sese region = SCOP_REGION (scop);
3109 FOR_EACH_LOOP (li, loop, 0)
3110 if (loop_in_sese_p (loop, region))
3111 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3113 if (changed)
3115 scev_reset_htab ();
3116 gsi_commit_edge_inserts ();
3117 update_ssa (TODO_update_ssa);
3118 #ifdef ENABLE_CHECKING
3119 verify_loop_closed_ssa (true);
3120 #endif
3124 /* Can all ivs be represented by a signed integer?
3125 As CLooG might generate negative values in its expressions, signed loop ivs
3126 are required in the backend. */
3128 static bool
3129 scop_ivs_can_be_represented (scop_p scop)
3131 loop_iterator li;
3132 loop_p loop;
3133 gimple_stmt_iterator psi;
3134 bool result = true;
3136 FOR_EACH_LOOP (li, loop, 0)
3138 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3139 continue;
3141 for (psi = gsi_start_phis (loop->header);
3142 !gsi_end_p (psi); gsi_next (&psi))
3144 gimple phi = gsi_stmt (psi);
3145 tree res = PHI_RESULT (phi);
3146 tree type = TREE_TYPE (res);
3148 if (TYPE_UNSIGNED (type)
3149 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3151 result = false;
3152 break;
3155 if (!result)
3156 FOR_EACH_LOOP_BREAK (li);
3159 return result;
3162 /* Builds the polyhedral representation for a SESE region. */
3164 void
3165 build_poly_scop (scop_p scop)
3167 sese region = SCOP_REGION (scop);
3168 graphite_dim_t max_dim;
3170 build_scop_bbs (scop);
3172 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3173 Once CLooG is fixed, remove this guard. Anyways, it makes no
3174 sense to optimize a scop containing only PBBs that do not belong
3175 to any loops. */
3176 if (nb_pbbs_in_loops (scop) == 0)
3177 return;
3179 if (!scop_ivs_can_be_represented (scop))
3180 return;
3182 if (flag_associative_math)
3183 rewrite_commutative_reductions_out_of_ssa (scop);
3185 build_sese_loop_nests (region);
3186 build_sese_conditions (region);
3187 find_scop_parameters (scop);
3189 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3190 if (scop_nb_params (scop) > max_dim)
3191 return;
3193 build_scop_iteration_domain (scop);
3194 build_scop_context (scop);
3195 add_conditions_to_constraints (scop);
3197 /* Rewrite out of SSA only after having translated the
3198 representation to the polyhedral representation to avoid scev
3199 analysis failures. That means that these functions will insert
3200 new data references that they create in the right place. */
3201 rewrite_reductions_out_of_ssa (scop);
3202 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3204 build_scop_drs (scop);
3205 scop_to_lst (scop);
3206 build_scop_scattering (scop);
3208 /* This SCoP has been translated to the polyhedral
3209 representation. */
3210 POLY_SCOP_P (scop) = true;
3212 #endif