Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS hook.
[official-gcc.git] / gcc / graphite-sese-to-poly.c
blobba38e1cb9b20b682b76d5fd539d386832d6f5321
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 "input.h"
44 #include "alias.h"
45 #include "symtab.h"
46 #include "options.h"
47 #include "tree.h"
48 #include "fold-const.h"
49 #include "predict.h"
50 #include "tm.h"
51 #include "hard-reg-set.h"
52 #include "function.h"
53 #include "dominance.h"
54 #include "cfg.h"
55 #include "basic-block.h"
56 #include "tree-ssa-alias.h"
57 #include "internal-fn.h"
58 #include "gimple-expr.h"
59 #include "is-a.h"
60 #include "gimple.h"
61 #include "gimple-iterator.h"
62 #include "gimplify.h"
63 #include "gimplify-me.h"
64 #include "gimple-ssa.h"
65 #include "tree-cfg.h"
66 #include "tree-phinodes.h"
67 #include "ssa-iterators.h"
68 #include "stringpool.h"
69 #include "tree-ssanames.h"
70 #include "tree-ssa-loop-manip.h"
71 #include "tree-ssa-loop-niter.h"
72 #include "tree-ssa-loop.h"
73 #include "tree-into-ssa.h"
74 #include "tree-pass.h"
75 #include "cfgloop.h"
76 #include "tree-chrec.h"
77 #include "tree-data-ref.h"
78 #include "tree-scalar-evolution.h"
79 #include "domwalk.h"
80 #include "sese.h"
81 #include "tree-ssa-propagate.h"
83 #ifdef HAVE_isl
84 #include "rtl.h"
85 #include "flags.h"
86 #include "insn-config.h"
87 #include "expmed.h"
88 #include "dojump.h"
89 #include "explow.h"
90 #include "calls.h"
91 #include "emit-rtl.h"
92 #include "varasm.h"
93 #include "stmt.h"
94 #include "expr.h"
95 #include "graphite-poly.h"
96 #include "graphite-sese-to-poly.h"
99 /* Assigns to RES the value of the INTEGER_CST T. */
101 static inline void
102 tree_int_to_gmp (tree t, mpz_t res)
104 wi::to_mpz (t, res, TYPE_SIGN (TREE_TYPE (t)));
107 /* Returns the index of the PHI argument defined in the outermost
108 loop. */
110 static size_t
111 phi_arg_in_outermost_loop (gphi *phi)
113 loop_p loop = gimple_bb (phi)->loop_father;
114 size_t i, res = 0;
116 for (i = 0; i < gimple_phi_num_args (phi); i++)
117 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
119 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
120 res = i;
123 return res;
126 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
127 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
129 static void
130 remove_simple_copy_phi (gphi_iterator *psi)
132 gphi *phi = psi->phi ();
133 tree res = gimple_phi_result (phi);
134 size_t entry = phi_arg_in_outermost_loop (phi);
135 tree init = gimple_phi_arg_def (phi, entry);
136 gassign *stmt = gimple_build_assign (res, init);
137 edge e = gimple_phi_arg_edge (phi, entry);
139 remove_phi_node (psi, false);
140 gsi_insert_on_edge_immediate (e, stmt);
143 /* Removes an invariant phi node at position PSI by inserting on the
144 loop ENTRY edge the assignment RES = INIT. */
146 static void
147 remove_invariant_phi (sese region, gphi_iterator *psi)
149 gphi *phi = psi->phi ();
150 loop_p loop = loop_containing_stmt (phi);
151 tree res = gimple_phi_result (phi);
152 tree scev = scalar_evolution_in_region (region, loop, res);
153 size_t entry = phi_arg_in_outermost_loop (phi);
154 edge e = gimple_phi_arg_edge (phi, entry);
155 tree var;
156 gassign *stmt;
157 gimple_seq stmts = NULL;
159 if (tree_contains_chrecs (scev, NULL))
160 scev = gimple_phi_arg_def (phi, entry);
162 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
163 stmt = gimple_build_assign (res, var);
164 remove_phi_node (psi, false);
166 gimple_seq_add_stmt (&stmts, stmt);
167 gsi_insert_seq_on_edge (e, stmts);
168 gsi_commit_edge_inserts ();
169 SSA_NAME_DEF_STMT (res) = stmt;
172 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
174 static inline bool
175 simple_copy_phi_p (gphi *phi)
177 tree res;
179 if (gimple_phi_num_args (phi) != 2)
180 return false;
182 res = gimple_phi_result (phi);
183 return (res == gimple_phi_arg_def (phi, 0)
184 || res == gimple_phi_arg_def (phi, 1));
187 /* Returns true when the phi node at position PSI is a reduction phi
188 node in REGION. Otherwise moves the pointer PSI to the next phi to
189 be considered. */
191 static bool
192 reduction_phi_p (sese region, gphi_iterator *psi)
194 loop_p loop;
195 gphi *phi = psi->phi ();
196 tree res = gimple_phi_result (phi);
198 loop = loop_containing_stmt (phi);
200 if (simple_copy_phi_p (phi))
202 /* PRE introduces phi nodes like these, for an example,
203 see id-5.f in the fortran graphite testsuite:
205 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
207 remove_simple_copy_phi (psi);
208 return false;
211 if (scev_analyzable_p (res, region))
213 tree scev = scalar_evolution_in_region (region, loop, res);
215 if (evolution_function_is_invariant_p (scev, loop->num))
216 remove_invariant_phi (region, psi);
217 else
218 gsi_next (psi);
220 return false;
223 /* All the other cases are considered reductions. */
224 return true;
227 /* Store the GRAPHITE representation of BB. */
229 static gimple_bb_p
230 new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
232 struct gimple_bb *gbb;
234 gbb = XNEW (struct gimple_bb);
235 bb->aux = gbb;
236 GBB_BB (gbb) = bb;
237 GBB_DATA_REFS (gbb) = drs;
238 GBB_CONDITIONS (gbb).create (0);
239 GBB_CONDITION_CASES (gbb).create (0);
241 return gbb;
244 static void
245 free_data_refs_aux (vec<data_reference_p> datarefs)
247 unsigned int i;
248 struct data_reference *dr;
250 FOR_EACH_VEC_ELT (datarefs, i, dr)
251 if (dr->aux)
253 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
255 free (bap->alias_set);
257 free (bap);
258 dr->aux = NULL;
261 /* Frees GBB. */
263 static void
264 free_gimple_bb (struct gimple_bb *gbb)
266 free_data_refs_aux (GBB_DATA_REFS (gbb));
267 free_data_refs (GBB_DATA_REFS (gbb));
269 GBB_CONDITIONS (gbb).release ();
270 GBB_CONDITION_CASES (gbb).release ();
271 GBB_BB (gbb)->aux = 0;
272 XDELETE (gbb);
275 /* Deletes all gimple bbs in SCOP. */
277 static void
278 remove_gbbs_in_scop (scop_p scop)
280 int i;
281 poly_bb_p pbb;
283 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
284 free_gimple_bb (PBB_BLACK_BOX (pbb));
287 /* Deletes all scops in SCOPS. */
289 void
290 free_scops (vec<scop_p> scops)
292 int i;
293 scop_p scop;
295 FOR_EACH_VEC_ELT (scops, i, scop)
297 remove_gbbs_in_scop (scop);
298 free_sese (SCOP_REGION (scop));
299 free_scop (scop);
302 scops.release ();
305 /* Same as outermost_loop_in_sese, returns the outermost loop
306 containing BB in REGION, but makes sure that the returned loop
307 belongs to the REGION, and so this returns the first loop in the
308 REGION when the loop containing BB does not belong to REGION. */
310 static loop_p
311 outermost_loop_in_sese_1 (sese region, basic_block bb)
313 loop_p nest = outermost_loop_in_sese (region, bb);
315 if (loop_in_sese_p (nest, region))
316 return nest;
318 /* When the basic block BB does not belong to a loop in the region,
319 return the first loop in the region. */
320 nest = nest->inner;
321 while (nest)
322 if (loop_in_sese_p (nest, region))
323 break;
324 else
325 nest = nest->next;
327 gcc_assert (nest);
328 return nest;
331 /* Generates a polyhedral black box only if the bb contains interesting
332 information. */
334 static gimple_bb_p
335 try_generate_gimple_bb (scop_p scop, basic_block bb)
337 vec<data_reference_p> drs;
338 drs.create (5);
339 sese region = SCOP_REGION (scop);
340 loop_p nest = outermost_loop_in_sese_1 (region, bb);
341 gimple_stmt_iterator gsi;
343 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
345 gimple stmt = gsi_stmt (gsi);
346 loop_p loop;
348 if (is_gimple_debug (stmt))
349 continue;
351 loop = loop_containing_stmt (stmt);
352 if (!loop_in_sese_p (loop, region))
353 loop = nest;
355 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
358 return new_gimple_bb (bb, drs);
361 /* Returns true if all predecessors of BB, that are not dominated by BB, are
362 marked in MAP. The predecessors dominated by BB are loop latches and will
363 be handled after BB. */
365 static bool
366 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
368 edge e;
369 edge_iterator ei;
371 FOR_EACH_EDGE (e, ei, bb->preds)
372 if (!bitmap_bit_p (map, e->src->index)
373 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
374 return false;
376 return true;
379 /* Compare the depth of two basic_block's P1 and P2. */
381 static int
382 compare_bb_depths (const void *p1, const void *p2)
384 const_basic_block const bb1 = *(const_basic_block const*)p1;
385 const_basic_block const bb2 = *(const_basic_block const*)p2;
386 int d1 = loop_depth (bb1->loop_father);
387 int d2 = loop_depth (bb2->loop_father);
389 if (d1 < d2)
390 return 1;
392 if (d1 > d2)
393 return -1;
395 return 0;
398 /* Sort the basic blocks from DOM such that the first are the ones at
399 a deepest loop level. */
401 static void
402 graphite_sort_dominated_info (vec<basic_block> dom)
404 dom.qsort (compare_bb_depths);
407 /* Recursive helper function for build_scops_bbs. */
409 static void
410 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
412 sese region = SCOP_REGION (scop);
413 vec<basic_block> dom;
414 poly_bb_p pbb;
416 if (bitmap_bit_p (visited, bb->index)
417 || !bb_in_sese_p (bb, region))
418 return;
420 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
421 SCOP_BBS (scop).safe_push (pbb);
422 bitmap_set_bit (visited, bb->index);
424 dom = get_dominated_by (CDI_DOMINATORS, bb);
426 if (!dom.exists ())
427 return;
429 graphite_sort_dominated_info (dom);
431 while (!dom.is_empty ())
433 int i;
434 basic_block dom_bb;
436 FOR_EACH_VEC_ELT (dom, i, dom_bb)
437 if (all_non_dominated_preds_marked_p (dom_bb, visited))
439 build_scop_bbs_1 (scop, visited, dom_bb);
440 dom.unordered_remove (i);
441 break;
445 dom.release ();
448 /* Gather the basic blocks belonging to the SCOP. */
450 static void
451 build_scop_bbs (scop_p scop)
453 sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
454 sese region = SCOP_REGION (scop);
456 bitmap_clear (visited);
457 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
458 sbitmap_free (visited);
461 /* Return an ISL identifier for the polyhedral basic block PBB. */
463 static isl_id *
464 isl_id_for_pbb (scop_p s, poly_bb_p pbb)
466 char name[50];
467 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
468 return isl_id_alloc (s->ctx, name, pbb);
471 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
472 We generate SCATTERING_DIMENSIONS scattering dimensions.
474 CLooG 0.15.0 and previous versions require, that all
475 scattering functions of one CloogProgram have the same number of
476 scattering dimensions, therefore we allow to specify it. This
477 should be removed in future versions of CLooG.
479 The scattering polyhedron consists of these dimensions: scattering,
480 loop_iterators, parameters.
482 Example:
484 | scattering_dimensions = 5
485 | used_scattering_dimensions = 3
486 | nb_iterators = 1
487 | scop_nb_params = 2
489 | Schedule:
491 | 4 5
493 | Scattering polyhedron:
495 | scattering: {s1, s2, s3, s4, s5}
496 | loop_iterators: {i}
497 | parameters: {p1, p2}
499 | s1 s2 s3 s4 s5 i p1 p2 1
500 | 1 0 0 0 0 0 0 0 -4 = 0
501 | 0 1 0 0 0 -1 0 0 0 = 0
502 | 0 0 1 0 0 0 0 0 -5 = 0 */
504 static void
505 build_pbb_scattering_polyhedrons (isl_aff *static_sched,
506 poly_bb_p pbb, int scattering_dimensions)
508 int i;
509 int nb_iterators = pbb_dim_iter_domain (pbb);
510 int used_scattering_dimensions = nb_iterators * 2 + 1;
511 isl_val *val;
512 isl_space *dc, *dm;
514 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
516 dc = isl_set_get_space (pbb->domain);
517 dm = isl_space_add_dims (isl_space_from_domain (dc),
518 isl_dim_out, scattering_dimensions);
519 pbb->schedule = isl_map_universe (dm);
521 for (i = 0; i < scattering_dimensions; i++)
523 /* Textual order inside this loop. */
524 if ((i % 2) == 0)
526 isl_constraint *c = isl_equality_alloc
527 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
529 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
531 val = isl_val_neg (val);
532 c = isl_constraint_set_constant_val (c, val);
533 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
534 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
537 /* Iterations of this loop. */
538 else /* if ((i % 2) == 1) */
540 int loop = (i - 1) / 2;
541 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
542 isl_dim_out, i);
546 pbb->transformed = isl_map_copy (pbb->schedule);
549 /* Build for BB the static schedule.
551 The static schedule is a Dewey numbering of the abstract syntax
552 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
554 The following example informally defines the static schedule:
557 for (i: ...)
559 for (j: ...)
565 for (k: ...)
573 Static schedules for A to F:
575 DEPTH
576 0 1 2
578 B 1 0 0
579 C 1 0 1
580 D 1 1 0
581 E 1 1 1
585 static void
586 build_scop_scattering (scop_p scop)
588 int i;
589 poly_bb_p pbb;
590 gimple_bb_p previous_gbb = NULL;
591 isl_space *dc = isl_set_get_space (scop->context);
592 isl_aff *static_sched;
594 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
595 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
597 /* We have to start schedules at 0 on the first component and
598 because we cannot compare_prefix_loops against a previous loop,
599 prefix will be equal to zero, and that index will be
600 incremented before copying. */
601 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
603 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
605 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
606 int prefix;
607 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
609 if (previous_gbb)
610 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
611 else
612 prefix = 0;
614 previous_gbb = gbb;
616 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
617 prefix, 1);
618 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
621 isl_aff_free (static_sched);
624 static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
626 /* Extract an affine expression from the chain of recurrence E. */
628 static isl_pw_aff *
629 extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
631 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
632 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
633 isl_local_space *ls = isl_local_space_from_space (space);
634 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
635 isl_aff *loop = isl_aff_set_coefficient_si
636 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
637 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
639 /* Before multiplying, make sure that the result is affine. */
640 gcc_assert (isl_pw_aff_is_cst (rhs)
641 || isl_pw_aff_is_cst (l));
643 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
646 /* Extract an affine expression from the mult_expr E. */
648 static isl_pw_aff *
649 extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
651 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
652 isl_space_copy (space));
653 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
655 if (!isl_pw_aff_is_cst (lhs)
656 && !isl_pw_aff_is_cst (rhs))
658 isl_pw_aff_free (lhs);
659 isl_pw_aff_free (rhs);
660 return NULL;
663 return isl_pw_aff_mul (lhs, rhs);
666 /* Return an ISL identifier from the name of the ssa_name E. */
668 static isl_id *
669 isl_id_for_ssa_name (scop_p s, tree e)
671 const char *name = get_name (e);
672 isl_id *id;
674 if (name)
675 id = isl_id_alloc (s->ctx, name, e);
676 else
678 char name1[50];
679 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
680 id = isl_id_alloc (s->ctx, name1, e);
683 return id;
686 /* Return an ISL identifier for the data reference DR. */
688 static isl_id *
689 isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
691 /* Data references all get the same isl_id. They need to be comparable
692 and are distinguished through the first dimension, which contains the
693 alias set number. */
694 return isl_id_alloc (s->ctx, "", 0);
697 /* Extract an affine expression from the ssa_name E. */
699 static isl_pw_aff *
700 extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
702 isl_aff *aff;
703 isl_set *dom;
704 isl_id *id;
705 int dimension;
707 id = isl_id_for_ssa_name (s, e);
708 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
709 isl_id_free (id);
710 dom = isl_set_universe (isl_space_copy (space));
711 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
712 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
713 return isl_pw_aff_alloc (dom, aff);
716 /* Extract an affine expression from the gmp constant G. */
718 static isl_pw_aff *
719 extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
721 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
722 isl_aff *aff = isl_aff_zero_on_domain (ls);
723 isl_set *dom = isl_set_universe (space);
724 isl_val *v;
725 isl_ctx *ct;
727 ct = isl_aff_get_ctx (aff);
728 v = isl_val_int_from_gmp (ct, g);
729 aff = isl_aff_add_constant_val (aff, v);
731 return isl_pw_aff_alloc (dom, aff);
734 /* Extract an affine expression from the integer_cst E. */
736 static isl_pw_aff *
737 extract_affine_int (tree e, __isl_take isl_space *space)
739 isl_pw_aff *res;
740 mpz_t g;
742 mpz_init (g);
743 tree_int_to_gmp (e, g);
744 res = extract_affine_gmp (g, space);
745 mpz_clear (g);
747 return res;
750 /* Compute pwaff mod 2^width. */
752 extern isl_ctx *the_isl_ctx;
754 static isl_pw_aff *
755 wrap (isl_pw_aff *pwaff, unsigned width)
757 isl_val *mod;
759 mod = isl_val_int_from_ui(the_isl_ctx, width);
760 mod = isl_val_2exp (mod);
761 pwaff = isl_pw_aff_mod_val (pwaff, mod);
763 return pwaff;
766 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
767 Otherwise returns -1. */
769 static inline int
770 parameter_index_in_region_1 (tree name, sese region)
772 int i;
773 tree p;
775 gcc_assert (TREE_CODE (name) == SSA_NAME);
777 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
778 if (p == name)
779 return i;
781 return -1;
784 /* When the parameter NAME is in REGION, returns its index in
785 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
786 and returns the index of NAME. */
788 static int
789 parameter_index_in_region (tree name, sese region)
791 int i;
793 gcc_assert (TREE_CODE (name) == SSA_NAME);
795 i = parameter_index_in_region_1 (name, region);
796 if (i != -1)
797 return i;
799 gcc_assert (SESE_ADD_PARAMS (region));
801 i = SESE_PARAMS (region).length ();
802 SESE_PARAMS (region).safe_push (name);
803 return i;
806 /* Extract an affine expression from the tree E in the scop S. */
808 static isl_pw_aff *
809 extract_affine (scop_p s, tree e, __isl_take isl_space *space)
811 isl_pw_aff *lhs, *rhs, *res;
812 tree type;
814 if (e == chrec_dont_know) {
815 isl_space_free (space);
816 return NULL;
819 switch (TREE_CODE (e))
821 case POLYNOMIAL_CHREC:
822 res = extract_affine_chrec (s, e, space);
823 break;
825 case MULT_EXPR:
826 res = extract_affine_mul (s, e, space);
827 break;
829 case PLUS_EXPR:
830 case POINTER_PLUS_EXPR:
831 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
832 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
833 res = isl_pw_aff_add (lhs, rhs);
834 break;
836 case MINUS_EXPR:
837 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
838 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
839 res = isl_pw_aff_sub (lhs, rhs);
840 break;
842 case NEGATE_EXPR:
843 case BIT_NOT_EXPR:
844 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
845 rhs = extract_affine (s, integer_minus_one_node, space);
846 res = isl_pw_aff_mul (lhs, rhs);
847 break;
849 case SSA_NAME:
850 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
851 res = extract_affine_name (s, e, space);
852 break;
854 case INTEGER_CST:
855 res = extract_affine_int (e, space);
856 /* No need to wrap a single integer. */
857 return res;
859 CASE_CONVERT:
860 case NON_LVALUE_EXPR:
861 res = extract_affine (s, TREE_OPERAND (e, 0), space);
862 break;
864 default:
865 gcc_unreachable ();
866 break;
869 type = TREE_TYPE (e);
870 if (TYPE_UNSIGNED (type))
871 res = wrap (res, TYPE_PRECISION (type));
873 return res;
876 /* In the context of sese S, scan the expression E and translate it to
877 a linear expression C. When parsing a symbolic multiplication, K
878 represents the constant multiplier of an expression containing
879 parameters. */
881 static void
882 scan_tree_for_params (sese s, tree e)
884 if (e == chrec_dont_know)
885 return;
887 switch (TREE_CODE (e))
889 case POLYNOMIAL_CHREC:
890 scan_tree_for_params (s, CHREC_LEFT (e));
891 break;
893 case MULT_EXPR:
894 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
895 scan_tree_for_params (s, TREE_OPERAND (e, 0));
896 else
897 scan_tree_for_params (s, TREE_OPERAND (e, 1));
898 break;
900 case PLUS_EXPR:
901 case POINTER_PLUS_EXPR:
902 case MINUS_EXPR:
903 scan_tree_for_params (s, TREE_OPERAND (e, 0));
904 scan_tree_for_params (s, TREE_OPERAND (e, 1));
905 break;
907 case NEGATE_EXPR:
908 case BIT_NOT_EXPR:
909 CASE_CONVERT:
910 case NON_LVALUE_EXPR:
911 scan_tree_for_params (s, TREE_OPERAND (e, 0));
912 break;
914 case SSA_NAME:
915 parameter_index_in_region (e, s);
916 break;
918 case INTEGER_CST:
919 case ADDR_EXPR:
920 break;
922 default:
923 gcc_unreachable ();
924 break;
928 /* Find parameters with respect to REGION in BB. We are looking in memory
929 access functions, conditions and loop bounds. */
931 static void
932 find_params_in_bb (sese region, gimple_bb_p gbb)
934 int i;
935 unsigned j;
936 data_reference_p dr;
937 gimple stmt;
938 loop_p loop = GBB_BB (gbb)->loop_father;
940 /* Find parameters in the access functions of data references. */
941 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
942 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
943 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
945 /* Find parameters in conditional statements. */
946 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
948 tree lhs = scalar_evolution_in_region (region, loop,
949 gimple_cond_lhs (stmt));
950 tree rhs = scalar_evolution_in_region (region, loop,
951 gimple_cond_rhs (stmt));
953 scan_tree_for_params (region, lhs);
954 scan_tree_for_params (region, rhs);
958 /* Record the parameters used in the SCOP. A variable is a parameter
959 in a scop if it does not vary during the execution of that scop. */
961 static void
962 find_scop_parameters (scop_p scop)
964 poly_bb_p pbb;
965 unsigned i;
966 sese region = SCOP_REGION (scop);
967 struct loop *loop;
968 int nbp;
970 /* Find the parameters used in the loop bounds. */
971 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
973 tree nb_iters = number_of_latch_executions (loop);
975 if (!chrec_contains_symbols (nb_iters))
976 continue;
978 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
979 scan_tree_for_params (region, nb_iters);
982 /* Find the parameters used in data accesses. */
983 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
984 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
986 nbp = sese_nb_params (region);
987 scop_set_nb_params (scop, nbp);
988 SESE_ADD_PARAMS (region) = false;
991 tree e;
992 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
994 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
995 space = isl_space_set_dim_id (space, isl_dim_param, i,
996 isl_id_for_ssa_name (scop, e));
998 scop->context = isl_set_universe (space);
1002 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1003 the constraints for the surrounding loops. */
1005 static void
1006 build_loop_iteration_domains (scop_p scop, struct loop *loop,
1007 int nb,
1008 isl_set *outer, isl_set **doms)
1010 tree nb_iters = number_of_latch_executions (loop);
1011 sese region = SCOP_REGION (scop);
1013 isl_set *inner = isl_set_copy (outer);
1014 isl_space *space;
1015 isl_constraint *c;
1016 int pos = isl_set_dim (outer, isl_dim_set);
1017 isl_val *v;
1018 mpz_t g;
1020 mpz_init (g);
1022 inner = isl_set_add_dims (inner, isl_dim_set, 1);
1023 space = isl_set_get_space (inner);
1025 /* 0 <= loop_i */
1026 c = isl_inequality_alloc
1027 (isl_local_space_from_space (isl_space_copy (space)));
1028 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
1029 inner = isl_set_add_constraint (inner, c);
1031 /* loop_i <= cst_nb_iters */
1032 if (TREE_CODE (nb_iters) == INTEGER_CST)
1034 c = isl_inequality_alloc
1035 (isl_local_space_from_space (isl_space_copy (space)));
1036 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1037 tree_int_to_gmp (nb_iters, g);
1038 v = isl_val_int_from_gmp (the_isl_ctx, g);
1039 c = isl_constraint_set_constant_val (c, v);
1040 inner = isl_set_add_constraint (inner, c);
1043 /* loop_i <= expr_nb_iters */
1044 else if (!chrec_contains_undetermined (nb_iters))
1046 widest_int nit;
1047 isl_pw_aff *aff;
1048 isl_set *valid;
1049 isl_local_space *ls;
1050 isl_aff *al;
1051 isl_set *le;
1053 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1055 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1056 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1057 valid = isl_set_project_out (valid, isl_dim_set, 0,
1058 isl_set_dim (valid, isl_dim_set));
1059 scop->context = isl_set_intersect (scop->context, valid);
1061 ls = isl_local_space_from_space (isl_space_copy (space));
1062 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1063 isl_dim_in, pos, 1);
1064 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1065 isl_pw_aff_copy (aff));
1066 inner = isl_set_intersect (inner, le);
1068 if (max_stmt_executions (loop, &nit))
1070 /* Insert in the context the constraints from the
1071 estimation of the number of iterations NIT and the
1072 symbolic number of iterations (involving parameter
1073 names) NB_ITERS. First, build the affine expression
1074 "NIT - NB_ITERS" and then say that it is positive,
1075 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1076 isl_pw_aff *approx;
1077 mpz_t g;
1078 isl_set *x;
1079 isl_constraint *c;
1081 mpz_init (g);
1082 wi::to_mpz (nit, g, SIGNED);
1083 mpz_sub_ui (g, g, 1);
1084 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1085 x = isl_pw_aff_ge_set (approx, aff);
1086 x = isl_set_project_out (x, isl_dim_set, 0,
1087 isl_set_dim (x, isl_dim_set));
1088 scop->context = isl_set_intersect (scop->context, x);
1090 c = isl_inequality_alloc
1091 (isl_local_space_from_space (isl_space_copy (space)));
1092 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1093 v = isl_val_int_from_gmp (the_isl_ctx, g);
1094 mpz_clear (g);
1095 c = isl_constraint_set_constant_val (c, v);
1096 inner = isl_set_add_constraint (inner, c);
1098 else
1099 isl_pw_aff_free (aff);
1101 else
1102 gcc_unreachable ();
1104 if (loop->inner && loop_in_sese_p (loop->inner, region))
1105 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1106 isl_set_copy (inner), doms);
1108 if (nb != 0
1109 && loop->next
1110 && loop_in_sese_p (loop->next, region))
1111 build_loop_iteration_domains (scop, loop->next, nb,
1112 isl_set_copy (outer), doms);
1114 doms[loop->num] = inner;
1116 isl_set_free (outer);
1117 isl_space_free (space);
1118 mpz_clear (g);
1121 /* Returns a linear expression for tree T evaluated in PBB. */
1123 static isl_pw_aff *
1124 create_pw_aff_from_tree (poly_bb_p pbb, tree t)
1126 scop_p scop = PBB_SCOP (pbb);
1128 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
1129 gcc_assert (!automatically_generated_chrec_p (t));
1131 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
1134 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1135 operator. This allows us to invert the condition or to handle
1136 inequalities. */
1138 static void
1139 add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
1141 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1142 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1143 isl_set *cond;
1145 switch (code)
1147 case LT_EXPR:
1148 cond = isl_pw_aff_lt_set (lhs, rhs);
1149 break;
1151 case GT_EXPR:
1152 cond = isl_pw_aff_gt_set (lhs, rhs);
1153 break;
1155 case LE_EXPR:
1156 cond = isl_pw_aff_le_set (lhs, rhs);
1157 break;
1159 case GE_EXPR:
1160 cond = isl_pw_aff_ge_set (lhs, rhs);
1161 break;
1163 case EQ_EXPR:
1164 cond = isl_pw_aff_eq_set (lhs, rhs);
1165 break;
1167 case NE_EXPR:
1168 cond = isl_pw_aff_ne_set (lhs, rhs);
1169 break;
1171 default:
1172 isl_pw_aff_free (lhs);
1173 isl_pw_aff_free (rhs);
1174 return;
1177 cond = isl_set_coalesce (cond);
1178 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1179 pbb->domain = isl_set_intersect (pbb->domain, cond);
1182 /* Add conditions to the domain of PBB. */
1184 static void
1185 add_conditions_to_domain (poly_bb_p pbb)
1187 unsigned int i;
1188 gimple stmt;
1189 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1191 if (GBB_CONDITIONS (gbb).is_empty ())
1192 return;
1194 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
1195 switch (gimple_code (stmt))
1197 case GIMPLE_COND:
1199 gcond *cond_stmt = as_a <gcond *> (stmt);
1200 enum tree_code code = gimple_cond_code (cond_stmt);
1202 /* The conditions for ELSE-branches are inverted. */
1203 if (!GBB_CONDITION_CASES (gbb)[i])
1204 code = invert_tree_comparison (code, false);
1206 add_condition_to_pbb (pbb, cond_stmt, code);
1207 break;
1210 case GIMPLE_SWITCH:
1211 /* Switch statements are not supported right now - fall through. */
1213 default:
1214 gcc_unreachable ();
1215 break;
1219 /* Traverses all the GBBs of the SCOP and add their constraints to the
1220 iteration domains. */
1222 static void
1223 add_conditions_to_constraints (scop_p scop)
1225 int i;
1226 poly_bb_p pbb;
1228 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1229 add_conditions_to_domain (pbb);
1232 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1233 edge between BB and its predecessor is not a loop exit edge, and
1234 the last statement of the single predecessor is a COND_EXPR. */
1236 static gcond *
1237 single_pred_cond_non_loop_exit (basic_block bb)
1239 if (single_pred_p (bb))
1241 edge e = single_pred_edge (bb);
1242 basic_block pred = e->src;
1243 gimple stmt;
1245 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1246 return NULL;
1248 stmt = last_stmt (pred);
1250 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1251 return as_a <gcond *> (stmt);
1254 return NULL;
1257 class sese_dom_walker : public dom_walker
1259 public:
1260 sese_dom_walker (cdi_direction, sese);
1262 virtual void before_dom_children (basic_block);
1263 virtual void after_dom_children (basic_block);
1265 private:
1266 auto_vec<gimple, 3> m_conditions, m_cases;
1267 sese m_region;
1270 sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
1271 : dom_walker (direction), m_region (region)
1275 /* Call-back for dom_walk executed before visiting the dominated
1276 blocks. */
1278 void
1279 sese_dom_walker::before_dom_children (basic_block bb)
1281 gimple_bb_p gbb;
1282 gcond *stmt;
1284 if (!bb_in_sese_p (bb, m_region))
1285 return;
1287 stmt = single_pred_cond_non_loop_exit (bb);
1289 if (stmt)
1291 edge e = single_pred_edge (bb);
1293 m_conditions.safe_push (stmt);
1295 if (e->flags & EDGE_TRUE_VALUE)
1296 m_cases.safe_push (stmt);
1297 else
1298 m_cases.safe_push (NULL);
1301 gbb = gbb_from_bb (bb);
1303 if (gbb)
1305 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1306 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
1310 /* Call-back for dom_walk executed after visiting the dominated
1311 blocks. */
1313 void
1314 sese_dom_walker::after_dom_children (basic_block bb)
1316 if (!bb_in_sese_p (bb, m_region))
1317 return;
1319 if (single_pred_cond_non_loop_exit (bb))
1321 m_conditions.pop ();
1322 m_cases.pop ();
1326 /* Add constraints on the possible values of parameter P from the type
1327 of P. */
1329 static void
1330 add_param_constraints (scop_p scop, graphite_dim_t p)
1332 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
1333 tree type = TREE_TYPE (parameter);
1334 tree lb = NULL_TREE;
1335 tree ub = NULL_TREE;
1337 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1338 lb = lower_bound_in_type (type, type);
1339 else
1340 lb = TYPE_MIN_VALUE (type);
1342 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1343 ub = upper_bound_in_type (type, type);
1344 else
1345 ub = TYPE_MAX_VALUE (type);
1347 if (lb)
1349 isl_space *space = isl_set_get_space (scop->context);
1350 isl_constraint *c;
1351 mpz_t g;
1352 isl_val *v;
1354 c = isl_inequality_alloc (isl_local_space_from_space (space));
1355 mpz_init (g);
1356 tree_int_to_gmp (lb, g);
1357 v = isl_val_int_from_gmp (the_isl_ctx, g);
1358 v = isl_val_neg (v);
1359 mpz_clear (g);
1360 c = isl_constraint_set_constant_val (c, v);
1361 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1363 scop->context = isl_set_add_constraint (scop->context, c);
1366 if (ub)
1368 isl_space *space = isl_set_get_space (scop->context);
1369 isl_constraint *c;
1370 mpz_t g;
1371 isl_val *v;
1373 c = isl_inequality_alloc (isl_local_space_from_space (space));
1375 mpz_init (g);
1376 tree_int_to_gmp (ub, g);
1377 v = isl_val_int_from_gmp (the_isl_ctx, g);
1378 mpz_clear (g);
1379 c = isl_constraint_set_constant_val (c, v);
1380 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1382 scop->context = isl_set_add_constraint (scop->context, c);
1386 /* Build the context of the SCOP. The context usually contains extra
1387 constraints that are added to the iteration domains that constrain
1388 some parameters. */
1390 static void
1391 build_scop_context (scop_p scop)
1393 graphite_dim_t p, n = scop_nb_params (scop);
1395 for (p = 0; p < n; p++)
1396 add_param_constraints (scop, p);
1399 /* Build the iteration domains: the loops belonging to the current
1400 SCOP, and that vary for the execution of the current basic block.
1401 Returns false if there is no loop in SCOP. */
1403 static void
1404 build_scop_iteration_domain (scop_p scop)
1406 struct loop *loop;
1407 sese region = SCOP_REGION (scop);
1408 int i;
1409 poly_bb_p pbb;
1410 int nb_loops = number_of_loops (cfun);
1411 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
1413 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
1414 if (!loop_in_sese_p (loop_outer (loop), region))
1415 build_loop_iteration_domains (scop, loop, 0,
1416 isl_set_copy (scop->context), doms);
1418 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1420 loop = pbb_loop (pbb);
1422 if (doms[loop->num])
1423 pbb->domain = isl_set_copy (doms[loop->num]);
1424 else
1425 pbb->domain = isl_set_copy (scop->context);
1427 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1428 isl_id_for_pbb (scop, pbb));
1431 for (i = 0; i < nb_loops; i++)
1432 if (doms[i])
1433 isl_set_free (doms[i]);
1435 free (doms);
1438 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1439 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1440 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1441 domain. */
1443 static isl_map *
1444 pdr_add_alias_set (isl_map *acc, data_reference_p dr)
1446 isl_constraint *c;
1447 int alias_set_num = 0;
1448 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1450 if (bap && bap->alias_set)
1451 alias_set_num = *(bap->alias_set);
1453 c = isl_equality_alloc
1454 (isl_local_space_from_space (isl_map_get_space (acc)));
1455 c = isl_constraint_set_constant_si (c, -alias_set_num);
1456 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1458 return isl_map_add_constraint (acc, c);
1461 /* Assign the affine expression INDEX to the output dimension POS of
1462 MAP and return the result. */
1464 static isl_map *
1465 set_index (isl_map *map, int pos, isl_pw_aff *index)
1467 isl_map *index_map;
1468 int len = isl_map_dim (map, isl_dim_out);
1469 isl_id *id;
1471 index_map = isl_map_from_pw_aff (index);
1472 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1473 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
1475 id = isl_map_get_tuple_id (map, isl_dim_out);
1476 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1477 id = isl_map_get_tuple_id (map, isl_dim_in);
1478 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
1480 return isl_map_intersect (map, index_map);
1483 /* Add to ACCESSES polyhedron equalities defining the access functions
1484 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1485 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1486 PBB is the poly_bb_p that contains the data reference DR. */
1488 static isl_map *
1489 pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
1491 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1492 scop_p scop = PBB_SCOP (pbb);
1494 for (i = 0; i < nb_subscripts; i++)
1496 isl_pw_aff *aff;
1497 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1499 aff = extract_affine (scop, afn,
1500 isl_space_domain (isl_map_get_space (acc)));
1501 acc = set_index (acc, i + 1, aff);
1504 return acc;
1507 /* Add constrains representing the size of the accessed data to the
1508 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1509 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1510 domain. */
1512 static isl_set *
1513 pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
1515 tree ref = DR_REF (dr);
1516 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1518 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1520 tree low, high;
1522 if (TREE_CODE (ref) != ARRAY_REF)
1523 break;
1525 low = array_ref_low_bound (ref);
1526 high = array_ref_up_bound (ref);
1528 /* XXX The PPL code dealt separately with
1529 subscript - low >= 0 and high - subscript >= 0 in case one of
1530 the two bounds isn't known. Do the same here? */
1532 if (tree_fits_shwi_p (low)
1533 && high
1534 && tree_fits_shwi_p (high)
1535 /* 1-element arrays at end of structures may extend over
1536 their declared size. */
1537 && !(array_at_struct_end_p (ref)
1538 && operand_equal_p (low, high, 0)))
1540 isl_id *id;
1541 isl_aff *aff;
1542 isl_set *univ, *lbs, *ubs;
1543 isl_pw_aff *index;
1544 isl_space *space;
1545 isl_set *valid;
1546 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1547 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1549 /* high >= 0 */
1550 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1551 valid = isl_set_project_out (valid, isl_dim_set, 0,
1552 isl_set_dim (valid, isl_dim_set));
1553 scop->context = isl_set_intersect (scop->context, valid);
1555 space = isl_set_get_space (extent);
1556 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1557 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1558 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1559 index = isl_pw_aff_alloc (univ, aff);
1561 id = isl_set_get_tuple_id (extent);
1562 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1563 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1565 /* low <= sub_i <= high */
1566 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1567 ubs = isl_pw_aff_le_set (index, ub);
1568 extent = isl_set_intersect (extent, lbs);
1569 extent = isl_set_intersect (extent, ubs);
1573 return extent;
1576 /* Build data accesses for DR in PBB. */
1578 static void
1579 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1581 int dr_base_object_set;
1582 isl_map *acc;
1583 isl_set *extent;
1584 scop_p scop = PBB_SCOP (pbb);
1587 isl_space *dc = isl_set_get_space (pbb->domain);
1588 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1589 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1590 isl_dim_out, nb_out);
1592 acc = isl_map_universe (space);
1593 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1596 acc = pdr_add_alias_set (acc, dr);
1597 acc = pdr_add_memory_accesses (acc, dr, pbb);
1600 isl_id *id = isl_id_for_dr (scop, dr);
1601 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1602 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1603 int alias_set_num = 0;
1604 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1606 if (bap && bap->alias_set)
1607 alias_set_num = *(bap->alias_set);
1609 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1610 extent = isl_set_nat_universe (space);
1611 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1612 extent = pdr_add_data_dimensions (extent, scop, dr);
1615 gcc_assert (dr->aux);
1616 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1618 new_poly_dr (pbb, dr_base_object_set,
1619 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1620 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
1623 /* Write to FILE the alias graph of data references in DIMACS format. */
1625 static inline bool
1626 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1627 vec<data_reference_p> drs)
1629 int num_vertex = drs.length ();
1630 int edge_num = 0;
1631 data_reference_p dr1, dr2;
1632 int i, j;
1634 if (num_vertex == 0)
1635 return true;
1637 FOR_EACH_VEC_ELT (drs, i, dr1)
1638 for (j = i + 1; drs.iterate (j, &dr2); j++)
1639 if (dr_may_alias_p (dr1, dr2, true))
1640 edge_num++;
1642 fprintf (file, "$\n");
1644 if (comment)
1645 fprintf (file, "c %s\n", comment);
1647 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1649 FOR_EACH_VEC_ELT (drs, i, dr1)
1650 for (j = i + 1; drs.iterate (j, &dr2); j++)
1651 if (dr_may_alias_p (dr1, dr2, true))
1652 fprintf (file, "e %d %d\n", i + 1, j + 1);
1654 return true;
1657 /* Write to FILE the alias graph of data references in DOT format. */
1659 static inline bool
1660 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1661 vec<data_reference_p> drs)
1663 int num_vertex = drs.length ();
1664 data_reference_p dr1, dr2;
1665 int i, j;
1667 if (num_vertex == 0)
1668 return true;
1670 fprintf (file, "$\n");
1672 if (comment)
1673 fprintf (file, "c %s\n", comment);
1675 /* First print all the vertices. */
1676 FOR_EACH_VEC_ELT (drs, i, dr1)
1677 fprintf (file, "n%d;\n", i);
1679 FOR_EACH_VEC_ELT (drs, i, dr1)
1680 for (j = i + 1; drs.iterate (j, &dr2); j++)
1681 if (dr_may_alias_p (dr1, dr2, true))
1682 fprintf (file, "n%d n%d\n", i, j);
1684 return true;
1687 /* Write to FILE the alias graph of data references in ECC format. */
1689 static inline bool
1690 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1691 vec<data_reference_p> drs)
1693 int num_vertex = drs.length ();
1694 data_reference_p dr1, dr2;
1695 int i, j;
1697 if (num_vertex == 0)
1698 return true;
1700 fprintf (file, "$\n");
1702 if (comment)
1703 fprintf (file, "c %s\n", comment);
1705 FOR_EACH_VEC_ELT (drs, i, dr1)
1706 for (j = i + 1; drs.iterate (j, &dr2); j++)
1707 if (dr_may_alias_p (dr1, dr2, true))
1708 fprintf (file, "%d %d\n", i, j);
1710 return true;
1713 /* Check if DR1 and DR2 are in the same object set. */
1715 static bool
1716 dr_same_base_object_p (const struct data_reference *dr1,
1717 const struct data_reference *dr2)
1719 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1722 /* Uses DFS component number as representative of alias-sets. Also tests for
1723 optimality by verifying if every connected component is a clique. Returns
1724 true (1) if the above test is true, and false (0) otherwise. */
1726 static int
1727 build_alias_set_optimal_p (vec<data_reference_p> drs)
1729 int num_vertices = drs.length ();
1730 struct graph *g = new_graph (num_vertices);
1731 data_reference_p dr1, dr2;
1732 int i, j;
1733 int num_connected_components;
1734 int v_indx1, v_indx2, num_vertices_in_component;
1735 int *all_vertices;
1736 int *vertices;
1737 struct graph_edge *e;
1738 int this_component_is_clique;
1739 int all_components_are_cliques = 1;
1741 FOR_EACH_VEC_ELT (drs, i, dr1)
1742 for (j = i+1; drs.iterate (j, &dr2); j++)
1743 if (dr_may_alias_p (dr1, dr2, true))
1745 add_edge (g, i, j);
1746 add_edge (g, j, i);
1749 all_vertices = XNEWVEC (int, num_vertices);
1750 vertices = XNEWVEC (int, num_vertices);
1751 for (i = 0; i < num_vertices; i++)
1752 all_vertices[i] = i;
1754 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1755 NULL, true, NULL);
1756 for (i = 0; i < g->n_vertices; i++)
1758 data_reference_p dr = drs[i];
1759 base_alias_pair *bap;
1761 gcc_assert (dr->aux);
1762 bap = (base_alias_pair *)(dr->aux);
1764 bap->alias_set = XNEW (int);
1765 *(bap->alias_set) = g->vertices[i].component + 1;
1768 /* Verify if the DFS numbering results in optimal solution. */
1769 for (i = 0; i < num_connected_components; i++)
1771 num_vertices_in_component = 0;
1772 /* Get all vertices whose DFS component number is the same as i. */
1773 for (j = 0; j < num_vertices; j++)
1774 if (g->vertices[j].component == i)
1775 vertices[num_vertices_in_component++] = j;
1777 /* Now test if the vertices in 'vertices' form a clique, by testing
1778 for edges among each pair. */
1779 this_component_is_clique = 1;
1780 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1782 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1784 /* Check if the two vertices are connected by iterating
1785 through all the edges which have one of these are source. */
1786 e = g->vertices[vertices[v_indx2]].pred;
1787 while (e)
1789 if (e->src == vertices[v_indx1])
1790 break;
1791 e = e->pred_next;
1793 if (!e)
1795 this_component_is_clique = 0;
1796 break;
1799 if (!this_component_is_clique)
1800 all_components_are_cliques = 0;
1804 free (all_vertices);
1805 free (vertices);
1806 free_graph (g);
1807 return all_components_are_cliques;
1810 /* Group each data reference in DRS with its base object set num. */
1812 static void
1813 build_base_obj_set_for_drs (vec<data_reference_p> drs)
1815 int num_vertex = drs.length ();
1816 struct graph *g = new_graph (num_vertex);
1817 data_reference_p dr1, dr2;
1818 int i, j;
1819 int *queue;
1821 FOR_EACH_VEC_ELT (drs, i, dr1)
1822 for (j = i + 1; drs.iterate (j, &dr2); j++)
1823 if (dr_same_base_object_p (dr1, dr2))
1825 add_edge (g, i, j);
1826 add_edge (g, j, i);
1829 queue = XNEWVEC (int, num_vertex);
1830 for (i = 0; i < num_vertex; i++)
1831 queue[i] = i;
1833 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1835 for (i = 0; i < g->n_vertices; i++)
1837 data_reference_p dr = drs[i];
1838 base_alias_pair *bap;
1840 gcc_assert (dr->aux);
1841 bap = (base_alias_pair *)(dr->aux);
1843 bap->base_obj_set = g->vertices[i].component + 1;
1846 free (queue);
1847 free_graph (g);
1850 /* Build the data references for PBB. */
1852 static void
1853 build_pbb_drs (poly_bb_p pbb)
1855 int j;
1856 data_reference_p dr;
1857 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1859 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
1860 build_poly_dr (dr, pbb);
1863 /* Dump to file the alias graphs for the data references in DRS. */
1865 static void
1866 dump_alias_graphs (vec<data_reference_p> drs)
1868 char comment[100];
1869 FILE *file_dimacs, *file_ecc, *file_dot;
1871 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1872 if (file_dimacs)
1874 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1875 current_function_name ());
1876 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1877 fclose (file_dimacs);
1880 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1881 if (file_ecc)
1883 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1884 current_function_name ());
1885 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1886 fclose (file_ecc);
1889 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1890 if (file_dot)
1892 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1893 current_function_name ());
1894 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1895 fclose (file_dot);
1899 /* Build data references in SCOP. */
1901 static void
1902 build_scop_drs (scop_p scop)
1904 int i, j;
1905 poly_bb_p pbb;
1906 data_reference_p dr;
1907 auto_vec<data_reference_p, 3> drs;
1909 /* Remove all the PBBs that do not have data references: these basic
1910 blocks are not handled in the polyhedral representation. */
1911 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1912 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1914 free_gimple_bb (PBB_BLACK_BOX (pbb));
1915 free_poly_bb (pbb);
1916 SCOP_BBS (scop).ordered_remove (i);
1917 i--;
1920 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1921 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1922 drs.safe_push (dr);
1924 FOR_EACH_VEC_ELT (drs, i, dr)
1925 dr->aux = XNEW (base_alias_pair);
1927 if (!build_alias_set_optimal_p (drs))
1929 /* TODO: Add support when building alias set is not optimal. */
1933 build_base_obj_set_for_drs (drs);
1935 /* When debugging, enable the following code. This cannot be used
1936 in production compilers. */
1937 if (0)
1938 dump_alias_graphs (drs);
1940 drs.release ();
1942 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1943 build_pbb_drs (pbb);
1946 /* Return a gsi at the position of the phi node STMT. */
1948 static gphi_iterator
1949 gsi_for_phi_node (gphi *stmt)
1951 gphi_iterator psi;
1952 basic_block bb = gimple_bb (stmt);
1954 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1955 if (stmt == psi.phi ())
1956 return psi;
1958 gcc_unreachable ();
1959 return psi;
1962 /* Analyze all the data references of STMTS and add them to the
1963 GBB_DATA_REFS vector of BB. */
1965 static void
1966 analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1968 loop_p nest;
1969 gimple_bb_p gbb;
1970 gimple stmt;
1971 int i;
1972 sese region = SCOP_REGION (scop);
1974 if (!bb_in_sese_p (bb, region))
1975 return;
1977 nest = outermost_loop_in_sese_1 (region, bb);
1978 gbb = gbb_from_bb (bb);
1980 FOR_EACH_VEC_ELT (stmts, i, stmt)
1982 loop_p loop;
1984 if (is_gimple_debug (stmt))
1985 continue;
1987 loop = loop_containing_stmt (stmt);
1988 if (!loop_in_sese_p (loop, region))
1989 loop = nest;
1991 graphite_find_data_references_in_stmt (nest, loop, stmt,
1992 &GBB_DATA_REFS (gbb));
1996 /* Insert STMT at the end of the STMTS sequence and then insert the
1997 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1998 on STMTS. */
2000 static void
2001 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2002 gimple_stmt_iterator insert_gsi)
2004 gimple_stmt_iterator gsi;
2005 auto_vec<gimple, 3> x;
2007 gimple_seq_add_stmt (&stmts, stmt);
2008 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2009 x.safe_push (gsi_stmt (gsi));
2011 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2012 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2015 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2017 static void
2018 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2020 gimple_seq stmts;
2021 gimple_stmt_iterator gsi;
2022 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2023 gassign *stmt = gimple_build_assign (unshare_expr (res), var);
2024 auto_vec<gimple, 3> x;
2026 gimple_seq_add_stmt (&stmts, stmt);
2027 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2028 x.safe_push (gsi_stmt (gsi));
2030 if (gimple_code (after_stmt) == GIMPLE_PHI)
2032 gsi = gsi_after_labels (gimple_bb (after_stmt));
2033 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2035 else
2037 gsi = gsi_for_stmt (after_stmt);
2038 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2041 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
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);
2062 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
2063 isl_id_for_pbb (scop, pbb1));
2065 GBB_PBB (gbb1) = pbb1;
2066 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2067 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2068 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
2071 /* Insert on edge E the assignment "RES := EXPR". */
2073 static void
2074 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2076 gimple_stmt_iterator gsi;
2077 gimple_seq stmts = NULL;
2078 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2079 gimple stmt = gimple_build_assign (unshare_expr (res), var);
2080 basic_block bb;
2081 auto_vec<gimple, 3> x;
2083 gimple_seq_add_stmt (&stmts, stmt);
2084 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2085 x.safe_push (gsi_stmt (gsi));
2087 gsi_insert_seq_on_edge (e, stmts);
2088 gsi_commit_edge_inserts ();
2089 bb = gimple_bb (stmt);
2091 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2092 return;
2094 if (!gbb_from_bb (bb))
2095 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2097 analyze_drs_in_stmts (scop, bb, x);
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 return;
2205 /* If res is scev analyzable and is not a scalar value, it is safe
2206 to ignore the close phi node: it will be code generated in the
2207 out of Graphite pass. */
2208 else if (scev_analyzable_p (res, region))
2210 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2211 tree scev;
2213 if (!loop_in_sese_p (loop, region))
2215 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2216 scev = scalar_evolution_in_region (region, loop, arg);
2217 scev = compute_overall_effect_of_inner_loop (loop, scev);
2219 else
2220 scev = scalar_evolution_in_region (region, loop, res);
2222 if (tree_does_not_contain_chrecs (scev))
2223 propagate_expr_outside_region (res, scev, region);
2225 gsi_next (psi);
2226 return;
2228 else
2230 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
2232 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2234 if (TREE_CODE (arg) == SSA_NAME)
2235 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2236 SSA_NAME_DEF_STMT (arg));
2237 else
2238 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2239 zero_dim_array, arg);
2242 remove_phi_node (psi, false);
2243 SSA_NAME_DEF_STMT (res) = stmt;
2245 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2248 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2249 dimension array for it. */
2251 static void
2252 rewrite_phi_out_of_ssa (scop_p scop, gphi_iterator *psi)
2254 size_t i;
2255 gphi *phi = psi->phi ();
2256 basic_block bb = gimple_bb (phi);
2257 tree res = gimple_phi_result (phi);
2258 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
2259 gimple stmt;
2261 for (i = 0; i < gimple_phi_num_args (phi); i++)
2263 tree arg = gimple_phi_arg_def (phi, i);
2264 edge e = gimple_phi_arg_edge (phi, i);
2266 /* Avoid the insertion of code in the loop latch to please the
2267 pattern matching of the vectorizer. */
2268 if (TREE_CODE (arg) == SSA_NAME
2269 && !SSA_NAME_IS_DEFAULT_DEF (arg)
2270 && e->src == bb->loop_father->latch)
2271 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2272 SSA_NAME_DEF_STMT (arg));
2273 else
2274 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2277 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
2278 remove_phi_node (psi, false);
2279 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2282 /* Rewrite the degenerate phi node at position PSI from the degenerate
2283 form "x = phi (y, y, ..., y)" to "x = y". */
2285 static void
2286 rewrite_degenerate_phi (gphi_iterator *psi)
2288 tree rhs;
2289 gimple stmt;
2290 gimple_stmt_iterator gsi;
2291 gphi *phi = psi->phi ();
2292 tree res = gimple_phi_result (phi);
2293 basic_block bb;
2295 bb = gimple_bb (phi);
2296 rhs = degenerate_phi_result (phi);
2297 gcc_assert (rhs);
2299 stmt = gimple_build_assign (res, rhs);
2300 remove_phi_node (psi, false);
2302 gsi = gsi_after_labels (bb);
2303 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2306 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2308 static void
2309 rewrite_reductions_out_of_ssa (scop_p scop)
2311 basic_block bb;
2312 gphi_iterator psi;
2313 sese region = SCOP_REGION (scop);
2315 FOR_EACH_BB_FN (bb, cfun)
2316 if (bb_in_sese_p (bb, region))
2317 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2319 gphi *phi = psi.phi ();
2321 if (virtual_operand_p (gimple_phi_result (phi)))
2323 gsi_next (&psi);
2324 continue;
2327 if (gimple_phi_num_args (phi) > 1
2328 && degenerate_phi_result (phi))
2329 rewrite_degenerate_phi (&psi);
2331 else if (scalar_close_phi_node_p (phi))
2332 rewrite_close_phi_out_of_ssa (scop, &psi);
2334 else if (reduction_phi_p (region, &psi))
2335 rewrite_phi_out_of_ssa (scop, &psi);
2338 update_ssa (TODO_update_ssa);
2339 #ifdef ENABLE_CHECKING
2340 verify_loop_closed_ssa (true);
2341 #endif
2344 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2345 read from ZERO_DIM_ARRAY. */
2347 static void
2348 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2349 tree def, gimple use_stmt)
2351 gimple name_stmt;
2352 tree name;
2353 ssa_op_iter iter;
2354 use_operand_p use_p;
2356 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2358 name = copy_ssa_name (def);
2359 name_stmt = gimple_build_assign (name, zero_dim_array);
2361 gimple_assign_set_lhs (name_stmt, name);
2362 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2364 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2365 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2366 replace_exp (use_p, name);
2368 update_stmt (use_stmt);
2371 /* For every definition DEF in the SCOP that is used outside the scop,
2372 insert a closing-scop definition in the basic block just after this
2373 SCOP. */
2375 static void
2376 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2378 tree var = create_tmp_reg (TREE_TYPE (def));
2379 tree new_name = make_ssa_name (var, stmt);
2380 bool needs_copy = false;
2381 use_operand_p use_p;
2382 imm_use_iterator imm_iter;
2383 gimple use_stmt;
2384 sese region = SCOP_REGION (scop);
2386 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2388 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2390 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2392 SET_USE (use_p, new_name);
2394 update_stmt (use_stmt);
2395 needs_copy = true;
2399 /* Insert in the empty BB just after the scop a use of DEF such
2400 that the rewrite of cross_bb_scalar_dependences won't insert
2401 arrays everywhere else. */
2402 if (needs_copy)
2404 gimple assign = gimple_build_assign (new_name, def);
2405 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2407 update_stmt (assign);
2408 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2412 /* Rewrite the scalar dependences crossing the boundary of the BB
2413 containing STMT with an array. Return true when something has been
2414 changed. */
2416 static bool
2417 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2419 sese region = SCOP_REGION (scop);
2420 gimple stmt = gsi_stmt (*gsi);
2421 imm_use_iterator imm_iter;
2422 tree def;
2423 basic_block def_bb;
2424 tree zero_dim_array = NULL_TREE;
2425 gimple use_stmt;
2426 bool res = false;
2428 switch (gimple_code (stmt))
2430 case GIMPLE_ASSIGN:
2431 def = gimple_assign_lhs (stmt);
2432 break;
2434 case GIMPLE_CALL:
2435 def = gimple_call_lhs (stmt);
2436 break;
2438 default:
2439 return false;
2442 if (!def
2443 || !is_gimple_reg (def))
2444 return false;
2446 if (scev_analyzable_p (def, region))
2448 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2449 tree scev = scalar_evolution_in_region (region, loop, def);
2451 if (tree_contains_chrecs (scev, NULL))
2452 return false;
2454 propagate_expr_outside_region (def, scev, region);
2455 return true;
2458 def_bb = gimple_bb (stmt);
2460 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2462 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2463 if (gimple_code (use_stmt) == GIMPLE_PHI
2464 && (res = true))
2466 gphi_iterator psi = gsi_start_phis (gimple_bb (use_stmt));
2468 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2469 rewrite_close_phi_out_of_ssa (scop, &psi);
2470 else
2471 rewrite_phi_out_of_ssa (scop, &psi);
2474 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2475 if (gimple_code (use_stmt) != GIMPLE_PHI
2476 && def_bb != gimple_bb (use_stmt)
2477 && !is_gimple_debug (use_stmt)
2478 && (res = true))
2480 if (!zero_dim_array)
2482 zero_dim_array = create_zero_dim_array
2483 (def, "Cross_BB_scalar_dependence");
2484 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2485 SSA_NAME_DEF_STMT (def));
2486 gsi_next (gsi);
2489 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
2490 def, use_stmt);
2493 return res;
2496 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2498 static void
2499 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2501 basic_block bb;
2502 gimple_stmt_iterator psi;
2503 sese region = SCOP_REGION (scop);
2504 bool changed = false;
2506 /* Create an extra empty BB after the scop. */
2507 split_edge (SESE_EXIT (region));
2509 FOR_EACH_BB_FN (bb, cfun)
2510 if (bb_in_sese_p (bb, region))
2511 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2512 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2514 if (changed)
2516 scev_reset_htab ();
2517 update_ssa (TODO_update_ssa);
2518 #ifdef ENABLE_CHECKING
2519 verify_loop_closed_ssa (true);
2520 #endif
2524 /* Returns the number of pbbs that are in loops contained in SCOP. */
2526 static int
2527 nb_pbbs_in_loops (scop_p scop)
2529 int i;
2530 poly_bb_p pbb;
2531 int res = 0;
2533 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
2534 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2535 res++;
2537 return res;
2540 /* Return the number of data references in BB that write in
2541 memory. */
2543 static int
2544 nb_data_writes_in_bb (basic_block bb)
2546 int res = 0;
2547 gimple_stmt_iterator gsi;
2549 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2550 if (gimple_vdef (gsi_stmt (gsi)))
2551 res++;
2553 return res;
2556 /* Splits at STMT the basic block BB represented as PBB in the
2557 polyhedral form. */
2559 static edge
2560 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2562 edge e1 = split_block (bb, stmt);
2563 new_pbb_from_pbb (scop, pbb, e1->dest);
2564 return e1;
2567 /* Splits STMT out of its current BB. This is done for reduction
2568 statements for which we want to ignore data dependences. */
2570 static basic_block
2571 split_reduction_stmt (scop_p scop, gimple stmt)
2573 basic_block bb = gimple_bb (stmt);
2574 poly_bb_p pbb = pbb_from_bb (bb);
2575 gimple_bb_p gbb = gbb_from_bb (bb);
2576 edge e1;
2577 int i;
2578 data_reference_p dr;
2580 /* Do not split basic blocks with no writes to memory: the reduction
2581 will be the only write to memory. */
2582 if (nb_data_writes_in_bb (bb) == 0
2583 /* Or if we have already marked BB as a reduction. */
2584 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
2585 return bb;
2587 e1 = split_pbb (scop, pbb, bb, stmt);
2589 /* Split once more only when the reduction stmt is not the only one
2590 left in the original BB. */
2591 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2593 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2594 gsi_prev (&gsi);
2595 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2598 /* A part of the data references will end in a different basic block
2599 after the split: move the DRs from the original GBB to the newly
2600 created GBB1. */
2601 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
2603 basic_block bb1 = gimple_bb (DR_STMT (dr));
2605 if (bb1 != bb)
2607 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2608 GBB_DATA_REFS (gbb1).safe_push (dr);
2609 GBB_DATA_REFS (gbb).ordered_remove (i);
2610 i--;
2614 return e1->dest;
2617 /* Return true when stmt is a reduction operation. */
2619 static inline bool
2620 is_reduction_operation_p (gimple stmt)
2622 enum tree_code code;
2624 gcc_assert (is_gimple_assign (stmt));
2625 code = gimple_assign_rhs_code (stmt);
2627 return flag_associative_math
2628 && commutative_tree_code (code)
2629 && associative_tree_code (code);
2632 /* Returns true when PHI contains an argument ARG. */
2634 static bool
2635 phi_contains_arg (gphi *phi, tree arg)
2637 size_t i;
2639 for (i = 0; i < gimple_phi_num_args (phi); i++)
2640 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2641 return true;
2643 return false;
2646 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2648 static gphi *
2649 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2651 gimple stmt;
2653 if (TREE_CODE (arg) != SSA_NAME)
2654 return NULL;
2656 stmt = SSA_NAME_DEF_STMT (arg);
2658 if (gimple_code (stmt) == GIMPLE_NOP
2659 || gimple_code (stmt) == GIMPLE_CALL)
2660 return NULL;
2662 if (gphi *phi = dyn_cast <gphi *> (stmt))
2664 if (phi_contains_arg (phi, lhs))
2665 return phi;
2666 return NULL;
2669 if (!is_gimple_assign (stmt))
2670 return NULL;
2672 if (gimple_num_ops (stmt) == 2)
2673 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2675 if (is_reduction_operation_p (stmt))
2677 gphi *res
2678 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2680 return res ? res :
2681 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2684 return NULL;
2687 /* Detect commutative and associative scalar reductions starting at
2688 the STMT. Return the phi node of the reduction cycle, or NULL. */
2690 static gphi *
2691 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2692 vec<gimple> *in,
2693 vec<gimple> *out)
2695 gphi *phi = follow_ssa_with_commutative_ops (arg, lhs);
2697 if (!phi)
2698 return NULL;
2700 in->safe_push (stmt);
2701 out->safe_push (stmt);
2702 return phi;
2705 /* Detect commutative and associative scalar reductions starting at
2706 STMT. Return the phi node of the reduction cycle, or NULL. */
2708 static gphi *
2709 detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2710 vec<gimple> *out)
2712 tree lhs = gimple_assign_lhs (stmt);
2714 if (gimple_num_ops (stmt) == 2)
2715 return detect_commutative_reduction_arg (lhs, stmt,
2716 gimple_assign_rhs1 (stmt),
2717 in, out);
2719 if (is_reduction_operation_p (stmt))
2721 gphi *res = detect_commutative_reduction_arg (lhs, stmt,
2722 gimple_assign_rhs1 (stmt),
2723 in, out);
2724 return res ? res
2725 : detect_commutative_reduction_arg (lhs, stmt,
2726 gimple_assign_rhs2 (stmt),
2727 in, out);
2730 return NULL;
2733 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2735 static gphi *
2736 follow_inital_value_to_phi (tree arg, tree lhs)
2738 gimple stmt;
2740 if (!arg || TREE_CODE (arg) != SSA_NAME)
2741 return NULL;
2743 stmt = SSA_NAME_DEF_STMT (arg);
2745 if (gphi *phi = dyn_cast <gphi *> (stmt))
2746 if (phi_contains_arg (phi, lhs))
2747 return phi;
2749 return NULL;
2753 /* Return the argument of the loop PHI that is the initial value coming
2754 from outside the loop. */
2756 static edge
2757 edge_initial_value_for_loop_phi (gphi *phi)
2759 size_t i;
2761 for (i = 0; i < gimple_phi_num_args (phi); i++)
2763 edge e = gimple_phi_arg_edge (phi, i);
2765 if (loop_depth (e->src->loop_father)
2766 < loop_depth (e->dest->loop_father))
2767 return e;
2770 return NULL;
2773 /* Return the argument of the loop PHI that is the initial value coming
2774 from outside the loop. */
2776 static tree
2777 initial_value_for_loop_phi (gphi *phi)
2779 size_t i;
2781 for (i = 0; i < gimple_phi_num_args (phi); i++)
2783 edge e = gimple_phi_arg_edge (phi, i);
2785 if (loop_depth (e->src->loop_father)
2786 < loop_depth (e->dest->loop_father))
2787 return gimple_phi_arg_def (phi, i);
2790 return NULL_TREE;
2793 /* Returns true when DEF is used outside the reduction cycle of
2794 LOOP_PHI. */
2796 static bool
2797 used_outside_reduction (tree def, gimple loop_phi)
2799 use_operand_p use_p;
2800 imm_use_iterator imm_iter;
2801 loop_p loop = loop_containing_stmt (loop_phi);
2803 /* In LOOP, DEF should be used only in LOOP_PHI. */
2804 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2806 gimple stmt = USE_STMT (use_p);
2808 if (stmt != loop_phi
2809 && !is_gimple_debug (stmt)
2810 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2811 return true;
2814 return false;
2817 /* Detect commutative and associative scalar reductions belonging to
2818 the SCOP starting at the loop closed phi node STMT. Return the phi
2819 node of the reduction cycle, or NULL. */
2821 static gphi *
2822 detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2823 vec<gimple> *out)
2825 if (scalar_close_phi_node_p (stmt))
2827 gimple def;
2828 gphi *loop_phi, *phi, *close_phi = as_a <gphi *> (stmt);
2829 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
2831 if (TREE_CODE (arg) != SSA_NAME)
2832 return NULL;
2834 /* Note that loop close phi nodes should have a single argument
2835 because we translated the representation into a canonical form
2836 before Graphite: see canonicalize_loop_closed_ssa_form. */
2837 gcc_assert (gimple_phi_num_args (close_phi) == 1);
2839 def = SSA_NAME_DEF_STMT (arg);
2840 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2841 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
2842 return NULL;
2844 lhs = gimple_phi_result (close_phi);
2845 init = initial_value_for_loop_phi (loop_phi);
2846 phi = follow_inital_value_to_phi (init, lhs);
2848 if (phi && (used_outside_reduction (lhs, phi)
2849 || !has_single_use (gimple_phi_result (phi))))
2850 return NULL;
2852 in->safe_push (loop_phi);
2853 out->safe_push (close_phi);
2854 return phi;
2857 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2858 return detect_commutative_reduction_assign (stmt, in, out);
2860 return NULL;
2863 /* Translate the scalar reduction statement STMT to an array RED
2864 knowing that its recursive phi node is LOOP_PHI. */
2866 static void
2867 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2868 gimple stmt, gphi *loop_phi)
2870 tree res = gimple_phi_result (loop_phi);
2871 gassign *assign = gimple_build_assign (res, unshare_expr (red));
2872 gimple_stmt_iterator gsi;
2874 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2876 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
2877 gsi = gsi_for_stmt (stmt);
2878 gsi_next (&gsi);
2879 insert_stmts (scop, assign, NULL, gsi);
2882 /* Removes the PHI node and resets all the debug stmts that are using
2883 the PHI_RESULT. */
2885 static void
2886 remove_phi (gphi *phi)
2888 imm_use_iterator imm_iter;
2889 tree def;
2890 use_operand_p use_p;
2891 gimple_stmt_iterator gsi;
2892 auto_vec<gimple, 3> update;
2893 unsigned int i;
2894 gimple stmt;
2896 def = PHI_RESULT (phi);
2897 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2899 stmt = USE_STMT (use_p);
2901 if (is_gimple_debug (stmt))
2903 gimple_debug_bind_reset_value (stmt);
2904 update.safe_push (stmt);
2908 FOR_EACH_VEC_ELT (update, i, stmt)
2909 update_stmt (stmt);
2911 gsi = gsi_for_phi_node (phi);
2912 remove_phi_node (&gsi, false);
2915 /* Helper function for for_each_index. For each INDEX of the data
2916 reference REF, returns true when its indices are valid in the loop
2917 nest LOOP passed in as DATA. */
2919 static bool
2920 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2922 loop_p loop;
2923 basic_block header, def_bb;
2924 gimple stmt;
2926 if (TREE_CODE (*index) != SSA_NAME)
2927 return true;
2929 loop = *((loop_p *) data);
2930 header = loop->header;
2931 stmt = SSA_NAME_DEF_STMT (*index);
2933 if (!stmt)
2934 return true;
2936 def_bb = gimple_bb (stmt);
2938 if (!def_bb)
2939 return true;
2941 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2944 /* When the result of a CLOSE_PHI is written to a memory location,
2945 return a pointer to that memory reference, otherwise return
2946 NULL_TREE. */
2948 static tree
2949 close_phi_written_to_memory (gphi *close_phi)
2951 imm_use_iterator imm_iter;
2952 use_operand_p use_p;
2953 gimple stmt;
2954 tree res, def = gimple_phi_result (close_phi);
2956 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2957 if ((stmt = USE_STMT (use_p))
2958 && gimple_code (stmt) == GIMPLE_ASSIGN
2959 && (res = gimple_assign_lhs (stmt)))
2961 switch (TREE_CODE (res))
2963 case VAR_DECL:
2964 case PARM_DECL:
2965 case RESULT_DECL:
2966 return res;
2968 case ARRAY_REF:
2969 case MEM_REF:
2971 tree arg = gimple_phi_arg_def (close_phi, 0);
2972 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2974 /* FIXME: this restriction is for id-{24,25}.f and
2975 could be handled by duplicating the computation of
2976 array indices before the loop of the close_phi. */
2977 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2978 return res;
2980 /* Fallthru. */
2982 default:
2983 continue;
2986 return NULL_TREE;
2989 /* Rewrite out of SSA the reduction described by the loop phi nodes
2990 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2991 levels like this:
2993 IN: stmt, loop_n, ..., loop_0
2994 OUT: stmt, close_n, ..., close_0
2996 the first element is the reduction statement, and the next elements
2997 are the loop and close phi nodes of each of the outer loops. */
2999 static void
3000 translate_scalar_reduction_to_array (scop_p scop,
3001 vec<gimple> in,
3002 vec<gimple> out)
3004 gimple loop_stmt;
3005 unsigned int i = out.length () - 1;
3006 tree red = close_phi_written_to_memory (as_a <gphi *> (out[i]));
3008 FOR_EACH_VEC_ELT (in, i, loop_stmt)
3010 gimple close_stmt = out[i];
3012 if (i == 0)
3014 basic_block bb = split_reduction_stmt (scop, loop_stmt);
3015 poly_bb_p pbb = pbb_from_bb (bb);
3016 PBB_IS_REDUCTION (pbb) = true;
3017 gcc_assert (close_stmt == loop_stmt);
3019 if (!red)
3020 red = create_zero_dim_array
3021 (gimple_assign_lhs (loop_stmt), "Commutative_Associative_Reduction");
3023 translate_scalar_reduction_to_array_for_stmt (scop, red, loop_stmt,
3024 as_a <gphi *> (in[1]));
3025 continue;
3028 gphi *loop_phi = as_a <gphi *> (loop_stmt);
3029 gphi *close_phi = as_a <gphi *> (close_stmt);
3031 if (i == in.length () - 1)
3033 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3034 unshare_expr (red), close_phi);
3035 insert_out_of_ssa_copy_on_edge
3036 (scop, edge_initial_value_for_loop_phi (loop_phi),
3037 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
3040 remove_phi (loop_phi);
3041 remove_phi (close_phi);
3045 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3046 true when something has been changed. */
3048 static bool
3049 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3050 gphi *close_phi)
3052 bool res;
3053 auto_vec<gimple, 10> in;
3054 auto_vec<gimple, 10> out;
3056 detect_commutative_reduction (scop, close_phi, &in, &out);
3057 res = in.length () > 1;
3058 if (res)
3059 translate_scalar_reduction_to_array (scop, in, out);
3061 return res;
3064 /* Rewrites all the commutative reductions from LOOP out of SSA.
3065 Returns true when something has been changed. */
3067 static bool
3068 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3069 loop_p loop)
3071 gphi_iterator gsi;
3072 edge exit = single_exit (loop);
3073 tree res;
3074 bool changed = false;
3076 if (!exit)
3077 return false;
3079 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3080 if ((res = gimple_phi_result (gsi.phi ()))
3081 && !virtual_operand_p (res)
3082 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3083 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3084 (scop, gsi.phi ());
3086 return changed;
3089 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3091 static void
3092 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3094 loop_p loop;
3095 bool changed = false;
3096 sese region = SCOP_REGION (scop);
3098 FOR_EACH_LOOP (loop, 0)
3099 if (loop_in_sese_p (loop, region))
3100 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3102 if (changed)
3104 scev_reset_htab ();
3105 gsi_commit_edge_inserts ();
3106 update_ssa (TODO_update_ssa);
3107 #ifdef ENABLE_CHECKING
3108 verify_loop_closed_ssa (true);
3109 #endif
3113 /* Can all ivs be represented by a signed integer?
3114 As CLooG might generate negative values in its expressions, signed loop ivs
3115 are required in the backend. */
3117 static bool
3118 scop_ivs_can_be_represented (scop_p scop)
3120 loop_p loop;
3121 gphi_iterator psi;
3122 bool result = true;
3124 FOR_EACH_LOOP (loop, 0)
3126 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3127 continue;
3129 for (psi = gsi_start_phis (loop->header);
3130 !gsi_end_p (psi); gsi_next (&psi))
3132 gphi *phi = psi.phi ();
3133 tree res = PHI_RESULT (phi);
3134 tree type = TREE_TYPE (res);
3136 if (TYPE_UNSIGNED (type)
3137 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
3139 result = false;
3140 break;
3143 if (!result)
3144 break;
3147 return result;
3150 /* Builds the polyhedral representation for a SESE region. */
3152 void
3153 build_poly_scop (scop_p scop)
3155 sese region = SCOP_REGION (scop);
3156 graphite_dim_t max_dim;
3158 build_scop_bbs (scop);
3160 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3161 Once CLooG is fixed, remove this guard. Anyways, it makes no
3162 sense to optimize a scop containing only PBBs that do not belong
3163 to any loops. */
3164 if (nb_pbbs_in_loops (scop) == 0)
3165 return;
3167 if (!scop_ivs_can_be_represented (scop))
3168 return;
3170 if (flag_associative_math)
3171 rewrite_commutative_reductions_out_of_ssa (scop);
3173 build_sese_loop_nests (region);
3174 /* Record all conditions in REGION. */
3175 sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
3176 find_scop_parameters (scop);
3178 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3179 if (scop_nb_params (scop) > max_dim)
3180 return;
3182 build_scop_iteration_domain (scop);
3183 build_scop_context (scop);
3184 add_conditions_to_constraints (scop);
3186 /* Rewrite out of SSA only after having translated the
3187 representation to the polyhedral representation to avoid scev
3188 analysis failures. That means that these functions will insert
3189 new data references that they create in the right place. */
3190 rewrite_reductions_out_of_ssa (scop);
3191 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3193 build_scop_drs (scop);
3194 scop_to_lst (scop);
3195 build_scop_scattering (scop);
3197 /* This SCoP has been translated to the polyhedral
3198 representation. */
3199 POLY_SCOP_P (scop) = true;
3201 #endif