PR target/65871
[official-gcc.git] / gcc / graphite-sese-to-poly.c
blob23b63ad1f5ea55ea89ddbf77717c9f7d256cc9b4
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
23 #ifdef HAVE_isl
24 #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 <isl/val.h>
31 /* Since ISL-0.13, the extern is in val_gmp.h. */
32 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
33 extern "C" {
34 #endif
35 #include <isl/val_gmp.h>
36 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
38 #endif
39 #endif
41 #include "system.h"
42 #include "coretypes.h"
43 #include "hash-set.h"
44 #include "machmode.h"
45 #include "vec.h"
46 #include "double-int.h"
47 #include "input.h"
48 #include "alias.h"
49 #include "symtab.h"
50 #include "options.h"
51 #include "wide-int.h"
52 #include "inchash.h"
53 #include "tree.h"
54 #include "fold-const.h"
55 #include "predict.h"
56 #include "tm.h"
57 #include "hard-reg-set.h"
58 #include "function.h"
59 #include "dominance.h"
60 #include "cfg.h"
61 #include "basic-block.h"
62 #include "tree-ssa-alias.h"
63 #include "internal-fn.h"
64 #include "gimple-expr.h"
65 #include "is-a.h"
66 #include "gimple.h"
67 #include "gimple-iterator.h"
68 #include "gimplify.h"
69 #include "gimplify-me.h"
70 #include "gimple-ssa.h"
71 #include "tree-cfg.h"
72 #include "tree-phinodes.h"
73 #include "ssa-iterators.h"
74 #include "stringpool.h"
75 #include "tree-ssanames.h"
76 #include "tree-ssa-loop-manip.h"
77 #include "tree-ssa-loop-niter.h"
78 #include "tree-ssa-loop.h"
79 #include "tree-into-ssa.h"
80 #include "tree-pass.h"
81 #include "cfgloop.h"
82 #include "tree-chrec.h"
83 #include "tree-data-ref.h"
84 #include "tree-scalar-evolution.h"
85 #include "domwalk.h"
86 #include "sese.h"
87 #include "tree-ssa-propagate.h"
89 #ifdef HAVE_isl
90 #include "hashtab.h"
91 #include "rtl.h"
92 #include "flags.h"
93 #include "statistics.h"
94 #include "real.h"
95 #include "fixed-value.h"
96 #include "insn-config.h"
97 #include "expmed.h"
98 #include "dojump.h"
99 #include "explow.h"
100 #include "calls.h"
101 #include "emit-rtl.h"
102 #include "varasm.h"
103 #include "stmt.h"
104 #include "expr.h"
105 #include "graphite-poly.h"
106 #include "graphite-sese-to-poly.h"
109 /* Assigns to RES the value of the INTEGER_CST T. */
111 static inline void
112 tree_int_to_gmp (tree t, mpz_t res)
114 wi::to_mpz (t, res, TYPE_SIGN (TREE_TYPE (t)));
117 /* Returns the index of the PHI argument defined in the outermost
118 loop. */
120 static size_t
121 phi_arg_in_outermost_loop (gphi *phi)
123 loop_p loop = gimple_bb (phi)->loop_father;
124 size_t i, res = 0;
126 for (i = 0; i < gimple_phi_num_args (phi); i++)
127 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
129 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
130 res = i;
133 return res;
136 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
137 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
139 static void
140 remove_simple_copy_phi (gphi_iterator *psi)
142 gphi *phi = psi->phi ();
143 tree res = gimple_phi_result (phi);
144 size_t entry = phi_arg_in_outermost_loop (phi);
145 tree init = gimple_phi_arg_def (phi, entry);
146 gassign *stmt = gimple_build_assign (res, init);
147 edge e = gimple_phi_arg_edge (phi, entry);
149 remove_phi_node (psi, false);
150 gsi_insert_on_edge_immediate (e, stmt);
153 /* Removes an invariant phi node at position PSI by inserting on the
154 loop ENTRY edge the assignment RES = INIT. */
156 static void
157 remove_invariant_phi (sese region, gphi_iterator *psi)
159 gphi *phi = psi->phi ();
160 loop_p loop = loop_containing_stmt (phi);
161 tree res = gimple_phi_result (phi);
162 tree scev = scalar_evolution_in_region (region, loop, res);
163 size_t entry = phi_arg_in_outermost_loop (phi);
164 edge e = gimple_phi_arg_edge (phi, entry);
165 tree var;
166 gassign *stmt;
167 gimple_seq stmts = NULL;
169 if (tree_contains_chrecs (scev, NULL))
170 scev = gimple_phi_arg_def (phi, entry);
172 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
173 stmt = gimple_build_assign (res, var);
174 remove_phi_node (psi, false);
176 gimple_seq_add_stmt (&stmts, stmt);
177 gsi_insert_seq_on_edge (e, stmts);
178 gsi_commit_edge_inserts ();
179 SSA_NAME_DEF_STMT (res) = stmt;
182 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
184 static inline bool
185 simple_copy_phi_p (gphi *phi)
187 tree res;
189 if (gimple_phi_num_args (phi) != 2)
190 return false;
192 res = gimple_phi_result (phi);
193 return (res == gimple_phi_arg_def (phi, 0)
194 || res == gimple_phi_arg_def (phi, 1));
197 /* Returns true when the phi node at position PSI is a reduction phi
198 node in REGION. Otherwise moves the pointer PSI to the next phi to
199 be considered. */
201 static bool
202 reduction_phi_p (sese region, gphi_iterator *psi)
204 loop_p loop;
205 gphi *phi = psi->phi ();
206 tree res = gimple_phi_result (phi);
208 loop = loop_containing_stmt (phi);
210 if (simple_copy_phi_p (phi))
212 /* PRE introduces phi nodes like these, for an example,
213 see id-5.f in the fortran graphite testsuite:
215 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
217 remove_simple_copy_phi (psi);
218 return false;
221 if (scev_analyzable_p (res, region))
223 tree scev = scalar_evolution_in_region (region, loop, res);
225 if (evolution_function_is_invariant_p (scev, loop->num))
226 remove_invariant_phi (region, psi);
227 else
228 gsi_next (psi);
230 return false;
233 /* All the other cases are considered reductions. */
234 return true;
237 /* Store the GRAPHITE representation of BB. */
239 static gimple_bb_p
240 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
242 struct gimple_bb *gbb;
244 gbb = XNEW (struct gimple_bb);
245 bb->aux = gbb;
246 GBB_BB (gbb) = bb;
247 GBB_DATA_REFS (gbb) = drs;
248 GBB_CONDITIONS (gbb).create (0);
249 GBB_CONDITION_CASES (gbb).create (0);
251 return gbb;
254 static void
255 free_data_refs_aux (vec<data_reference_p> datarefs)
257 unsigned int i;
258 struct data_reference *dr;
260 FOR_EACH_VEC_ELT (datarefs, i, dr)
261 if (dr->aux)
263 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
265 free (bap->alias_set);
267 free (bap);
268 dr->aux = NULL;
271 /* Frees GBB. */
273 static void
274 free_gimple_bb (struct gimple_bb *gbb)
276 free_data_refs_aux (GBB_DATA_REFS (gbb));
277 free_data_refs (GBB_DATA_REFS (gbb));
279 GBB_CONDITIONS (gbb).release ();
280 GBB_CONDITION_CASES (gbb).release ();
281 GBB_BB (gbb)->aux = 0;
282 XDELETE (gbb);
285 /* Deletes all gimple bbs in SCOP. */
287 static void
288 remove_gbbs_in_scop (scop_p scop)
290 int i;
291 poly_bb_p pbb;
293 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
294 free_gimple_bb (PBB_BLACK_BOX (pbb));
297 /* Deletes all scops in SCOPS. */
299 void
300 free_scops (vec<scop_p> scops)
302 int i;
303 scop_p scop;
305 FOR_EACH_VEC_ELT (scops, i, scop)
307 remove_gbbs_in_scop (scop);
308 free_sese (SCOP_REGION (scop));
309 free_scop (scop);
312 scops.release ();
315 /* Same as outermost_loop_in_sese, returns the outermost loop
316 containing BB in REGION, but makes sure that the returned loop
317 belongs to the REGION, and so this returns the first loop in the
318 REGION when the loop containing BB does not belong to REGION. */
320 static loop_p
321 outermost_loop_in_sese_1 (sese region, basic_block bb)
323 loop_p nest = outermost_loop_in_sese (region, bb);
325 if (loop_in_sese_p (nest, region))
326 return nest;
328 /* When the basic block BB does not belong to a loop in the region,
329 return the first loop in the region. */
330 nest = nest->inner;
331 while (nest)
332 if (loop_in_sese_p (nest, region))
333 break;
334 else
335 nest = nest->next;
337 gcc_assert (nest);
338 return nest;
341 /* Generates a polyhedral black box only if the bb contains interesting
342 information. */
344 static gimple_bb_p
345 try_generate_gimple_bb (scop_p scop, basic_block bb)
347 vec<data_reference_p> drs;
348 drs.create (5);
349 sese region = SCOP_REGION (scop);
350 loop_p nest = outermost_loop_in_sese_1 (region, bb);
351 gimple_stmt_iterator gsi;
353 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
355 gimple stmt = gsi_stmt (gsi);
356 loop_p loop;
358 if (is_gimple_debug (stmt))
359 continue;
361 loop = loop_containing_stmt (stmt);
362 if (!loop_in_sese_p (loop, region))
363 loop = nest;
365 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
368 return new_gimple_bb (bb, drs);
371 /* Returns true if all predecessors of BB, that are not dominated by BB, are
372 marked in MAP. The predecessors dominated by BB are loop latches and will
373 be handled after BB. */
375 static bool
376 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
378 edge e;
379 edge_iterator ei;
381 FOR_EACH_EDGE (e, ei, bb->preds)
382 if (!bitmap_bit_p (map, e->src->index)
383 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
384 return false;
386 return true;
389 /* Compare the depth of two basic_block's P1 and P2. */
391 static int
392 compare_bb_depths (const void *p1, const void *p2)
394 const_basic_block const bb1 = *(const_basic_block const*)p1;
395 const_basic_block const bb2 = *(const_basic_block const*)p2;
396 int d1 = loop_depth (bb1->loop_father);
397 int d2 = loop_depth (bb2->loop_father);
399 if (d1 < d2)
400 return 1;
402 if (d1 > d2)
403 return -1;
405 return 0;
408 /* Sort the basic blocks from DOM such that the first are the ones at
409 a deepest loop level. */
411 static void
412 graphite_sort_dominated_info (vec<basic_block> dom)
414 dom.qsort (compare_bb_depths);
417 /* Recursive helper function for build_scops_bbs. */
419 static void
420 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
422 sese region = SCOP_REGION (scop);
423 vec<basic_block> dom;
424 poly_bb_p pbb;
426 if (bitmap_bit_p (visited, bb->index)
427 || !bb_in_sese_p (bb, region))
428 return;
430 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
431 SCOP_BBS (scop).safe_push (pbb);
432 bitmap_set_bit (visited, bb->index);
434 dom = get_dominated_by (CDI_DOMINATORS, bb);
436 if (!dom.exists ())
437 return;
439 graphite_sort_dominated_info (dom);
441 while (!dom.is_empty ())
443 int i;
444 basic_block dom_bb;
446 FOR_EACH_VEC_ELT (dom, i, dom_bb)
447 if (all_non_dominated_preds_marked_p (dom_bb, visited))
449 build_scop_bbs_1 (scop, visited, dom_bb);
450 dom.unordered_remove (i);
451 break;
455 dom.release ();
458 /* Gather the basic blocks belonging to the SCOP. */
460 static void
461 build_scop_bbs (scop_p scop)
463 sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
464 sese region = SCOP_REGION (scop);
466 bitmap_clear (visited);
467 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
468 sbitmap_free (visited);
471 /* Return an ISL identifier for the polyhedral basic block PBB. */
473 static isl_id *
474 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
476 char name[50];
477 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
478 return isl_id_alloc (s->ctx, name, pbb);
481 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
482 We generate SCATTERING_DIMENSIONS scattering dimensions.
484 CLooG 0.15.0 and previous versions require, that all
485 scattering functions of one CloogProgram have the same number of
486 scattering dimensions, therefore we allow to specify it. This
487 should be removed in future versions of CLooG.
489 The scattering polyhedron consists of these dimensions: scattering,
490 loop_iterators, parameters.
492 Example:
494 | scattering_dimensions = 5
495 | used_scattering_dimensions = 3
496 | nb_iterators = 1
497 | scop_nb_params = 2
499 | Schedule:
501 | 4 5
503 | Scattering polyhedron:
505 | scattering: {s1, s2, s3, s4, s5}
506 | loop_iterators: {i}
507 | parameters: {p1, p2}
509 | s1 s2 s3 s4 s5 i p1 p2 1
510 | 1 0 0 0 0 0 0 0 -4 = 0
511 | 0 1 0 0 0 -1 0 0 0 = 0
512 | 0 0 1 0 0 0 0 0 -5 = 0 */
514 static void
515 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
516 poly_bb_p pbb, int scattering_dimensions)
518 int i;
519 int nb_iterators = pbb_dim_iter_domain (pbb);
520 int used_scattering_dimensions = nb_iterators * 2 + 1;
521 isl_val *val;
522 isl_space *dc, *dm;
524 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
526 dc = isl_set_get_space (pbb->domain);
527 dm = isl_space_add_dims (isl_space_from_domain (dc),
528 isl_dim_out, scattering_dimensions);
529 pbb->schedule = isl_map_universe (dm);
531 for (i = 0; i < scattering_dimensions; i++)
533 /* Textual order inside this loop. */
534 if ((i % 2) == 0)
536 isl_constraint *c = isl_equality_alloc
537 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
539 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
541 val = isl_val_neg (val);
542 c = isl_constraint_set_constant_val (c, val);
543 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
544 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
547 /* Iterations of this loop. */
548 else /* if ((i % 2) == 1) */
550 int loop = (i - 1) / 2;
551 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
552 isl_dim_out, i);
556 pbb->transformed = isl_map_copy (pbb->schedule);
559 /* Build for BB the static schedule.
561 The static schedule is a Dewey numbering of the abstract syntax
562 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
564 The following example informally defines the static schedule:
567 for (i: ...)
569 for (j: ...)
575 for (k: ...)
583 Static schedules for A to F:
585 DEPTH
586 0 1 2
588 B 1 0 0
589 C 1 0 1
590 D 1 1 0
591 E 1 1 1
595 static void
596 build_scop_scattering (scop_p scop)
598 int i;
599 poly_bb_p pbb;
600 gimple_bb_p previous_gbb = NULL;
601 isl_space *dc = isl_set_get_space (scop->context);
602 isl_aff *static_sched;
604 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
605 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
607 /* We have to start schedules at 0 on the first component and
608 because we cannot compare_prefix_loops against a previous loop,
609 prefix will be equal to zero, and that index will be
610 incremented before copying. */
611 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
613 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
615 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
616 int prefix;
617 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
619 if (previous_gbb)
620 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
621 else
622 prefix = 0;
624 previous_gbb = gbb;
626 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
627 prefix, 1);
628 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
631 isl_aff_free (static_sched);
634 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
636 /* Extract an affine expression from the chain of recurrence E. */
638 static isl_pw_aff *
639 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
641 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
642 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
643 isl_local_space *ls = isl_local_space_from_space (space);
644 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
645 isl_aff *loop = isl_aff_set_coefficient_si
646 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
647 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
649 /* Before multiplying, make sure that the result is affine. */
650 gcc_assert (isl_pw_aff_is_cst (rhs)
651 || isl_pw_aff_is_cst (l));
653 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
656 /* Extract an affine expression from the mult_expr E. */
658 static isl_pw_aff *
659 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
661 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
662 isl_space_copy (space));
663 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
665 if (!isl_pw_aff_is_cst (lhs)
666 && !isl_pw_aff_is_cst (rhs))
668 isl_pw_aff_free (lhs);
669 isl_pw_aff_free (rhs);
670 return NULL;
673 return isl_pw_aff_mul (lhs, rhs);
676 /* Return an ISL identifier from the name of the ssa_name E. */
678 static isl_id *
679 isl_id_for_ssa_name (scop_p s, tree e)
681 const char *name = get_name (e);
682 isl_id *id;
684 if (name)
685 id = isl_id_alloc (s->ctx, name, e);
686 else
688 char name1[50];
689 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
690 id = isl_id_alloc (s->ctx, name1, e);
693 return id;
696 /* Return an ISL identifier for the data reference DR. */
698 static isl_id *
699 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
701 /* Data references all get the same isl_id. They need to be comparable
702 and are distinguished through the first dimension, which contains the
703 alias set number. */
704 return isl_id_alloc (s->ctx, "", 0);
707 /* Extract an affine expression from the ssa_name E. */
709 static isl_pw_aff *
710 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
712 isl_aff *aff;
713 isl_set *dom;
714 isl_id *id;
715 int dimension;
717 id = isl_id_for_ssa_name (s, e);
718 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
719 isl_id_free (id);
720 dom = isl_set_universe (isl_space_copy (space));
721 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
722 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
723 return isl_pw_aff_alloc (dom, aff);
726 /* Extract an affine expression from the gmp constant G. */
728 static isl_pw_aff *
729 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
731 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
732 isl_aff *aff = isl_aff_zero_on_domain (ls);
733 isl_set *dom = isl_set_universe (space);
734 isl_val *v;
735 isl_ctx *ct;
737 ct = isl_aff_get_ctx (aff);
738 v = isl_val_int_from_gmp (ct, g);
739 aff = isl_aff_add_constant_val (aff, v);
741 return isl_pw_aff_alloc (dom, aff);
744 /* Extract an affine expression from the integer_cst E. */
746 static isl_pw_aff *
747 extract_affine_int (tree e, __isl_take isl_space *space)
749 isl_pw_aff *res;
750 mpz_t g;
752 mpz_init (g);
753 tree_int_to_gmp (e, g);
754 res = extract_affine_gmp (g, space);
755 mpz_clear (g);
757 return res;
760 /* Compute pwaff mod 2^width. */
762 extern isl_ctx *the_isl_ctx;
764 static isl_pw_aff *
765 wrap (isl_pw_aff *pwaff, unsigned width)
767 isl_val *mod;
769 mod = isl_val_int_from_ui(the_isl_ctx, width);
770 mod = isl_val_2exp (mod);
771 pwaff = isl_pw_aff_mod_val (pwaff, mod);
773 return pwaff;
776 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
777 Otherwise returns -1. */
779 static inline int
780 parameter_index_in_region_1 (tree name, sese region)
782 int i;
783 tree p;
785 gcc_assert (TREE_CODE (name) == SSA_NAME);
787 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
788 if (p == name)
789 return i;
791 return -1;
794 /* When the parameter NAME is in REGION, returns its index in
795 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
796 and returns the index of NAME. */
798 static int
799 parameter_index_in_region (tree name, sese region)
801 int i;
803 gcc_assert (TREE_CODE (name) == SSA_NAME);
805 i = parameter_index_in_region_1 (name, region);
806 if (i != -1)
807 return i;
809 gcc_assert (SESE_ADD_PARAMS (region));
811 i = SESE_PARAMS (region).length ();
812 SESE_PARAMS (region).safe_push (name);
813 return i;
816 /* Extract an affine expression from the tree E in the scop S. */
818 static isl_pw_aff *
819 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
821 isl_pw_aff *lhs, *rhs, *res;
822 tree type;
824 if (e == chrec_dont_know) {
825 isl_space_free (space);
826 return NULL;
829 switch (TREE_CODE (e))
831 case POLYNOMIAL_CHREC:
832 res = extract_affine_chrec (s, e, space);
833 break;
835 case MULT_EXPR:
836 res = extract_affine_mul (s, e, space);
837 break;
839 case PLUS_EXPR:
840 case POINTER_PLUS_EXPR:
841 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
842 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
843 res = isl_pw_aff_add (lhs, rhs);
844 break;
846 case MINUS_EXPR:
847 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
848 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
849 res = isl_pw_aff_sub (lhs, rhs);
850 break;
852 case NEGATE_EXPR:
853 case BIT_NOT_EXPR:
854 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
855 rhs = extract_affine (s, integer_minus_one_node, space);
856 res = isl_pw_aff_mul (lhs, rhs);
857 break;
859 case SSA_NAME:
860 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
861 res = extract_affine_name (s, e, space);
862 break;
864 case INTEGER_CST:
865 res = extract_affine_int (e, space);
866 /* No need to wrap a single integer. */
867 return res;
869 CASE_CONVERT:
870 case NON_LVALUE_EXPR:
871 res = extract_affine (s, TREE_OPERAND (e, 0), space);
872 break;
874 default:
875 gcc_unreachable ();
876 break;
879 type = TREE_TYPE (e);
880 if (TYPE_UNSIGNED (type))
881 res = wrap (res, TYPE_PRECISION (type));
883 return res;
886 /* In the context of sese S, scan the expression E and translate it to
887 a linear expression C. When parsing a symbolic multiplication, K
888 represents the constant multiplier of an expression containing
889 parameters. */
891 static void
892 scan_tree_for_params (sese s, tree e)
894 if (e == chrec_dont_know)
895 return;
897 switch (TREE_CODE (e))
899 case POLYNOMIAL_CHREC:
900 scan_tree_for_params (s, CHREC_LEFT (e));
901 break;
903 case MULT_EXPR:
904 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
905 scan_tree_for_params (s, TREE_OPERAND (e, 0));
906 else
907 scan_tree_for_params (s, TREE_OPERAND (e, 1));
908 break;
910 case PLUS_EXPR:
911 case POINTER_PLUS_EXPR:
912 case MINUS_EXPR:
913 scan_tree_for_params (s, TREE_OPERAND (e, 0));
914 scan_tree_for_params (s, TREE_OPERAND (e, 1));
915 break;
917 case NEGATE_EXPR:
918 case BIT_NOT_EXPR:
919 CASE_CONVERT:
920 case NON_LVALUE_EXPR:
921 scan_tree_for_params (s, TREE_OPERAND (e, 0));
922 break;
924 case SSA_NAME:
925 parameter_index_in_region (e, s);
926 break;
928 case INTEGER_CST:
929 case ADDR_EXPR:
930 break;
932 default:
933 gcc_unreachable ();
934 break;
938 /* Find parameters with respect to REGION in BB. We are looking in memory
939 access functions, conditions and loop bounds. */
941 static void
942 find_params_in_bb (sese region, gimple_bb_p gbb)
944 int i;
945 unsigned j;
946 data_reference_p dr;
947 gimple stmt;
948 loop_p loop = GBB_BB (gbb)->loop_father;
950 /* Find parameters in the access functions of data references. */
951 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
952 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
953 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
955 /* Find parameters in conditional statements. */
956 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
958 tree lhs = scalar_evolution_in_region (region, loop,
959 gimple_cond_lhs (stmt));
960 tree rhs = scalar_evolution_in_region (region, loop,
961 gimple_cond_rhs (stmt));
963 scan_tree_for_params (region, lhs);
964 scan_tree_for_params (region, rhs);
968 /* Record the parameters used in the SCOP. A variable is a parameter
969 in a scop if it does not vary during the execution of that scop. */
971 static void
972 find_scop_parameters (scop_p scop)
974 poly_bb_p pbb;
975 unsigned i;
976 sese region = SCOP_REGION (scop);
977 struct loop *loop;
978 int nbp;
980 /* Find the parameters used in the loop bounds. */
981 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
983 tree nb_iters = number_of_latch_executions (loop);
985 if (!chrec_contains_symbols (nb_iters))
986 continue;
988 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
989 scan_tree_for_params (region, nb_iters);
992 /* Find the parameters used in data accesses. */
993 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
994 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
996 nbp = sese_nb_params (region);
997 scop_set_nb_params (scop, nbp);
998 SESE_ADD_PARAMS (region) = false;
1001 tree e;
1002 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
1004 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
1005 space = isl_space_set_dim_id (space, isl_dim_param, i,
1006 isl_id_for_ssa_name (scop, e));
1008 scop->context = isl_set_universe (space);
1012 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1013 the constraints for the surrounding loops. */
1015 static void
1016 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1017 int nb,
1018 isl_set *outer, isl_set **doms)
1020 tree nb_iters = number_of_latch_executions (loop);
1021 sese region = SCOP_REGION (scop);
1023 isl_set *inner = isl_set_copy (outer);
1024 isl_space *space;
1025 isl_constraint *c;
1026 int pos = isl_set_dim (outer, isl_dim_set);
1027 isl_val *v;
1028 mpz_t g;
1030 mpz_init (g);
1032 inner = isl_set_add_dims (inner, isl_dim_set, 1);
1033 space = isl_set_get_space (inner);
1035 /* 0 <= loop_i */
1036 c = isl_inequality_alloc
1037 (isl_local_space_from_space (isl_space_copy (space)));
1038 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
1039 inner = isl_set_add_constraint (inner, c);
1041 /* loop_i <= cst_nb_iters */
1042 if (TREE_CODE (nb_iters) == INTEGER_CST)
1044 c = isl_inequality_alloc
1045 (isl_local_space_from_space (isl_space_copy (space)));
1046 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1047 tree_int_to_gmp (nb_iters, g);
1048 v = isl_val_int_from_gmp (the_isl_ctx, g);
1049 c = isl_constraint_set_constant_val (c, v);
1050 inner = isl_set_add_constraint (inner, c);
1053 /* loop_i <= expr_nb_iters */
1054 else if (!chrec_contains_undetermined (nb_iters))
1056 widest_int nit;
1057 isl_pw_aff *aff;
1058 isl_set *valid;
1059 isl_local_space *ls;
1060 isl_aff *al;
1061 isl_set *le;
1063 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1065 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1066 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1067 valid = isl_set_project_out (valid, isl_dim_set, 0,
1068 isl_set_dim (valid, isl_dim_set));
1069 scop->context = isl_set_intersect (scop->context, valid);
1071 ls = isl_local_space_from_space (isl_space_copy (space));
1072 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1073 isl_dim_in, pos, 1);
1074 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1075 isl_pw_aff_copy (aff));
1076 inner = isl_set_intersect (inner, le);
1078 if (max_stmt_executions (loop, &nit))
1080 /* Insert in the context the constraints from the
1081 estimation of the number of iterations NIT and the
1082 symbolic number of iterations (involving parameter
1083 names) NB_ITERS. First, build the affine expression
1084 "NIT - NB_ITERS" and then say that it is positive,
1085 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1086 isl_pw_aff *approx;
1087 mpz_t g;
1088 isl_set *x;
1089 isl_constraint *c;
1091 mpz_init (g);
1092 wi::to_mpz (nit, g, SIGNED);
1093 mpz_sub_ui (g, g, 1);
1094 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1095 x = isl_pw_aff_ge_set (approx, aff);
1096 x = isl_set_project_out (x, isl_dim_set, 0,
1097 isl_set_dim (x, isl_dim_set));
1098 scop->context = isl_set_intersect (scop->context, x);
1100 c = isl_inequality_alloc
1101 (isl_local_space_from_space (isl_space_copy (space)));
1102 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1103 v = isl_val_int_from_gmp (the_isl_ctx, g);
1104 mpz_clear (g);
1105 c = isl_constraint_set_constant_val (c, v);
1106 inner = isl_set_add_constraint (inner, c);
1108 else
1109 isl_pw_aff_free (aff);
1111 else
1112 gcc_unreachable ();
1114 if (loop->inner && loop_in_sese_p (loop->inner, region))
1115 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1116 isl_set_copy (inner), doms);
1118 if (nb != 0
1119 && loop->next
1120 && loop_in_sese_p (loop->next, region))
1121 build_loop_iteration_domains (scop, loop->next, nb,
1122 isl_set_copy (outer), doms);
1124 doms[loop->num] = inner;
1126 isl_set_free (outer);
1127 isl_space_free (space);
1128 mpz_clear (g);
1131 /* Returns a linear expression for tree T evaluated in PBB. */
1133 static isl_pw_aff *
1134 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1136 scop_p scop = PBB_SCOP (pbb);
1138 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1139 gcc_assert (!automatically_generated_chrec_p (t));
1141 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1144 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1145 operator. This allows us to invert the condition or to handle
1146 inequalities. */
1148 static void
1149 add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
1151 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1152 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1153 isl_set *cond;
1155 switch (code)
1157 case LT_EXPR:
1158 cond = isl_pw_aff_lt_set (lhs, rhs);
1159 break;
1161 case GT_EXPR:
1162 cond = isl_pw_aff_gt_set (lhs, rhs);
1163 break;
1165 case LE_EXPR:
1166 cond = isl_pw_aff_le_set (lhs, rhs);
1167 break;
1169 case GE_EXPR:
1170 cond = isl_pw_aff_ge_set (lhs, rhs);
1171 break;
1173 case EQ_EXPR:
1174 cond = isl_pw_aff_eq_set (lhs, rhs);
1175 break;
1177 case NE_EXPR:
1178 cond = isl_pw_aff_ne_set (lhs, rhs);
1179 break;
1181 default:
1182 isl_pw_aff_free (lhs);
1183 isl_pw_aff_free (rhs);
1184 return;
1187 cond = isl_set_coalesce (cond);
1188 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1189 pbb->domain = isl_set_intersect (pbb->domain, cond);
1192 /* Add conditions to the domain of PBB. */
1194 static void
1195 add_conditions_to_domain (poly_bb_p pbb)
1197 unsigned int i;
1198 gimple stmt;
1199 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1201 if (GBB_CONDITIONS (gbb).is_empty ())
1202 return;
1204 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1205 switch (gimple_code (stmt))
1207 case GIMPLE_COND:
1209 gcond *cond_stmt = as_a <gcond *> (stmt);
1210 enum tree_code code = gimple_cond_code (cond_stmt);
1212 /* The conditions for ELSE-branches are inverted. */
1213 if (!GBB_CONDITION_CASES (gbb)[i])
1214 code = invert_tree_comparison (code, false);
1216 add_condition_to_pbb (pbb, cond_stmt, code);
1217 break;
1220 case GIMPLE_SWITCH:
1221 /* Switch statements are not supported right now - fall through. */
1223 default:
1224 gcc_unreachable ();
1225 break;
1229 /* Traverses all the GBBs of the SCOP and add their constraints to the
1230 iteration domains. */
1232 static void
1233 add_conditions_to_constraints (scop_p scop)
1235 int i;
1236 poly_bb_p pbb;
1238 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1239 add_conditions_to_domain (pbb);
1242 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1243 edge between BB and its predecessor is not a loop exit edge, and
1244 the last statement of the single predecessor is a COND_EXPR. */
1246 static gcond *
1247 single_pred_cond_non_loop_exit (basic_block bb)
1249 if (single_pred_p (bb))
1251 edge e = single_pred_edge (bb);
1252 basic_block pred = e->src;
1253 gimple stmt;
1255 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1256 return NULL;
1258 stmt = last_stmt (pred);
1260 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1261 return as_a <gcond *> (stmt);
1264 return NULL;
1267 class sese_dom_walker : public dom_walker
1269 public:
1270 sese_dom_walker (cdi_direction, sese);
1272 virtual void before_dom_children (basic_block);
1273 virtual void after_dom_children (basic_block);
1275 private:
1276 auto_vec<gimple, 3> m_conditions, m_cases;
1277 sese m_region;
1280 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1281 : dom_walker (direction), m_region (region)
1285 /* Call-back for dom_walk executed before visiting the dominated
1286 blocks. */
1288 void
1289 sese_dom_walker::before_dom_children (basic_block bb)
1291 gimple_bb_p gbb;
1292 gcond *stmt;
1294 if (!bb_in_sese_p (bb, m_region))
1295 return;
1297 stmt = single_pred_cond_non_loop_exit (bb);
1299 if (stmt)
1301 edge e = single_pred_edge (bb);
1303 m_conditions.safe_push (stmt);
1305 if (e->flags & EDGE_TRUE_VALUE)
1306 m_cases.safe_push (stmt);
1307 else
1308 m_cases.safe_push (NULL);
1311 gbb = gbb_from_bb (bb);
1313 if (gbb)
1315 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1316 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1320 /* Call-back for dom_walk executed after visiting the dominated
1321 blocks. */
1323 void
1324 sese_dom_walker::after_dom_children (basic_block bb)
1326 if (!bb_in_sese_p (bb, m_region))
1327 return;
1329 if (single_pred_cond_non_loop_exit (bb))
1331 m_conditions.pop ();
1332 m_cases.pop ();
1336 /* Add constraints on the possible values of parameter P from the type
1337 of P. */
1339 static void
1340 add_param_constraints (scop_p scop, graphite_dim_t p)
1342 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1343 tree type = TREE_TYPE (parameter);
1344 tree lb = NULL_TREE;
1345 tree ub = NULL_TREE;
1347 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1348 lb = lower_bound_in_type (type, type);
1349 else
1350 lb = TYPE_MIN_VALUE (type);
1352 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1353 ub = upper_bound_in_type (type, type);
1354 else
1355 ub = TYPE_MAX_VALUE (type);
1357 if (lb)
1359 isl_space *space = isl_set_get_space (scop->context);
1360 isl_constraint *c;
1361 mpz_t g;
1362 isl_val *v;
1364 c = isl_inequality_alloc (isl_local_space_from_space (space));
1365 mpz_init (g);
1366 tree_int_to_gmp (lb, g);
1367 v = isl_val_int_from_gmp (the_isl_ctx, g);
1368 v = isl_val_neg (v);
1369 mpz_clear (g);
1370 c = isl_constraint_set_constant_val (c, v);
1371 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1373 scop->context = isl_set_add_constraint (scop->context, c);
1376 if (ub)
1378 isl_space *space = isl_set_get_space (scop->context);
1379 isl_constraint *c;
1380 mpz_t g;
1381 isl_val *v;
1383 c = isl_inequality_alloc (isl_local_space_from_space (space));
1385 mpz_init (g);
1386 tree_int_to_gmp (ub, g);
1387 v = isl_val_int_from_gmp (the_isl_ctx, g);
1388 mpz_clear (g);
1389 c = isl_constraint_set_constant_val (c, v);
1390 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1392 scop->context = isl_set_add_constraint (scop->context, c);
1396 /* Build the context of the SCOP. The context usually contains extra
1397 constraints that are added to the iteration domains that constrain
1398 some parameters. */
1400 static void
1401 build_scop_context (scop_p scop)
1403 graphite_dim_t p, n = scop_nb_params (scop);
1405 for (p = 0; p < n; p++)
1406 add_param_constraints (scop, p);
1409 /* Build the iteration domains: the loops belonging to the current
1410 SCOP, and that vary for the execution of the current basic block.
1411 Returns false if there is no loop in SCOP. */
1413 static void
1414 build_scop_iteration_domain (scop_p scop)
1416 struct loop *loop;
1417 sese region = SCOP_REGION (scop);
1418 int i;
1419 poly_bb_p pbb;
1420 int nb_loops = number_of_loops (cfun);
1421 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1423 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1424 if (!loop_in_sese_p (loop_outer (loop), region))
1425 build_loop_iteration_domains (scop, loop, 0,
1426 isl_set_copy (scop->context), doms);
1428 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1430 loop = pbb_loop (pbb);
1432 if (doms[loop->num])
1433 pbb->domain = isl_set_copy (doms[loop->num]);
1434 else
1435 pbb->domain = isl_set_copy (scop->context);
1437 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1438 isl_id_for_pbb (scop, pbb));
1441 for (i = 0; i < nb_loops; i++)
1442 if (doms[i])
1443 isl_set_free (doms[i]);
1445 free (doms);
1448 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1449 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1450 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1451 domain. */
1453 static isl_map *
1454 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1456 isl_constraint *c;
1457 int alias_set_num = 0;
1458 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1460 if (bap && bap->alias_set)
1461 alias_set_num = *(bap->alias_set);
1463 c = isl_equality_alloc
1464 (isl_local_space_from_space (isl_map_get_space (acc)));
1465 c = isl_constraint_set_constant_si (c, -alias_set_num);
1466 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1468 return isl_map_add_constraint (acc, c);
1471 /* Assign the affine expression INDEX to the output dimension POS of
1472 MAP and return the result. */
1474 static isl_map *
1475 set_index (isl_map *map, int pos, isl_pw_aff *index)
1477 isl_map *index_map;
1478 int len = isl_map_dim (map, isl_dim_out);
1479 isl_id *id;
1481 index_map = isl_map_from_pw_aff (index);
1482 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1483 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1485 id = isl_map_get_tuple_id (map, isl_dim_out);
1486 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1487 id = isl_map_get_tuple_id (map, isl_dim_in);
1488 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1490 return isl_map_intersect (map, index_map);
1493 /* Add to ACCESSES polyhedron equalities defining the access functions
1494 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1495 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1496 PBB is the poly_bb_p that contains the data reference DR. */
1498 static isl_map *
1499 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1501 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1502 scop_p scop = PBB_SCOP (pbb);
1504 for (i = 0; i < nb_subscripts; i++)
1506 isl_pw_aff *aff;
1507 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1509 aff = extract_affine (scop, afn,
1510 isl_space_domain (isl_map_get_space (acc)));
1511 acc = set_index (acc, i + 1, aff);
1514 return acc;
1517 /* Add constrains representing the size of the accessed data to the
1518 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1519 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1520 domain. */
1522 static isl_set *
1523 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1525 tree ref = DR_REF (dr);
1526 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1528 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1530 tree low, high;
1532 if (TREE_CODE (ref) != ARRAY_REF)
1533 break;
1535 low = array_ref_low_bound (ref);
1536 high = array_ref_up_bound (ref);
1538 /* XXX The PPL code dealt separately with
1539 subscript - low >= 0 and high - subscript >= 0 in case one of
1540 the two bounds isn't known. Do the same here? */
1542 if (tree_fits_shwi_p (low)
1543 && high
1544 && tree_fits_shwi_p (high)
1545 /* 1-element arrays at end of structures may extend over
1546 their declared size. */
1547 && !(array_at_struct_end_p (ref)
1548 && operand_equal_p (low, high, 0)))
1550 isl_id *id;
1551 isl_aff *aff;
1552 isl_set *univ, *lbs, *ubs;
1553 isl_pw_aff *index;
1554 isl_space *space;
1555 isl_set *valid;
1556 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1557 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1559 /* high >= 0 */
1560 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1561 valid = isl_set_project_out (valid, isl_dim_set, 0,
1562 isl_set_dim (valid, isl_dim_set));
1563 scop->context = isl_set_intersect (scop->context, valid);
1565 space = isl_set_get_space (extent);
1566 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1567 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1568 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1569 index = isl_pw_aff_alloc (univ, aff);
1571 id = isl_set_get_tuple_id (extent);
1572 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1573 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1575 /* low <= sub_i <= high */
1576 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1577 ubs = isl_pw_aff_le_set (index, ub);
1578 extent = isl_set_intersect (extent, lbs);
1579 extent = isl_set_intersect (extent, ubs);
1583 return extent;
1586 /* Build data accesses for DR in PBB. */
1588 static void
1589 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1591 int dr_base_object_set;
1592 isl_map *acc;
1593 isl_set *extent;
1594 scop_p scop = PBB_SCOP (pbb);
1597 isl_space *dc = isl_set_get_space (pbb->domain);
1598 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1599 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1600 isl_dim_out, nb_out);
1602 acc = isl_map_universe (space);
1603 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1606 acc = pdr_add_alias_set (acc, dr);
1607 acc = pdr_add_memory_accesses (acc, dr, pbb);
1610 isl_id *id = isl_id_for_dr (scop, dr);
1611 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1612 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1613 int alias_set_num = 0;
1614 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1616 if (bap && bap->alias_set)
1617 alias_set_num = *(bap->alias_set);
1619 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1620 extent = isl_set_nat_universe (space);
1621 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1622 extent = pdr_add_data_dimensions (extent, scop, dr);
1625 gcc_assert (dr->aux);
1626 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1628 new_poly_dr (pbb, dr_base_object_set,
1629 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1630 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1633 /* Write to FILE the alias graph of data references in DIMACS format. */
1635 static inline bool
1636 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1637 vec<data_reference_p> drs)
1639 int num_vertex = drs.length ();
1640 int edge_num = 0;
1641 data_reference_p dr1, dr2;
1642 int i, j;
1644 if (num_vertex == 0)
1645 return true;
1647 FOR_EACH_VEC_ELT (drs, i, dr1)
1648 for (j = i + 1; drs.iterate (j, &dr2); j++)
1649 if (dr_may_alias_p (dr1, dr2, true))
1650 edge_num++;
1652 fprintf (file, "$\n");
1654 if (comment)
1655 fprintf (file, "c %s\n", comment);
1657 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1659 FOR_EACH_VEC_ELT (drs, i, dr1)
1660 for (j = i + 1; drs.iterate (j, &dr2); j++)
1661 if (dr_may_alias_p (dr1, dr2, true))
1662 fprintf (file, "e %d %d\n", i + 1, j + 1);
1664 return true;
1667 /* Write to FILE the alias graph of data references in DOT format. */
1669 static inline bool
1670 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1671 vec<data_reference_p> drs)
1673 int num_vertex = drs.length ();
1674 data_reference_p dr1, dr2;
1675 int i, j;
1677 if (num_vertex == 0)
1678 return true;
1680 fprintf (file, "$\n");
1682 if (comment)
1683 fprintf (file, "c %s\n", comment);
1685 /* First print all the vertices. */
1686 FOR_EACH_VEC_ELT (drs, i, dr1)
1687 fprintf (file, "n%d;\n", i);
1689 FOR_EACH_VEC_ELT (drs, i, dr1)
1690 for (j = i + 1; drs.iterate (j, &dr2); j++)
1691 if (dr_may_alias_p (dr1, dr2, true))
1692 fprintf (file, "n%d n%d\n", i, j);
1694 return true;
1697 /* Write to FILE the alias graph of data references in ECC format. */
1699 static inline bool
1700 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1701 vec<data_reference_p> drs)
1703 int num_vertex = drs.length ();
1704 data_reference_p dr1, dr2;
1705 int i, j;
1707 if (num_vertex == 0)
1708 return true;
1710 fprintf (file, "$\n");
1712 if (comment)
1713 fprintf (file, "c %s\n", comment);
1715 FOR_EACH_VEC_ELT (drs, i, dr1)
1716 for (j = i + 1; drs.iterate (j, &dr2); j++)
1717 if (dr_may_alias_p (dr1, dr2, true))
1718 fprintf (file, "%d %d\n", i, j);
1720 return true;
1723 /* Check if DR1 and DR2 are in the same object set. */
1725 static bool
1726 dr_same_base_object_p (const struct data_reference *dr1,
1727 const struct data_reference *dr2)
1729 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1732 /* Uses DFS component number as representative of alias-sets. Also tests for
1733 optimality by verifying if every connected component is a clique. Returns
1734 true (1) if the above test is true, and false (0) otherwise. */
1736 static int
1737 build_alias_set_optimal_p (vec<data_reference_p> drs)
1739 int num_vertices = drs.length ();
1740 struct graph *g = new_graph (num_vertices);
1741 data_reference_p dr1, dr2;
1742 int i, j;
1743 int num_connected_components;
1744 int v_indx1, v_indx2, num_vertices_in_component;
1745 int *all_vertices;
1746 int *vertices;
1747 struct graph_edge *e;
1748 int this_component_is_clique;
1749 int all_components_are_cliques = 1;
1751 FOR_EACH_VEC_ELT (drs, i, dr1)
1752 for (j = i+1; drs.iterate (j, &dr2); j++)
1753 if (dr_may_alias_p (dr1, dr2, true))
1755 add_edge (g, i, j);
1756 add_edge (g, j, i);
1759 all_vertices = XNEWVEC (int, num_vertices);
1760 vertices = XNEWVEC (int, num_vertices);
1761 for (i = 0; i < num_vertices; i++)
1762 all_vertices[i] = i;
1764 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1765 NULL, true, NULL);
1766 for (i = 0; i < g->n_vertices; i++)
1768 data_reference_p dr = drs[i];
1769 base_alias_pair *bap;
1771 gcc_assert (dr->aux);
1772 bap = (base_alias_pair *)(dr->aux);
1774 bap->alias_set = XNEW (int);
1775 *(bap->alias_set) = g->vertices[i].component + 1;
1778 /* Verify if the DFS numbering results in optimal solution. */
1779 for (i = 0; i < num_connected_components; i++)
1781 num_vertices_in_component = 0;
1782 /* Get all vertices whose DFS component number is the same as i. */
1783 for (j = 0; j < num_vertices; j++)
1784 if (g->vertices[j].component == i)
1785 vertices[num_vertices_in_component++] = j;
1787 /* Now test if the vertices in 'vertices' form a clique, by testing
1788 for edges among each pair. */
1789 this_component_is_clique = 1;
1790 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1792 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1794 /* Check if the two vertices are connected by iterating
1795 through all the edges which have one of these are source. */
1796 e = g->vertices[vertices[v_indx2]].pred;
1797 while (e)
1799 if (e->src == vertices[v_indx1])
1800 break;
1801 e = e->pred_next;
1803 if (!e)
1805 this_component_is_clique = 0;
1806 break;
1809 if (!this_component_is_clique)
1810 all_components_are_cliques = 0;
1814 free (all_vertices);
1815 free (vertices);
1816 free_graph (g);
1817 return all_components_are_cliques;
1820 /* Group each data reference in DRS with its base object set num. */
1822 static void
1823 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1825 int num_vertex = drs.length ();
1826 struct graph *g = new_graph (num_vertex);
1827 data_reference_p dr1, dr2;
1828 int i, j;
1829 int *queue;
1831 FOR_EACH_VEC_ELT (drs, i, dr1)
1832 for (j = i + 1; drs.iterate (j, &dr2); j++)
1833 if (dr_same_base_object_p (dr1, dr2))
1835 add_edge (g, i, j);
1836 add_edge (g, j, i);
1839 queue = XNEWVEC (int, num_vertex);
1840 for (i = 0; i < num_vertex; i++)
1841 queue[i] = i;
1843 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1845 for (i = 0; i < g->n_vertices; i++)
1847 data_reference_p dr = drs[i];
1848 base_alias_pair *bap;
1850 gcc_assert (dr->aux);
1851 bap = (base_alias_pair *)(dr->aux);
1853 bap->base_obj_set = g->vertices[i].component + 1;
1856 free (queue);
1857 free_graph (g);
1860 /* Build the data references for PBB. */
1862 static void
1863 build_pbb_drs (poly_bb_p pbb)
1865 int j;
1866 data_reference_p dr;
1867 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1869 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1870 build_poly_dr (dr, pbb);
1873 /* Dump to file the alias graphs for the data references in DRS. */
1875 static void
1876 dump_alias_graphs (vec<data_reference_p> drs)
1878 char comment[100];
1879 FILE *file_dimacs, *file_ecc, *file_dot;
1881 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1882 if (file_dimacs)
1884 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1885 current_function_name ());
1886 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1887 fclose (file_dimacs);
1890 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1891 if (file_ecc)
1893 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1894 current_function_name ());
1895 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1896 fclose (file_ecc);
1899 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1900 if (file_dot)
1902 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1903 current_function_name ());
1904 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1905 fclose (file_dot);
1909 /* Build data references in SCOP. */
1911 static void
1912 build_scop_drs (scop_p scop)
1914 int i, j;
1915 poly_bb_p pbb;
1916 data_reference_p dr;
1917 auto_vec<data_reference_p, 3> drs;
1919 /* Remove all the PBBs that do not have data references: these basic
1920 blocks are not handled in the polyhedral representation. */
1921 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1922 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1924 free_gimple_bb (PBB_BLACK_BOX (pbb));
1925 free_poly_bb (pbb);
1926 SCOP_BBS (scop).ordered_remove (i);
1927 i--;
1930 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1931 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1932 drs.safe_push (dr);
1934 FOR_EACH_VEC_ELT (drs, i, dr)
1935 dr->aux = XNEW (base_alias_pair);
1937 if (!build_alias_set_optimal_p (drs))
1939 /* TODO: Add support when building alias set is not optimal. */
1943 build_base_obj_set_for_drs (drs);
1945 /* When debugging, enable the following code. This cannot be used
1946 in production compilers. */
1947 if (0)
1948 dump_alias_graphs (drs);
1950 drs.release ();
1952 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1953 build_pbb_drs (pbb);
1956 /* Return a gsi at the position of the phi node STMT. */
1958 static gphi_iterator
1959 gsi_for_phi_node (gphi *stmt)
1961 gphi_iterator psi;
1962 basic_block bb = gimple_bb (stmt);
1964 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1965 if (stmt == psi.phi ())
1966 return psi;
1968 gcc_unreachable ();
1969 return psi;
1972 /* Analyze all the data references of STMTS and add them to the
1973 GBB_DATA_REFS vector of BB. */
1975 static void
1976 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1978 loop_p nest;
1979 gimple_bb_p gbb;
1980 gimple stmt;
1981 int i;
1982 sese region = SCOP_REGION (scop);
1984 if (!bb_in_sese_p (bb, region))
1985 return;
1987 nest = outermost_loop_in_sese_1 (region, bb);
1988 gbb = gbb_from_bb (bb);
1990 FOR_EACH_VEC_ELT (stmts, i, stmt)
1992 loop_p loop;
1994 if (is_gimple_debug (stmt))
1995 continue;
1997 loop = loop_containing_stmt (stmt);
1998 if (!loop_in_sese_p (loop, region))
1999 loop = nest;
2001 graphite_find_data_references_in_stmt (nest, loop, stmt,
2002 &GBB_DATA_REFS (gbb));
2006 /* Insert STMT at the end of the STMTS sequence and then insert the
2007 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2008 on STMTS. */
2010 static void
2011 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2012 gimple_stmt_iterator insert_gsi)
2014 gimple_stmt_iterator gsi;
2015 auto_vec<gimple, 3> x;
2017 gimple_seq_add_stmt (&stmts, stmt);
2018 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2019 x.safe_push (gsi_stmt (gsi));
2021 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2022 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2025 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2027 static void
2028 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2030 gimple_seq stmts;
2031 gimple_stmt_iterator gsi;
2032 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2033 gassign *stmt = gimple_build_assign (unshare_expr (res), var);
2034 auto_vec<gimple, 3> x;
2036 gimple_seq_add_stmt (&stmts, stmt);
2037 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2038 x.safe_push (gsi_stmt (gsi));
2040 if (gimple_code (after_stmt) == GIMPLE_PHI)
2042 gsi = gsi_after_labels (gimple_bb (after_stmt));
2043 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2045 else
2047 gsi = gsi_for_stmt (after_stmt);
2048 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2051 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2054 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2056 static void
2057 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2059 vec<data_reference_p> drs;
2060 drs.create (3);
2061 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2062 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2063 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2064 int index, n = SCOP_BBS (scop).length ();
2066 /* The INDEX of PBB in SCOP_BBS. */
2067 for (index = 0; index < n; index++)
2068 if (SCOP_BBS (scop)[index] == pbb)
2069 break;
2071 pbb1->domain = isl_set_copy (pbb->domain);
2072 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
2073 isl_id_for_pbb (scop, pbb1));
2075 GBB_PBB (gbb1) = pbb1;
2076 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2077 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2078 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2081 /* Insert on edge E the assignment "RES := EXPR". */
2083 static void
2084 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2086 gimple_stmt_iterator gsi;
2087 gimple_seq stmts = NULL;
2088 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2089 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2090 basic_block bb;
2091 auto_vec<gimple, 3> x;
2093 gimple_seq_add_stmt (&stmts, stmt);
2094 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2095 x.safe_push (gsi_stmt (gsi));
2097 gsi_insert_seq_on_edge (e, stmts);
2098 gsi_commit_edge_inserts ();
2099 bb = gimple_bb (stmt);
2101 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2102 return;
2104 if (!gbb_from_bb (bb))
2105 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2107 analyze_drs_in_stmts (scop, bb, x);
2110 /* Creates a zero dimension array of the same type as VAR. */
2112 static tree
2113 create_zero_dim_array (tree var, const char *base_name)
2115 tree index_type = build_index_type (integer_zero_node);
2116 tree elt_type = TREE_TYPE (var);
2117 tree array_type = build_array_type (elt_type, index_type);
2118 tree base = create_tmp_var (array_type, base_name);
2120 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2121 NULL_TREE);
2124 /* Returns true when PHI is a loop close phi node. */
2126 static bool
2127 scalar_close_phi_node_p (gimple phi)
2129 if (gimple_code (phi) != GIMPLE_PHI
2130 || virtual_operand_p (gimple_phi_result (phi)))
2131 return false;
2133 /* Note that loop close phi nodes should have a single argument
2134 because we translated the representation into a canonical form
2135 before Graphite: see canonicalize_loop_closed_ssa_form. */
2136 return (gimple_phi_num_args (phi) == 1);
2139 /* For a definition DEF in REGION, propagates the expression EXPR in
2140 all the uses of DEF outside REGION. */
2142 static void
2143 propagate_expr_outside_region (tree def, tree expr, sese region)
2145 imm_use_iterator imm_iter;
2146 gimple use_stmt;
2147 gimple_seq stmts;
2148 bool replaced_once = false;
2150 gcc_assert (TREE_CODE (def) == SSA_NAME);
2152 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2153 NULL_TREE);
2155 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2156 if (!is_gimple_debug (use_stmt)
2157 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2159 ssa_op_iter iter;
2160 use_operand_p use_p;
2162 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2163 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2164 && (replaced_once = true))
2165 replace_exp (use_p, expr);
2167 update_stmt (use_stmt);
2170 if (replaced_once)
2172 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2173 gsi_commit_edge_inserts ();
2177 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2178 dimension array for it. */
2180 static void
2181 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2183 sese region = SCOP_REGION (scop);
2184 gimple phi = gsi_stmt (*psi);
2185 tree res = gimple_phi_result (phi);
2186 basic_block bb = gimple_bb (phi);
2187 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2188 tree arg = gimple_phi_arg_def (phi, 0);
2189 gimple stmt;
2191 /* Note that loop close phi nodes should have a single argument
2192 because we translated the representation into a canonical form
2193 before Graphite: see canonicalize_loop_closed_ssa_form. */
2194 gcc_assert (gimple_phi_num_args (phi) == 1);
2196 /* The phi node can be a non close phi node, when its argument is
2197 invariant, or a default definition. */
2198 if (is_gimple_min_invariant (arg)
2199 || SSA_NAME_IS_DEFAULT_DEF (arg))
2201 propagate_expr_outside_region (res, arg, region);
2202 gsi_next (psi);
2203 return;
2206 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2208 propagate_expr_outside_region (res, arg, region);
2209 stmt = gimple_build_assign (res, arg);
2210 remove_phi_node (psi, false);
2211 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2212 return;
2215 /* If res is scev analyzable and is not a scalar value, it is safe
2216 to ignore the close phi node: it will be code generated in the
2217 out of Graphite pass. */
2218 else if (scev_analyzable_p (res, region))
2220 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2221 tree scev;
2223 if (!loop_in_sese_p (loop, region))
2225 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2226 scev = scalar_evolution_in_region (region, loop, arg);
2227 scev = compute_overall_effect_of_inner_loop (loop, scev);
2229 else
2230 scev = scalar_evolution_in_region (region, loop, res);
2232 if (tree_does_not_contain_chrecs (scev))
2233 propagate_expr_outside_region (res, scev, region);
2235 gsi_next (psi);
2236 return;
2238 else
2240 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2242 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2244 if (TREE_CODE (arg) == SSA_NAME)
2245 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2246 SSA_NAME_DEF_STMT (arg));
2247 else
2248 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2249 zero_dim_array, arg);
2252 remove_phi_node (psi, false);
2253 SSA_NAME_DEF_STMT (res) = stmt;
2255 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2258 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2259 dimension array for it. */
2261 static void
2262 rewrite_phi_out_of_ssa (scop_p scop, gphi_iterator *psi)
2264 size_t i;
2265 gphi *phi = psi->phi ();
2266 basic_block bb = gimple_bb (phi);
2267 tree res = gimple_phi_result (phi);
2268 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2269 gimple stmt;
2271 for (i = 0; i < gimple_phi_num_args (phi); i++)
2273 tree arg = gimple_phi_arg_def (phi, i);
2274 edge e = gimple_phi_arg_edge (phi, i);
2276 /* Avoid the insertion of code in the loop latch to please the
2277 pattern matching of the vectorizer. */
2278 if (TREE_CODE (arg) == SSA_NAME
2279 && !SSA_NAME_IS_DEFAULT_DEF (arg)
2280 && e->src == bb->loop_father->latch)
2281 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2282 SSA_NAME_DEF_STMT (arg));
2283 else
2284 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2287 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2288 remove_phi_node (psi, false);
2289 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2292 /* Rewrite the degenerate phi node at position PSI from the degenerate
2293 form "x = phi (y, y, ..., y)" to "x = y". */
2295 static void
2296 rewrite_degenerate_phi (gphi_iterator *psi)
2298 tree rhs;
2299 gimple stmt;
2300 gimple_stmt_iterator gsi;
2301 gphi *phi = psi->phi ();
2302 tree res = gimple_phi_result (phi);
2303 basic_block bb;
2305 bb = gimple_bb (phi);
2306 rhs = degenerate_phi_result (phi);
2307 gcc_assert (rhs);
2309 stmt = gimple_build_assign (res, rhs);
2310 remove_phi_node (psi, false);
2312 gsi = gsi_after_labels (bb);
2313 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2316 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2318 static void
2319 rewrite_reductions_out_of_ssa (scop_p scop)
2321 basic_block bb;
2322 gphi_iterator psi;
2323 sese region = SCOP_REGION (scop);
2325 FOR_EACH_BB_FN (bb, cfun)
2326 if (bb_in_sese_p (bb, region))
2327 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2329 gphi *phi = psi.phi ();
2331 if (virtual_operand_p (gimple_phi_result (phi)))
2333 gsi_next (&psi);
2334 continue;
2337 if (gimple_phi_num_args (phi) > 1
2338 && degenerate_phi_result (phi))
2339 rewrite_degenerate_phi (&psi);
2341 else if (scalar_close_phi_node_p (phi))
2342 rewrite_close_phi_out_of_ssa (scop, &psi);
2344 else if (reduction_phi_p (region, &psi))
2345 rewrite_phi_out_of_ssa (scop, &psi);
2348 update_ssa (TODO_update_ssa);
2349 #ifdef ENABLE_CHECKING
2350 verify_loop_closed_ssa (true);
2351 #endif
2354 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2355 read from ZERO_DIM_ARRAY. */
2357 static void
2358 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2359 tree def, gimple use_stmt)
2361 gimple name_stmt;
2362 tree name;
2363 ssa_op_iter iter;
2364 use_operand_p use_p;
2366 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2368 name = copy_ssa_name (def);
2369 name_stmt = gimple_build_assign (name, zero_dim_array);
2371 gimple_assign_set_lhs (name_stmt, name);
2372 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2374 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2375 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2376 replace_exp (use_p, name);
2378 update_stmt (use_stmt);
2381 /* For every definition DEF in the SCOP that is used outside the scop,
2382 insert a closing-scop definition in the basic block just after this
2383 SCOP. */
2385 static void
2386 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2388 tree var = create_tmp_reg (TREE_TYPE (def));
2389 tree new_name = make_ssa_name (var, stmt);
2390 bool needs_copy = false;
2391 use_operand_p use_p;
2392 imm_use_iterator imm_iter;
2393 gimple use_stmt;
2394 sese region = SCOP_REGION (scop);
2396 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2398 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2400 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2402 SET_USE (use_p, new_name);
2404 update_stmt (use_stmt);
2405 needs_copy = true;
2409 /* Insert in the empty BB just after the scop a use of DEF such
2410 that the rewrite of cross_bb_scalar_dependences won't insert
2411 arrays everywhere else. */
2412 if (needs_copy)
2414 gimple assign = gimple_build_assign (new_name, def);
2415 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2417 update_stmt (assign);
2418 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2422 /* Rewrite the scalar dependences crossing the boundary of the BB
2423 containing STMT with an array. Return true when something has been
2424 changed. */
2426 static bool
2427 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2429 sese region = SCOP_REGION (scop);
2430 gimple stmt = gsi_stmt (*gsi);
2431 imm_use_iterator imm_iter;
2432 tree def;
2433 basic_block def_bb;
2434 tree zero_dim_array = NULL_TREE;
2435 gimple use_stmt;
2436 bool res = false;
2438 switch (gimple_code (stmt))
2440 case GIMPLE_ASSIGN:
2441 def = gimple_assign_lhs (stmt);
2442 break;
2444 case GIMPLE_CALL:
2445 def = gimple_call_lhs (stmt);
2446 break;
2448 default:
2449 return false;
2452 if (!def
2453 || !is_gimple_reg (def))
2454 return false;
2456 if (scev_analyzable_p (def, region))
2458 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2459 tree scev = scalar_evolution_in_region (region, loop, def);
2461 if (tree_contains_chrecs (scev, NULL))
2462 return false;
2464 propagate_expr_outside_region (def, scev, region);
2465 return true;
2468 def_bb = gimple_bb (stmt);
2470 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2472 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2473 if (gimple_code (use_stmt) == GIMPLE_PHI
2474 && (res = true))
2476 gphi_iterator psi = gsi_start_phis (gimple_bb (use_stmt));
2478 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2479 rewrite_close_phi_out_of_ssa (scop, &psi);
2480 else
2481 rewrite_phi_out_of_ssa (scop, &psi);
2484 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2485 if (gimple_code (use_stmt) != GIMPLE_PHI
2486 && def_bb != gimple_bb (use_stmt)
2487 && !is_gimple_debug (use_stmt)
2488 && (res = true))
2490 if (!zero_dim_array)
2492 zero_dim_array = create_zero_dim_array
2493 (def, "Cross_BB_scalar_dependence");
2494 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2495 SSA_NAME_DEF_STMT (def));
2496 gsi_next (gsi);
2499 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
2500 def, use_stmt);
2503 return res;
2506 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2508 static void
2509 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2511 basic_block bb;
2512 gimple_stmt_iterator psi;
2513 sese region = SCOP_REGION (scop);
2514 bool changed = false;
2516 /* Create an extra empty BB after the scop. */
2517 split_edge (SESE_EXIT (region));
2519 FOR_EACH_BB_FN (bb, cfun)
2520 if (bb_in_sese_p (bb, region))
2521 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2522 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2524 if (changed)
2526 scev_reset_htab ();
2527 update_ssa (TODO_update_ssa);
2528 #ifdef ENABLE_CHECKING
2529 verify_loop_closed_ssa (true);
2530 #endif
2534 /* Returns the number of pbbs that are in loops contained in SCOP. */
2536 static int
2537 nb_pbbs_in_loops (scop_p scop)
2539 int i;
2540 poly_bb_p pbb;
2541 int res = 0;
2543 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2544 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2545 res++;
2547 return res;
2550 /* Return the number of data references in BB that write in
2551 memory. */
2553 static int
2554 nb_data_writes_in_bb (basic_block bb)
2556 int res = 0;
2557 gimple_stmt_iterator gsi;
2559 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2560 if (gimple_vdef (gsi_stmt (gsi)))
2561 res++;
2563 return res;
2566 /* Splits at STMT the basic block BB represented as PBB in the
2567 polyhedral form. */
2569 static edge
2570 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2572 edge e1 = split_block (bb, stmt);
2573 new_pbb_from_pbb (scop, pbb, e1->dest);
2574 return e1;
2577 /* Splits STMT out of its current BB. This is done for reduction
2578 statements for which we want to ignore data dependences. */
2580 static basic_block
2581 split_reduction_stmt (scop_p scop, gimple stmt)
2583 basic_block bb = gimple_bb (stmt);
2584 poly_bb_p pbb = pbb_from_bb (bb);
2585 gimple_bb_p gbb = gbb_from_bb (bb);
2586 edge e1;
2587 int i;
2588 data_reference_p dr;
2590 /* Do not split basic blocks with no writes to memory: the reduction
2591 will be the only write to memory. */
2592 if (nb_data_writes_in_bb (bb) == 0
2593 /* Or if we have already marked BB as a reduction. */
2594 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2595 return bb;
2597 e1 = split_pbb (scop, pbb, bb, stmt);
2599 /* Split once more only when the reduction stmt is not the only one
2600 left in the original BB. */
2601 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2603 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2604 gsi_prev (&gsi);
2605 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2608 /* A part of the data references will end in a different basic block
2609 after the split: move the DRs from the original GBB to the newly
2610 created GBB1. */
2611 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2613 basic_block bb1 = gimple_bb (DR_STMT (dr));
2615 if (bb1 != bb)
2617 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2618 GBB_DATA_REFS (gbb1).safe_push (dr);
2619 GBB_DATA_REFS (gbb).ordered_remove (i);
2620 i--;
2624 return e1->dest;
2627 /* Return true when stmt is a reduction operation. */
2629 static inline bool
2630 is_reduction_operation_p (gimple stmt)
2632 enum tree_code code;
2634 gcc_assert (is_gimple_assign (stmt));
2635 code = gimple_assign_rhs_code (stmt);
2637 return flag_associative_math
2638 && commutative_tree_code (code)
2639 && associative_tree_code (code);
2642 /* Returns true when PHI contains an argument ARG. */
2644 static bool
2645 phi_contains_arg (gphi *phi, tree arg)
2647 size_t i;
2649 for (i = 0; i < gimple_phi_num_args (phi); i++)
2650 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2651 return true;
2653 return false;
2656 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2658 static gphi *
2659 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2661 gimple stmt;
2663 if (TREE_CODE (arg) != SSA_NAME)
2664 return NULL;
2666 stmt = SSA_NAME_DEF_STMT (arg);
2668 if (gimple_code (stmt) == GIMPLE_NOP
2669 || gimple_code (stmt) == GIMPLE_CALL)
2670 return NULL;
2672 if (gphi *phi = dyn_cast <gphi *> (stmt))
2674 if (phi_contains_arg (phi, lhs))
2675 return phi;
2676 return NULL;
2679 if (!is_gimple_assign (stmt))
2680 return NULL;
2682 if (gimple_num_ops (stmt) == 2)
2683 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2685 if (is_reduction_operation_p (stmt))
2687 gphi *res
2688 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2690 return res ? res :
2691 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2694 return NULL;
2697 /* Detect commutative and associative scalar reductions starting at
2698 the STMT. Return the phi node of the reduction cycle, or NULL. */
2700 static gphi *
2701 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2702 vec<gimple> *in,
2703 vec<gimple> *out)
2705 gphi *phi = follow_ssa_with_commutative_ops (arg, lhs);
2707 if (!phi)
2708 return NULL;
2710 in->safe_push (stmt);
2711 out->safe_push (stmt);
2712 return phi;
2715 /* Detect commutative and associative scalar reductions starting at
2716 STMT. Return the phi node of the reduction cycle, or NULL. */
2718 static gphi *
2719 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2720 vec<gimple> *out)
2722 tree lhs = gimple_assign_lhs (stmt);
2724 if (gimple_num_ops (stmt) == 2)
2725 return detect_commutative_reduction_arg (lhs, stmt,
2726 gimple_assign_rhs1 (stmt),
2727 in, out);
2729 if (is_reduction_operation_p (stmt))
2731 gphi *res = detect_commutative_reduction_arg (lhs, stmt,
2732 gimple_assign_rhs1 (stmt),
2733 in, out);
2734 return res ? res
2735 : detect_commutative_reduction_arg (lhs, stmt,
2736 gimple_assign_rhs2 (stmt),
2737 in, out);
2740 return NULL;
2743 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2745 static gphi *
2746 follow_inital_value_to_phi (tree arg, tree lhs)
2748 gimple stmt;
2750 if (!arg || TREE_CODE (arg) != SSA_NAME)
2751 return NULL;
2753 stmt = SSA_NAME_DEF_STMT (arg);
2755 if (gphi *phi = dyn_cast <gphi *> (stmt))
2756 if (phi_contains_arg (phi, lhs))
2757 return phi;
2759 return NULL;
2763 /* Return the argument of the loop PHI that is the initial value coming
2764 from outside the loop. */
2766 static edge
2767 edge_initial_value_for_loop_phi (gphi *phi)
2769 size_t i;
2771 for (i = 0; i < gimple_phi_num_args (phi); i++)
2773 edge e = gimple_phi_arg_edge (phi, i);
2775 if (loop_depth (e->src->loop_father)
2776 < loop_depth (e->dest->loop_father))
2777 return e;
2780 return NULL;
2783 /* Return the argument of the loop PHI that is the initial value coming
2784 from outside the loop. */
2786 static tree
2787 initial_value_for_loop_phi (gphi *phi)
2789 size_t i;
2791 for (i = 0; i < gimple_phi_num_args (phi); i++)
2793 edge e = gimple_phi_arg_edge (phi, i);
2795 if (loop_depth (e->src->loop_father)
2796 < loop_depth (e->dest->loop_father))
2797 return gimple_phi_arg_def (phi, i);
2800 return NULL_TREE;
2803 /* Returns true when DEF is used outside the reduction cycle of
2804 LOOP_PHI. */
2806 static bool
2807 used_outside_reduction (tree def, gimple loop_phi)
2809 use_operand_p use_p;
2810 imm_use_iterator imm_iter;
2811 loop_p loop = loop_containing_stmt (loop_phi);
2813 /* In LOOP, DEF should be used only in LOOP_PHI. */
2814 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2816 gimple stmt = USE_STMT (use_p);
2818 if (stmt != loop_phi
2819 && !is_gimple_debug (stmt)
2820 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2821 return true;
2824 return false;
2827 /* Detect commutative and associative scalar reductions belonging to
2828 the SCOP starting at the loop closed phi node STMT. Return the phi
2829 node of the reduction cycle, or NULL. */
2831 static gphi *
2832 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2833 vec<gimple> *out)
2835 if (scalar_close_phi_node_p (stmt))
2837 gimple def;
2838 gphi *loop_phi, *phi, *close_phi = as_a <gphi *> (stmt);
2839 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2841 if (TREE_CODE (arg) != SSA_NAME)
2842 return NULL;
2844 /* Note that loop close phi nodes should have a single argument
2845 because we translated the representation into a canonical form
2846 before Graphite: see canonicalize_loop_closed_ssa_form. */
2847 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2849 def = SSA_NAME_DEF_STMT (arg);
2850 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2851 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2852 return NULL;
2854 lhs = gimple_phi_result (close_phi);
2855 init = initial_value_for_loop_phi (loop_phi);
2856 phi = follow_inital_value_to_phi (init, lhs);
2858 if (phi && (used_outside_reduction (lhs, phi)
2859 || !has_single_use (gimple_phi_result (phi))))
2860 return NULL;
2862 in->safe_push (loop_phi);
2863 out->safe_push (close_phi);
2864 return phi;
2867 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2868 return detect_commutative_reduction_assign (stmt, in, out);
2870 return NULL;
2873 /* Translate the scalar reduction statement STMT to an array RED
2874 knowing that its recursive phi node is LOOP_PHI. */
2876 static void
2877 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2878 gimple stmt, gphi *loop_phi)
2880 tree res = gimple_phi_result (loop_phi);
2881 gassign *assign = gimple_build_assign (res, unshare_expr (red));
2882 gimple_stmt_iterator gsi;
2884 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2886 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2887 gsi = gsi_for_stmt (stmt);
2888 gsi_next (&gsi);
2889 insert_stmts (scop, assign, NULL, gsi);
2892 /* Removes the PHI node and resets all the debug stmts that are using
2893 the PHI_RESULT. */
2895 static void
2896 remove_phi (gphi *phi)
2898 imm_use_iterator imm_iter;
2899 tree def;
2900 use_operand_p use_p;
2901 gimple_stmt_iterator gsi;
2902 auto_vec<gimple, 3> update;
2903 unsigned int i;
2904 gimple stmt;
2906 def = PHI_RESULT (phi);
2907 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2909 stmt = USE_STMT (use_p);
2911 if (is_gimple_debug (stmt))
2913 gimple_debug_bind_reset_value (stmt);
2914 update.safe_push (stmt);
2918 FOR_EACH_VEC_ELT (update, i, stmt)
2919 update_stmt (stmt);
2921 gsi = gsi_for_phi_node (phi);
2922 remove_phi_node (&gsi, false);
2925 /* Helper function for for_each_index. For each INDEX of the data
2926 reference REF, returns true when its indices are valid in the loop
2927 nest LOOP passed in as DATA. */
2929 static bool
2930 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2932 loop_p loop;
2933 basic_block header, def_bb;
2934 gimple stmt;
2936 if (TREE_CODE (*index) != SSA_NAME)
2937 return true;
2939 loop = *((loop_p *) data);
2940 header = loop->header;
2941 stmt = SSA_NAME_DEF_STMT (*index);
2943 if (!stmt)
2944 return true;
2946 def_bb = gimple_bb (stmt);
2948 if (!def_bb)
2949 return true;
2951 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2954 /* When the result of a CLOSE_PHI is written to a memory location,
2955 return a pointer to that memory reference, otherwise return
2956 NULL_TREE. */
2958 static tree
2959 close_phi_written_to_memory (gphi *close_phi)
2961 imm_use_iterator imm_iter;
2962 use_operand_p use_p;
2963 gimple stmt;
2964 tree res, def = gimple_phi_result (close_phi);
2966 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2967 if ((stmt = USE_STMT (use_p))
2968 && gimple_code (stmt) == GIMPLE_ASSIGN
2969 && (res = gimple_assign_lhs (stmt)))
2971 switch (TREE_CODE (res))
2973 case VAR_DECL:
2974 case PARM_DECL:
2975 case RESULT_DECL:
2976 return res;
2978 case ARRAY_REF:
2979 case MEM_REF:
2981 tree arg = gimple_phi_arg_def (close_phi, 0);
2982 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2984 /* FIXME: this restriction is for id-{24,25}.f and
2985 could be handled by duplicating the computation of
2986 array indices before the loop of the close_phi. */
2987 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2988 return res;
2990 /* Fallthru. */
2992 default:
2993 continue;
2996 return NULL_TREE;
2999 /* Rewrite out of SSA the reduction described by the loop phi nodes
3000 IN, and the close phi nodes OUT. IN and OUT are structured by loop
3001 levels like this:
3003 IN: stmt, loop_n, ..., loop_0
3004 OUT: stmt, close_n, ..., close_0
3006 the first element is the reduction statement, and the next elements
3007 are the loop and close phi nodes of each of the outer loops. */
3009 static void
3010 translate_scalar_reduction_to_array (scop_p scop,
3011 vec<gimple> in,
3012 vec<gimple> out)
3014 gimple loop_stmt;
3015 unsigned int i = out.length () - 1;
3016 tree red = close_phi_written_to_memory (as_a <gphi *> (out[i]));
3018 FOR_EACH_VEC_ELT (in, i, loop_stmt)
3020 gimple close_stmt = out[i];
3022 if (i == 0)
3024 basic_block bb = split_reduction_stmt (scop, loop_stmt);
3025 poly_bb_p pbb = pbb_from_bb (bb);
3026 PBB_IS_REDUCTION (pbb) = true;
3027 gcc_assert (close_stmt == loop_stmt);
3029 if (!red)
3030 red = create_zero_dim_array
3031 (gimple_assign_lhs (loop_stmt), "Commutative_Associative_Reduction");
3033 translate_scalar_reduction_to_array_for_stmt (scop, red, loop_stmt,
3034 as_a <gphi *> (in[1]));
3035 continue;
3038 gphi *loop_phi = as_a <gphi *> (loop_stmt);
3039 gphi *close_phi = as_a <gphi *> (close_stmt);
3041 if (i == in.length () - 1)
3043 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3044 unshare_expr (red), close_phi);
3045 insert_out_of_ssa_copy_on_edge
3046 (scop, edge_initial_value_for_loop_phi (loop_phi),
3047 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3050 remove_phi (loop_phi);
3051 remove_phi (close_phi);
3055 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3056 true when something has been changed. */
3058 static bool
3059 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3060 gphi *close_phi)
3062 bool res;
3063 auto_vec<gimple, 10> in;
3064 auto_vec<gimple, 10> out;
3066 detect_commutative_reduction (scop, close_phi, &in, &out);
3067 res = in.length () > 1;
3068 if (res)
3069 translate_scalar_reduction_to_array (scop, in, out);
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 gphi_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.phi ()))
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.phi ());
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_p loop;
3105 bool changed = false;
3106 sese region = SCOP_REGION (scop);
3108 FOR_EACH_LOOP (loop, 0)
3109 if (loop_in_sese_p (loop, region))
3110 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3112 if (changed)
3114 scev_reset_htab ();
3115 gsi_commit_edge_inserts ();
3116 update_ssa (TODO_update_ssa);
3117 #ifdef ENABLE_CHECKING
3118 verify_loop_closed_ssa (true);
3119 #endif
3123 /* Can all ivs be represented by a signed integer?
3124 As CLooG might generate negative values in its expressions, signed loop ivs
3125 are required in the backend. */
3127 static bool
3128 scop_ivs_can_be_represented (scop_p scop)
3130 loop_p loop;
3131 gphi_iterator psi;
3132 bool result = true;
3134 FOR_EACH_LOOP (loop, 0)
3136 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3137 continue;
3139 for (psi = gsi_start_phis (loop->header);
3140 !gsi_end_p (psi); gsi_next (&psi))
3142 gphi *phi = psi.phi ();
3143 tree res = PHI_RESULT (phi);
3144 tree type = TREE_TYPE (res);
3146 if (TYPE_UNSIGNED (type)
3147 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3149 result = false;
3150 break;
3153 if (!result)
3154 break;
3157 return result;
3160 /* Builds the polyhedral representation for a SESE region. */
3162 void
3163 build_poly_scop (scop_p scop)
3165 sese region = SCOP_REGION (scop);
3166 graphite_dim_t max_dim;
3168 build_scop_bbs (scop);
3170 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3171 Once CLooG is fixed, remove this guard. Anyways, it makes no
3172 sense to optimize a scop containing only PBBs that do not belong
3173 to any loops. */
3174 if (nb_pbbs_in_loops (scop) == 0)
3175 return;
3177 if (!scop_ivs_can_be_represented (scop))
3178 return;
3180 if (flag_associative_math)
3181 rewrite_commutative_reductions_out_of_ssa (scop);
3183 build_sese_loop_nests (region);
3184 /* Record all conditions in REGION. */
3185 sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
3186 find_scop_parameters (scop);
3188 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3189 if (scop_nb_params (scop) > max_dim)
3190 return;
3192 build_scop_iteration_domain (scop);
3193 build_scop_context (scop);
3194 add_conditions_to_constraints (scop);
3196 /* Rewrite out of SSA only after having translated the
3197 representation to the polyhedral representation to avoid scev
3198 analysis failures. That means that these functions will insert
3199 new data references that they create in the right place. */
3200 rewrite_reductions_out_of_ssa (scop);
3201 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3203 build_scop_drs (scop);
3204 scop_to_lst (scop);
3205 build_scop_scattering (scop);
3207 /* This SCoP has been translated to the polyhedral
3208 representation. */
3209 POLY_SCOP_P (scop) = true;
3211 #endif