Fix PR47021: ADDR_EXPRs don't contain SCoP parameters.
[official-gcc/graphite-test-results.git] / gcc / graphite-sese-to-poly.c
blob078749c43208aded3ee2f3c300a93f022089a55c
1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009, 2010 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"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "basic-block.h"
29 #include "diagnostic.h"
30 #include "tree-flow.h"
31 #include "tree-dump.h"
32 #include "timevar.h"
33 #include "cfgloop.h"
34 #include "tree-chrec.h"
35 #include "tree-data-ref.h"
36 #include "tree-scalar-evolution.h"
37 #include "tree-pass.h"
38 #include "domwalk.h"
39 #include "value-prof.h"
40 #include "pointer-set.h"
41 #include "gimple.h"
42 #include "sese.h"
44 #ifdef HAVE_cloog
45 #include "ppl_c.h"
46 #include "graphite-ppl.h"
47 #include "graphite.h"
48 #include "graphite-poly.h"
49 #include "graphite-scop-detection.h"
50 #include "graphite-sese-to-poly.h"
52 /* Returns the index of the PHI argument defined in the outermost
53 loop. */
55 static size_t
56 phi_arg_in_outermost_loop (gimple phi)
58 loop_p loop = gimple_bb (phi)->loop_father;
59 size_t i, res = 0;
61 for (i = 0; i < gimple_phi_num_args (phi); i++)
62 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
64 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
65 res = i;
68 return res;
71 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
72 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
74 static void
75 remove_simple_copy_phi (gimple_stmt_iterator *psi)
77 gimple phi = gsi_stmt (*psi);
78 tree res = gimple_phi_result (phi);
79 size_t entry = phi_arg_in_outermost_loop (phi);
80 tree init = gimple_phi_arg_def (phi, entry);
81 gimple stmt = gimple_build_assign (res, init);
82 edge e = gimple_phi_arg_edge (phi, entry);
84 remove_phi_node (psi, false);
85 gsi_insert_on_edge_immediate (e, stmt);
86 SSA_NAME_DEF_STMT (res) = stmt;
89 /* Removes an invariant phi node at position PSI by inserting on the
90 loop ENTRY edge the assignment RES = INIT. */
92 static void
93 remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
95 gimple phi = gsi_stmt (*psi);
96 loop_p loop = loop_containing_stmt (phi);
97 tree res = gimple_phi_result (phi);
98 tree scev = scalar_evolution_in_region (region, loop, res);
99 size_t entry = phi_arg_in_outermost_loop (phi);
100 edge e = gimple_phi_arg_edge (phi, entry);
101 tree var;
102 gimple stmt;
103 gimple_seq stmts;
104 gimple_stmt_iterator gsi;
106 if (tree_contains_chrecs (scev, NULL))
107 scev = gimple_phi_arg_def (phi, entry);
109 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
110 stmt = gimple_build_assign (res, var);
111 remove_phi_node (psi, false);
113 if (!stmts)
114 stmts = gimple_seq_alloc ();
116 gsi = gsi_last (stmts);
117 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
118 gsi_insert_seq_on_edge (e, stmts);
119 gsi_commit_edge_inserts ();
120 SSA_NAME_DEF_STMT (res) = stmt;
123 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
125 static inline bool
126 simple_copy_phi_p (gimple phi)
128 tree res;
130 if (gimple_phi_num_args (phi) != 2)
131 return false;
133 res = gimple_phi_result (phi);
134 return (res == gimple_phi_arg_def (phi, 0)
135 || res == gimple_phi_arg_def (phi, 1));
138 /* Returns true when the phi node at position PSI is a reduction phi
139 node in REGION. Otherwise moves the pointer PSI to the next phi to
140 be considered. */
142 static bool
143 reduction_phi_p (sese region, gimple_stmt_iterator *psi)
145 loop_p loop;
146 gimple phi = gsi_stmt (*psi);
147 tree res = gimple_phi_result (phi);
149 loop = loop_containing_stmt (phi);
151 if (simple_copy_phi_p (phi))
153 /* PRE introduces phi nodes like these, for an example,
154 see id-5.f in the fortran graphite testsuite:
156 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
158 remove_simple_copy_phi (psi);
159 return false;
162 if (scev_analyzable_p (res, region))
164 tree scev = scalar_evolution_in_region (region, loop, res);
166 if (evolution_function_is_invariant_p (scev, loop->num))
167 remove_invariant_phi (region, psi);
168 else
169 gsi_next (psi);
171 return false;
174 /* All the other cases are considered reductions. */
175 return true;
178 /* Store the GRAPHITE representation of BB. */
180 static gimple_bb_p
181 new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
183 struct gimple_bb *gbb;
185 gbb = XNEW (struct gimple_bb);
186 bb->aux = gbb;
187 GBB_BB (gbb) = bb;
188 GBB_DATA_REFS (gbb) = drs;
189 GBB_CONDITIONS (gbb) = NULL;
190 GBB_CONDITION_CASES (gbb) = NULL;
192 return gbb;
195 static void
196 free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
198 unsigned int i;
199 struct data_reference *dr;
201 FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
202 if (dr->aux)
204 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
206 if (bap->alias_set)
207 free (bap->alias_set);
209 free (bap);
210 dr->aux = NULL;
213 /* Frees GBB. */
215 static void
216 free_gimple_bb (struct gimple_bb *gbb)
218 free_data_refs_aux (GBB_DATA_REFS (gbb));
219 free_data_refs (GBB_DATA_REFS (gbb));
221 VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
222 VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
223 GBB_BB (gbb)->aux = 0;
224 XDELETE (gbb);
227 /* Deletes all gimple bbs in SCOP. */
229 static void
230 remove_gbbs_in_scop (scop_p scop)
232 int i;
233 poly_bb_p pbb;
235 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
236 free_gimple_bb (PBB_BLACK_BOX (pbb));
239 /* Deletes all scops in SCOPS. */
241 void
242 free_scops (VEC (scop_p, heap) *scops)
244 int i;
245 scop_p scop;
247 FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
249 remove_gbbs_in_scop (scop);
250 free_sese (SCOP_REGION (scop));
251 free_scop (scop);
254 VEC_free (scop_p, heap, scops);
257 /* Generates a polyhedral black box only if the bb contains interesting
258 information. */
260 static gimple_bb_p
261 try_generate_gimple_bb (scop_p scop, basic_block bb)
263 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
264 loop_p nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
265 gimple_stmt_iterator gsi;
267 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
269 gimple stmt = gsi_stmt (gsi);
270 if (!is_gimple_debug (stmt))
271 graphite_find_data_references_in_stmt (nest, stmt, &drs);
274 return new_gimple_bb (bb, drs);
277 /* Returns true if all predecessors of BB, that are not dominated by BB, are
278 marked in MAP. The predecessors dominated by BB are loop latches and will
279 be handled after BB. */
281 static bool
282 all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
284 edge e;
285 edge_iterator ei;
287 FOR_EACH_EDGE (e, ei, bb->preds)
288 if (!TEST_BIT (map, e->src->index)
289 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
290 return false;
292 return true;
295 /* Compare the depth of two basic_block's P1 and P2. */
297 static int
298 compare_bb_depths (const void *p1, const void *p2)
300 const_basic_block const bb1 = *(const_basic_block const*)p1;
301 const_basic_block const bb2 = *(const_basic_block const*)p2;
302 int d1 = loop_depth (bb1->loop_father);
303 int d2 = loop_depth (bb2->loop_father);
305 if (d1 < d2)
306 return 1;
308 if (d1 > d2)
309 return -1;
311 return 0;
314 /* Sort the basic blocks from DOM such that the first are the ones at
315 a deepest loop level. */
317 static void
318 graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
320 VEC_qsort (basic_block, dom, compare_bb_depths);
323 /* Recursive helper function for build_scops_bbs. */
325 static void
326 build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
328 sese region = SCOP_REGION (scop);
329 VEC (basic_block, heap) *dom;
330 poly_bb_p pbb;
332 if (TEST_BIT (visited, bb->index)
333 || !bb_in_sese_p (bb, region))
334 return;
336 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
337 VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
338 SET_BIT (visited, bb->index);
340 dom = get_dominated_by (CDI_DOMINATORS, bb);
342 if (dom == NULL)
343 return;
345 graphite_sort_dominated_info (dom);
347 while (!VEC_empty (basic_block, dom))
349 int i;
350 basic_block dom_bb;
352 FOR_EACH_VEC_ELT (basic_block, dom, i, dom_bb)
353 if (all_non_dominated_preds_marked_p (dom_bb, visited))
355 build_scop_bbs_1 (scop, visited, dom_bb);
356 VEC_unordered_remove (basic_block, dom, i);
357 break;
361 VEC_free (basic_block, heap, dom);
364 /* Gather the basic blocks belonging to the SCOP. */
366 static void
367 build_scop_bbs (scop_p scop)
369 sbitmap visited = sbitmap_alloc (last_basic_block);
370 sese region = SCOP_REGION (scop);
372 sbitmap_zero (visited);
373 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
374 sbitmap_free (visited);
377 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
378 We generate SCATTERING_DIMENSIONS scattering dimensions.
380 CLooG 0.15.0 and previous versions require, that all
381 scattering functions of one CloogProgram have the same number of
382 scattering dimensions, therefore we allow to specify it. This
383 should be removed in future versions of CLooG.
385 The scattering polyhedron consists of these dimensions: scattering,
386 loop_iterators, parameters.
388 Example:
390 | scattering_dimensions = 5
391 | used_scattering_dimensions = 3
392 | nb_iterators = 1
393 | scop_nb_params = 2
395 | Schedule:
397 | 4 5
399 | Scattering polyhedron:
401 | scattering: {s1, s2, s3, s4, s5}
402 | loop_iterators: {i}
403 | parameters: {p1, p2}
405 | s1 s2 s3 s4 s5 i p1 p2 1
406 | 1 0 0 0 0 0 0 0 -4 = 0
407 | 0 1 0 0 0 -1 0 0 0 = 0
408 | 0 0 1 0 0 0 0 0 -5 = 0 */
410 static void
411 build_pbb_scattering_polyhedrons (ppl_Linear_Expression_t static_schedule,
412 poly_bb_p pbb, int scattering_dimensions)
414 int i;
415 scop_p scop = PBB_SCOP (pbb);
416 int nb_iterators = pbb_dim_iter_domain (pbb);
417 int used_scattering_dimensions = nb_iterators * 2 + 1;
418 int nb_params = scop_nb_params (scop);
419 ppl_Coefficient_t c;
420 ppl_dimension_type dim = scattering_dimensions + nb_iterators + nb_params;
421 mpz_t v;
423 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
425 mpz_init (v);
426 ppl_new_Coefficient (&c);
427 PBB_TRANSFORMED (pbb) = poly_scattering_new ();
428 ppl_new_C_Polyhedron_from_space_dimension
429 (&PBB_TRANSFORMED_SCATTERING (pbb), dim, 0);
431 PBB_NB_SCATTERING_TRANSFORM (pbb) = scattering_dimensions;
433 for (i = 0; i < scattering_dimensions; i++)
435 ppl_Constraint_t cstr;
436 ppl_Linear_Expression_t expr;
438 ppl_new_Linear_Expression_with_dimension (&expr, dim);
439 mpz_set_si (v, 1);
440 ppl_assign_Coefficient_from_mpz_t (c, v);
441 ppl_Linear_Expression_add_to_coefficient (expr, i, c);
443 /* Textual order inside this loop. */
444 if ((i % 2) == 0)
446 ppl_Linear_Expression_coefficient (static_schedule, i / 2, c);
447 ppl_Coefficient_to_mpz_t (c, v);
448 mpz_neg (v, v);
449 ppl_assign_Coefficient_from_mpz_t (c, v);
450 ppl_Linear_Expression_add_to_inhomogeneous (expr, c);
453 /* Iterations of this loop. */
454 else /* if ((i % 2) == 1) */
456 int loop = (i - 1) / 2;
458 mpz_set_si (v, -1);
459 ppl_assign_Coefficient_from_mpz_t (c, v);
460 ppl_Linear_Expression_add_to_coefficient
461 (expr, scattering_dimensions + loop, c);
464 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
465 ppl_Polyhedron_add_constraint (PBB_TRANSFORMED_SCATTERING (pbb), cstr);
466 ppl_delete_Linear_Expression (expr);
467 ppl_delete_Constraint (cstr);
470 mpz_clear (v);
471 ppl_delete_Coefficient (c);
473 PBB_ORIGINAL (pbb) = poly_scattering_copy (PBB_TRANSFORMED (pbb));
476 /* Build for BB the static schedule.
478 The static schedule is a Dewey numbering of the abstract syntax
479 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
481 The following example informally defines the static schedule:
484 for (i: ...)
486 for (j: ...)
492 for (k: ...)
500 Static schedules for A to F:
502 DEPTH
503 0 1 2
505 B 1 0 0
506 C 1 0 1
507 D 1 1 0
508 E 1 1 1
512 static void
513 build_scop_scattering (scop_p scop)
515 int i;
516 poly_bb_p pbb;
517 gimple_bb_p previous_gbb = NULL;
518 ppl_Linear_Expression_t static_schedule;
519 ppl_Coefficient_t c;
520 mpz_t v;
522 mpz_init (v);
523 ppl_new_Coefficient (&c);
524 ppl_new_Linear_Expression (&static_schedule);
526 /* We have to start schedules at 0 on the first component and
527 because we cannot compare_prefix_loops against a previous loop,
528 prefix will be equal to zero, and that index will be
529 incremented before copying. */
530 mpz_set_si (v, -1);
531 ppl_assign_Coefficient_from_mpz_t (c, v);
532 ppl_Linear_Expression_add_to_coefficient (static_schedule, 0, c);
534 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
536 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
537 ppl_Linear_Expression_t common;
538 int prefix;
539 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
541 if (previous_gbb)
542 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
543 else
544 prefix = 0;
546 previous_gbb = gbb;
547 ppl_new_Linear_Expression_with_dimension (&common, prefix + 1);
548 ppl_assign_Linear_Expression_from_Linear_Expression (common,
549 static_schedule);
551 mpz_set_si (v, 1);
552 ppl_assign_Coefficient_from_mpz_t (c, v);
553 ppl_Linear_Expression_add_to_coefficient (common, prefix, c);
554 ppl_assign_Linear_Expression_from_Linear_Expression (static_schedule,
555 common);
557 build_pbb_scattering_polyhedrons (common, pbb, nb_scat_dims);
559 ppl_delete_Linear_Expression (common);
562 mpz_clear (v);
563 ppl_delete_Coefficient (c);
564 ppl_delete_Linear_Expression (static_schedule);
567 /* Add the value K to the dimension D of the linear expression EXPR. */
569 static void
570 add_value_to_dim (ppl_dimension_type d, ppl_Linear_Expression_t expr,
571 mpz_t k)
573 mpz_t val;
574 ppl_Coefficient_t coef;
576 ppl_new_Coefficient (&coef);
577 ppl_Linear_Expression_coefficient (expr, d, coef);
578 mpz_init (val);
579 ppl_Coefficient_to_mpz_t (coef, val);
581 mpz_add (val, val, k);
583 ppl_assign_Coefficient_from_mpz_t (coef, val);
584 ppl_Linear_Expression_add_to_coefficient (expr, d, coef);
585 mpz_clear (val);
586 ppl_delete_Coefficient (coef);
589 /* In the context of scop S, scan E, the right hand side of a scalar
590 evolution function in loop VAR, and translate it to a linear
591 expression EXPR. */
593 static void
594 scan_tree_for_params_right_scev (sese s, tree e, int var,
595 ppl_Linear_Expression_t expr)
597 if (expr)
599 loop_p loop = get_loop (var);
600 ppl_dimension_type l = sese_loop_depth (s, loop) - 1;
601 mpz_t val;
603 /* Scalar evolutions should happen in the sese region. */
604 gcc_assert (sese_loop_depth (s, loop) > 0);
606 /* We can not deal with parametric strides like:
608 | p = parameter;
610 | for i:
611 | a [i * p] = ... */
612 gcc_assert (TREE_CODE (e) == INTEGER_CST);
614 mpz_init (val);
615 mpz_set_si (val, int_cst_value (e));
616 add_value_to_dim (l, expr, val);
617 mpz_clear (val);
621 /* Scan the integer constant CST, and add it to the inhomogeneous part of the
622 linear expression EXPR. K is the multiplier of the constant. */
624 static void
625 scan_tree_for_params_int (tree cst, ppl_Linear_Expression_t expr, mpz_t k)
627 mpz_t val;
628 ppl_Coefficient_t coef;
629 int v = int_cst_value (cst);
631 mpz_init (val);
632 mpz_set_si (val, 0);
634 /* Necessary to not get "-1 = 2^n - 1". */
635 if (v < 0)
636 mpz_sub_ui (val, val, -v);
637 else
638 mpz_add_ui (val, val, v);
640 mpz_mul (val, val, k);
641 ppl_new_Coefficient (&coef);
642 ppl_assign_Coefficient_from_mpz_t (coef, val);
643 ppl_Linear_Expression_add_to_inhomogeneous (expr, coef);
644 mpz_clear (val);
645 ppl_delete_Coefficient (coef);
648 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
649 Otherwise returns -1. */
651 static inline int
652 parameter_index_in_region_1 (tree name, sese region)
654 int i;
655 tree p;
657 gcc_assert (TREE_CODE (name) == SSA_NAME);
659 FOR_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, p)
660 if (p == name)
661 return i;
663 return -1;
666 /* When the parameter NAME is in REGION, returns its index in
667 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
668 and returns the index of NAME. */
670 static int
671 parameter_index_in_region (tree name, sese region)
673 int i;
675 gcc_assert (TREE_CODE (name) == SSA_NAME);
677 i = parameter_index_in_region_1 (name, region);
678 if (i != -1)
679 return i;
681 gcc_assert (SESE_ADD_PARAMS (region));
683 i = VEC_length (tree, SESE_PARAMS (region));
684 VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
685 return i;
688 /* In the context of sese S, scan the expression E and translate it to
689 a linear expression C. When parsing a symbolic multiplication, K
690 represents the constant multiplier of an expression containing
691 parameters. */
693 static void
694 scan_tree_for_params (sese s, tree e, ppl_Linear_Expression_t c,
695 mpz_t k)
697 if (e == chrec_dont_know)
698 return;
700 switch (TREE_CODE (e))
702 case POLYNOMIAL_CHREC:
703 scan_tree_for_params_right_scev (s, CHREC_RIGHT (e),
704 CHREC_VARIABLE (e), c);
705 scan_tree_for_params (s, CHREC_LEFT (e), c, k);
706 break;
708 case MULT_EXPR:
709 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
711 if (c)
713 mpz_t val;
714 gcc_assert (host_integerp (TREE_OPERAND (e, 1), 0));
715 mpz_init (val);
716 mpz_set_si (val, int_cst_value (TREE_OPERAND (e, 1)));
717 mpz_mul (val, val, k);
718 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, val);
719 mpz_clear (val);
721 else
722 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
724 else
726 if (c)
728 mpz_t val;
729 gcc_assert (host_integerp (TREE_OPERAND (e, 0), 0));
730 mpz_init (val);
731 mpz_set_si (val, int_cst_value (TREE_OPERAND (e, 0)));
732 mpz_mul (val, val, k);
733 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, val);
734 mpz_clear (val);
736 else
737 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
739 break;
741 case PLUS_EXPR:
742 case POINTER_PLUS_EXPR:
743 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
744 scan_tree_for_params (s, TREE_OPERAND (e, 1), c, k);
745 break;
747 case MINUS_EXPR:
749 ppl_Linear_Expression_t tmp_expr = NULL;
751 if (c)
753 ppl_dimension_type dim;
754 ppl_Linear_Expression_space_dimension (c, &dim);
755 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
758 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
759 scan_tree_for_params (s, TREE_OPERAND (e, 1), tmp_expr, k);
761 if (c)
763 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
764 tmp_expr);
765 ppl_delete_Linear_Expression (tmp_expr);
768 break;
771 case NEGATE_EXPR:
773 ppl_Linear_Expression_t tmp_expr = NULL;
775 if (c)
777 ppl_dimension_type dim;
778 ppl_Linear_Expression_space_dimension (c, &dim);
779 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
782 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
784 if (c)
786 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
787 tmp_expr);
788 ppl_delete_Linear_Expression (tmp_expr);
791 break;
794 case BIT_NOT_EXPR:
796 ppl_Linear_Expression_t tmp_expr = NULL;
798 if (c)
800 ppl_dimension_type dim;
801 ppl_Linear_Expression_space_dimension (c, &dim);
802 ppl_new_Linear_Expression_with_dimension (&tmp_expr, dim);
805 scan_tree_for_params (s, TREE_OPERAND (e, 0), tmp_expr, k);
807 if (c)
809 ppl_Coefficient_t coef;
810 mpz_t minus_one;
812 ppl_subtract_Linear_Expression_from_Linear_Expression (c,
813 tmp_expr);
814 ppl_delete_Linear_Expression (tmp_expr);
815 mpz_init (minus_one);
816 mpz_set_si (minus_one, -1);
817 ppl_new_Coefficient_from_mpz_t (&coef, minus_one);
818 ppl_Linear_Expression_add_to_inhomogeneous (c, coef);
819 mpz_clear (minus_one);
820 ppl_delete_Coefficient (coef);
823 break;
826 case SSA_NAME:
828 ppl_dimension_type p = parameter_index_in_region (e, s);
830 if (c)
832 ppl_dimension_type dim;
833 ppl_Linear_Expression_space_dimension (c, &dim);
834 p += dim - sese_nb_params (s);
835 add_value_to_dim (p, c, k);
837 break;
840 case INTEGER_CST:
841 if (c)
842 scan_tree_for_params_int (e, c, k);
843 break;
845 CASE_CONVERT:
846 case NON_LVALUE_EXPR:
847 scan_tree_for_params (s, TREE_OPERAND (e, 0), c, k);
848 break;
850 case ADDR_EXPR:
851 break;
853 default:
854 gcc_unreachable ();
855 break;
859 /* Find parameters with respect to REGION in BB. We are looking in memory
860 access functions, conditions and loop bounds. */
862 static void
863 find_params_in_bb (sese region, gimple_bb_p gbb)
865 int i;
866 unsigned j;
867 data_reference_p dr;
868 gimple stmt;
869 loop_p loop = GBB_BB (gbb)->loop_father;
870 mpz_t one;
872 mpz_init (one);
873 mpz_set_si (one, 1);
875 /* Find parameters in the access functions of data references. */
876 FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
877 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
878 scan_tree_for_params (region, DR_ACCESS_FN (dr, j), NULL, one);
880 /* Find parameters in conditional statements. */
881 FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
883 tree lhs = scalar_evolution_in_region (region, loop,
884 gimple_cond_lhs (stmt));
885 tree rhs = scalar_evolution_in_region (region, loop,
886 gimple_cond_rhs (stmt));
888 scan_tree_for_params (region, lhs, NULL, one);
889 scan_tree_for_params (region, rhs, NULL, one);
892 mpz_clear (one);
895 /* Record the parameters used in the SCOP. A variable is a parameter
896 in a scop if it does not vary during the execution of that scop. */
898 static void
899 find_scop_parameters (scop_p scop)
901 poly_bb_p pbb;
902 unsigned i;
903 sese region = SCOP_REGION (scop);
904 struct loop *loop;
905 mpz_t one;
907 mpz_init (one);
908 mpz_set_si (one, 1);
910 /* Find the parameters used in the loop bounds. */
911 FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
913 tree nb_iters = number_of_latch_executions (loop);
915 if (!chrec_contains_symbols (nb_iters))
916 continue;
918 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
919 scan_tree_for_params (region, nb_iters, NULL, one);
922 mpz_clear (one);
924 /* Find the parameters used in data accesses. */
925 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
926 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
928 scop_set_nb_params (scop, sese_nb_params (region));
929 SESE_ADD_PARAMS (region) = false;
931 ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension
932 (&SCOP_CONTEXT (scop), scop_nb_params (scop), 0);
935 /* Insert in the SCOP context constraints from the estimation of the
936 number of iterations. UB_EXPR is a linear expression describing
937 the number of iterations in a loop. This expression is bounded by
938 the estimation NIT. */
940 static void
941 add_upper_bounds_from_estimated_nit (scop_p scop, double_int nit,
942 ppl_dimension_type dim,
943 ppl_Linear_Expression_t ub_expr)
945 mpz_t val;
946 ppl_Linear_Expression_t nb_iters_le;
947 ppl_Polyhedron_t pol;
948 ppl_Coefficient_t coef;
949 ppl_Constraint_t ub;
951 ppl_new_C_Polyhedron_from_space_dimension (&pol, dim, 0);
952 ppl_new_Linear_Expression_from_Linear_Expression (&nb_iters_le,
953 ub_expr);
955 /* Construct the negated number of last iteration in VAL. */
956 mpz_init (val);
957 mpz_set_double_int (val, nit, false);
958 mpz_sub_ui (val, val, 1);
959 mpz_neg (val, val);
961 /* NB_ITERS_LE holds the number of last iteration in
962 parametrical form. Subtract estimated number of last
963 iteration and assert that result is not positive. */
964 ppl_new_Coefficient_from_mpz_t (&coef, val);
965 ppl_Linear_Expression_add_to_inhomogeneous (nb_iters_le, coef);
966 ppl_delete_Coefficient (coef);
967 ppl_new_Constraint (&ub, nb_iters_le,
968 PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
969 ppl_Polyhedron_add_constraint (pol, ub);
971 /* Remove all but last GDIM dimensions from POL to obtain
972 only the constraints on the parameters. */
974 graphite_dim_t gdim = scop_nb_params (scop);
975 ppl_dimension_type *dims = XNEWVEC (ppl_dimension_type, dim - gdim);
976 graphite_dim_t i;
978 for (i = 0; i < dim - gdim; i++)
979 dims[i] = i;
981 ppl_Polyhedron_remove_space_dimensions (pol, dims, dim - gdim);
982 XDELETEVEC (dims);
985 /* Add the constraints on the parameters to the SCoP context. */
987 ppl_Pointset_Powerset_C_Polyhedron_t constraints_ps;
989 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
990 (&constraints_ps, pol);
991 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
992 (SCOP_CONTEXT (scop), constraints_ps);
993 ppl_delete_Pointset_Powerset_C_Polyhedron (constraints_ps);
996 ppl_delete_Polyhedron (pol);
997 ppl_delete_Linear_Expression (nb_iters_le);
998 ppl_delete_Constraint (ub);
999 mpz_clear (val);
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 ppl_Polyhedron_t outer_ph, int nb,
1008 ppl_Pointset_Powerset_C_Polyhedron_t *domains)
1010 int i;
1011 ppl_Polyhedron_t ph;
1012 tree nb_iters = number_of_latch_executions (loop);
1013 ppl_dimension_type dim = nb + 1 + scop_nb_params (scop);
1014 sese region = SCOP_REGION (scop);
1017 ppl_const_Constraint_System_t pcs;
1018 ppl_dimension_type *map
1019 = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, dim);
1021 ppl_new_C_Polyhedron_from_space_dimension (&ph, dim, 0);
1022 ppl_Polyhedron_get_constraints (outer_ph, &pcs);
1023 ppl_Polyhedron_add_constraints (ph, pcs);
1025 for (i = 0; i < (int) nb; i++)
1026 map[i] = i;
1027 for (i = (int) nb; i < (int) dim - 1; i++)
1028 map[i] = i + 1;
1029 map[dim - 1] = nb;
1031 ppl_Polyhedron_map_space_dimensions (ph, map, dim);
1032 free (map);
1035 /* 0 <= loop_i */
1037 ppl_Constraint_t lb;
1038 ppl_Linear_Expression_t lb_expr;
1040 ppl_new_Linear_Expression_with_dimension (&lb_expr, dim);
1041 ppl_set_coef (lb_expr, nb, 1);
1042 ppl_new_Constraint (&lb, lb_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1043 ppl_delete_Linear_Expression (lb_expr);
1044 ppl_Polyhedron_add_constraint (ph, lb);
1045 ppl_delete_Constraint (lb);
1048 if (TREE_CODE (nb_iters) == INTEGER_CST)
1050 ppl_Constraint_t ub;
1051 ppl_Linear_Expression_t ub_expr;
1053 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1055 /* loop_i <= cst_nb_iters */
1056 ppl_set_coef (ub_expr, nb, -1);
1057 ppl_set_inhomogeneous_tree (ub_expr, nb_iters);
1058 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1059 ppl_Polyhedron_add_constraint (ph, ub);
1060 ppl_delete_Linear_Expression (ub_expr);
1061 ppl_delete_Constraint (ub);
1063 else if (!chrec_contains_undetermined (nb_iters))
1065 mpz_t one;
1066 ppl_Constraint_t ub;
1067 ppl_Linear_Expression_t ub_expr;
1068 double_int nit;
1070 mpz_init (one);
1071 mpz_set_si (one, 1);
1072 ppl_new_Linear_Expression_with_dimension (&ub_expr, dim);
1073 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
1074 scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one);
1075 mpz_clear (one);
1077 if (estimated_loop_iterations (loop, true, &nit))
1078 add_upper_bounds_from_estimated_nit (scop, nit, dim, ub_expr);
1080 /* loop_i <= expr_nb_iters */
1081 ppl_set_coef (ub_expr, nb, -1);
1082 ppl_new_Constraint (&ub, ub_expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1083 ppl_Polyhedron_add_constraint (ph, ub);
1084 ppl_delete_Linear_Expression (ub_expr);
1085 ppl_delete_Constraint (ub);
1087 else
1088 gcc_unreachable ();
1090 if (loop->inner && loop_in_sese_p (loop->inner, region))
1091 build_loop_iteration_domains (scop, loop->inner, ph, nb + 1, domains);
1093 if (nb != 0
1094 && loop->next
1095 && loop_in_sese_p (loop->next, region))
1096 build_loop_iteration_domains (scop, loop->next, outer_ph, nb, domains);
1098 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1099 (&domains[loop->num], ph);
1101 ppl_delete_Polyhedron (ph);
1104 /* Returns a linear expression for tree T evaluated in PBB. */
1106 static ppl_Linear_Expression_t
1107 create_linear_expr_from_tree (poly_bb_p pbb, tree t)
1109 mpz_t one;
1110 ppl_Linear_Expression_t res;
1111 ppl_dimension_type dim;
1112 sese region = SCOP_REGION (PBB_SCOP (pbb));
1113 loop_p loop = pbb_loop (pbb);
1115 dim = pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
1116 ppl_new_Linear_Expression_with_dimension (&res, dim);
1118 t = scalar_evolution_in_region (region, loop, t);
1119 gcc_assert (!automatically_generated_chrec_p (t));
1121 mpz_init (one);
1122 mpz_set_si (one, 1);
1123 scan_tree_for_params (region, t, res, one);
1124 mpz_clear (one);
1126 return res;
1129 /* Returns the ppl constraint type from the gimple tree code CODE. */
1131 static enum ppl_enum_Constraint_Type
1132 ppl_constraint_type_from_tree_code (enum tree_code code)
1134 switch (code)
1136 /* We do not support LT and GT to be able to work with C_Polyhedron.
1137 As we work on integer polyhedron "a < b" can be expressed by
1138 "a + 1 <= b". */
1139 case LT_EXPR:
1140 case GT_EXPR:
1141 gcc_unreachable ();
1143 case LE_EXPR:
1144 return PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL;
1146 case GE_EXPR:
1147 return PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL;
1149 case EQ_EXPR:
1150 return PPL_CONSTRAINT_TYPE_EQUAL;
1152 default:
1153 gcc_unreachable ();
1157 /* Add conditional statement STMT to PS. It is evaluated in PBB and
1158 CODE is used as the comparison operator. This allows us to invert the
1159 condition or to handle inequalities. */
1161 static void
1162 add_condition_to_domain (ppl_Pointset_Powerset_C_Polyhedron_t ps, gimple stmt,
1163 poly_bb_p pbb, enum tree_code code)
1165 mpz_t v;
1166 ppl_Coefficient_t c;
1167 ppl_Linear_Expression_t left, right;
1168 ppl_Constraint_t cstr;
1169 enum ppl_enum_Constraint_Type type;
1171 left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
1172 right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
1174 /* If we have < or > expressions convert them to <= or >= by adding 1 to
1175 the left or the right side of the expression. */
1176 if (code == LT_EXPR)
1178 mpz_init (v);
1179 mpz_set_si (v, 1);
1180 ppl_new_Coefficient (&c);
1181 ppl_assign_Coefficient_from_mpz_t (c, v);
1182 ppl_Linear_Expression_add_to_inhomogeneous (left, c);
1183 ppl_delete_Coefficient (c);
1184 mpz_clear (v);
1186 code = LE_EXPR;
1188 else if (code == GT_EXPR)
1190 mpz_init (v);
1191 mpz_set_si (v, 1);
1192 ppl_new_Coefficient (&c);
1193 ppl_assign_Coefficient_from_mpz_t (c, v);
1194 ppl_Linear_Expression_add_to_inhomogeneous (right, c);
1195 ppl_delete_Coefficient (c);
1196 mpz_clear (v);
1198 code = GE_EXPR;
1201 type = ppl_constraint_type_from_tree_code (code);
1203 ppl_subtract_Linear_Expression_from_Linear_Expression (left, right);
1205 ppl_new_Constraint (&cstr, left, type);
1206 ppl_Pointset_Powerset_C_Polyhedron_add_constraint (ps, cstr);
1208 ppl_delete_Constraint (cstr);
1209 ppl_delete_Linear_Expression (left);
1210 ppl_delete_Linear_Expression (right);
1213 /* Add conditional statement STMT to pbb. CODE is used as the comparision
1214 operator. This allows us to invert the condition or to handle
1215 inequalities. */
1217 static void
1218 add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
1220 if (code == NE_EXPR)
1222 ppl_Pointset_Powerset_C_Polyhedron_t left = PBB_DOMAIN (pbb);
1223 ppl_Pointset_Powerset_C_Polyhedron_t right;
1224 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1225 (&right, left);
1226 add_condition_to_domain (left, stmt, pbb, LT_EXPR);
1227 add_condition_to_domain (right, stmt, pbb, GT_EXPR);
1228 ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (left, right);
1229 ppl_delete_Pointset_Powerset_C_Polyhedron (right);
1231 else
1232 add_condition_to_domain (PBB_DOMAIN (pbb), stmt, pbb, code);
1235 /* Add conditions to the domain of PBB. */
1237 static void
1238 add_conditions_to_domain (poly_bb_p pbb)
1240 unsigned int i;
1241 gimple stmt;
1242 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1244 if (VEC_empty (gimple, GBB_CONDITIONS (gbb)))
1245 return;
1247 FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
1248 switch (gimple_code (stmt))
1250 case GIMPLE_COND:
1252 enum tree_code code = gimple_cond_code (stmt);
1254 /* The conditions for ELSE-branches are inverted. */
1255 if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
1256 code = invert_tree_comparison (code, false);
1258 add_condition_to_pbb (pbb, stmt, code);
1259 break;
1262 case GIMPLE_SWITCH:
1263 /* Switch statements are not supported right now - fall throught. */
1265 default:
1266 gcc_unreachable ();
1267 break;
1271 /* Traverses all the GBBs of the SCOP and add their constraints to the
1272 iteration domains. */
1274 static void
1275 add_conditions_to_constraints (scop_p scop)
1277 int i;
1278 poly_bb_p pbb;
1280 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1281 add_conditions_to_domain (pbb);
1284 /* Structure used to pass data to dom_walk. */
1286 struct bsc
1288 VEC (gimple, heap) **conditions, **cases;
1289 sese region;
1292 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1293 edge between BB and its predecessor is not a loop exit edge, and
1294 the last statement of the single predecessor is a COND_EXPR. */
1296 static gimple
1297 single_pred_cond_non_loop_exit (basic_block bb)
1299 if (single_pred_p (bb))
1301 edge e = single_pred_edge (bb);
1302 basic_block pred = e->src;
1303 gimple stmt;
1305 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1306 return NULL;
1308 stmt = last_stmt (pred);
1310 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1311 return stmt;
1314 return NULL;
1317 /* Call-back for dom_walk executed before visiting the dominated
1318 blocks. */
1320 static void
1321 build_sese_conditions_before (struct dom_walk_data *dw_data,
1322 basic_block bb)
1324 struct bsc *data = (struct bsc *) dw_data->global_data;
1325 VEC (gimple, heap) **conditions = data->conditions;
1326 VEC (gimple, heap) **cases = data->cases;
1327 gimple_bb_p gbb;
1328 gimple stmt;
1330 if (!bb_in_sese_p (bb, data->region))
1331 return;
1333 stmt = single_pred_cond_non_loop_exit (bb);
1335 if (stmt)
1337 edge e = single_pred_edge (bb);
1339 VEC_safe_push (gimple, heap, *conditions, stmt);
1341 if (e->flags & EDGE_TRUE_VALUE)
1342 VEC_safe_push (gimple, heap, *cases, stmt);
1343 else
1344 VEC_safe_push (gimple, heap, *cases, NULL);
1347 gbb = gbb_from_bb (bb);
1349 if (gbb)
1351 GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
1352 GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
1356 /* Call-back for dom_walk executed after visiting the dominated
1357 blocks. */
1359 static void
1360 build_sese_conditions_after (struct dom_walk_data *dw_data,
1361 basic_block bb)
1363 struct bsc *data = (struct bsc *) dw_data->global_data;
1364 VEC (gimple, heap) **conditions = data->conditions;
1365 VEC (gimple, heap) **cases = data->cases;
1367 if (!bb_in_sese_p (bb, data->region))
1368 return;
1370 if (single_pred_cond_non_loop_exit (bb))
1372 VEC_pop (gimple, *conditions);
1373 VEC_pop (gimple, *cases);
1377 /* Record all conditions in REGION. */
1379 static void
1380 build_sese_conditions (sese region)
1382 struct dom_walk_data walk_data;
1383 VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
1384 VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
1385 struct bsc data;
1387 data.conditions = &conditions;
1388 data.cases = &cases;
1389 data.region = region;
1391 walk_data.dom_direction = CDI_DOMINATORS;
1392 walk_data.initialize_block_local_data = NULL;
1393 walk_data.before_dom_children = build_sese_conditions_before;
1394 walk_data.after_dom_children = build_sese_conditions_after;
1395 walk_data.global_data = &data;
1396 walk_data.block_local_data_size = 0;
1398 init_walk_dominator_tree (&walk_data);
1399 walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
1400 fini_walk_dominator_tree (&walk_data);
1402 VEC_free (gimple, heap, conditions);
1403 VEC_free (gimple, heap, cases);
1406 /* Add constraints on the possible values of parameter P from the type
1407 of P. */
1409 static void
1410 add_param_constraints (scop_p scop, ppl_Polyhedron_t context, graphite_dim_t p)
1412 ppl_Constraint_t cstr;
1413 ppl_Linear_Expression_t le;
1414 tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
1415 tree type = TREE_TYPE (parameter);
1416 tree lb = NULL_TREE;
1417 tree ub = NULL_TREE;
1419 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1420 lb = lower_bound_in_type (type, type);
1421 else
1422 lb = TYPE_MIN_VALUE (type);
1424 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1425 ub = upper_bound_in_type (type, type);
1426 else
1427 ub = TYPE_MAX_VALUE (type);
1429 if (lb)
1431 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1432 ppl_set_coef (le, p, -1);
1433 ppl_set_inhomogeneous_tree (le, lb);
1434 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
1435 ppl_Polyhedron_add_constraint (context, cstr);
1436 ppl_delete_Linear_Expression (le);
1437 ppl_delete_Constraint (cstr);
1440 if (ub)
1442 ppl_new_Linear_Expression_with_dimension (&le, scop_nb_params (scop));
1443 ppl_set_coef (le, p, -1);
1444 ppl_set_inhomogeneous_tree (le, ub);
1445 ppl_new_Constraint (&cstr, le, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1446 ppl_Polyhedron_add_constraint (context, cstr);
1447 ppl_delete_Linear_Expression (le);
1448 ppl_delete_Constraint (cstr);
1452 /* Build the context of the SCOP. The context usually contains extra
1453 constraints that are added to the iteration domains that constrain
1454 some parameters. */
1456 static void
1457 build_scop_context (scop_p scop)
1459 ppl_Polyhedron_t context;
1460 ppl_Pointset_Powerset_C_Polyhedron_t ps;
1461 graphite_dim_t p, n = scop_nb_params (scop);
1463 ppl_new_C_Polyhedron_from_space_dimension (&context, n, 0);
1465 for (p = 0; p < n; p++)
1466 add_param_constraints (scop, context, p);
1468 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1469 (&ps, context);
1470 ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
1471 (SCOP_CONTEXT (scop), ps);
1473 ppl_delete_Pointset_Powerset_C_Polyhedron (ps);
1474 ppl_delete_Polyhedron (context);
1477 /* Build the iteration domains: the loops belonging to the current
1478 SCOP, and that vary for the execution of the current basic block.
1479 Returns false if there is no loop in SCOP. */
1481 static void
1482 build_scop_iteration_domain (scop_p scop)
1484 struct loop *loop;
1485 sese region = SCOP_REGION (scop);
1486 int i;
1487 ppl_Polyhedron_t ph;
1488 poly_bb_p pbb;
1489 int nb_loops = number_of_loops ();
1490 ppl_Pointset_Powerset_C_Polyhedron_t *domains
1491 = XNEWVEC (ppl_Pointset_Powerset_C_Polyhedron_t, nb_loops);
1493 for (i = 0; i < nb_loops; i++)
1494 domains[i] = NULL;
1496 ppl_new_C_Polyhedron_from_space_dimension (&ph, scop_nb_params (scop), 0);
1498 FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
1499 if (!loop_in_sese_p (loop_outer (loop), region))
1500 build_loop_iteration_domains (scop, loop, ph, 0, domains);
1502 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1503 if (domains[gbb_loop (PBB_BLACK_BOX (pbb))->num])
1504 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
1505 (&PBB_DOMAIN (pbb), (ppl_const_Pointset_Powerset_C_Polyhedron_t)
1506 domains[gbb_loop (PBB_BLACK_BOX (pbb))->num]);
1507 else
1508 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron
1509 (&PBB_DOMAIN (pbb), ph);
1511 for (i = 0; i < nb_loops; i++)
1512 if (domains[i])
1513 ppl_delete_Pointset_Powerset_C_Polyhedron (domains[i]);
1515 ppl_delete_Polyhedron (ph);
1516 free (domains);
1519 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1520 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1521 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1522 domain. */
1524 static void
1525 pdr_add_alias_set (ppl_Polyhedron_t accesses, data_reference_p dr,
1526 ppl_dimension_type accessp_nb_dims,
1527 ppl_dimension_type dom_nb_dims)
1529 ppl_Linear_Expression_t alias;
1530 ppl_Constraint_t cstr;
1531 int alias_set_num = 0;
1532 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1534 if (bap && bap->alias_set)
1535 alias_set_num = *(bap->alias_set);
1537 ppl_new_Linear_Expression_with_dimension (&alias, accessp_nb_dims);
1539 ppl_set_coef (alias, dom_nb_dims, 1);
1540 ppl_set_inhomogeneous (alias, -alias_set_num);
1541 ppl_new_Constraint (&cstr, alias, PPL_CONSTRAINT_TYPE_EQUAL);
1542 ppl_Polyhedron_add_constraint (accesses, cstr);
1544 ppl_delete_Linear_Expression (alias);
1545 ppl_delete_Constraint (cstr);
1548 /* Add to ACCESSES polyhedron equalities defining the access functions
1549 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1550 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1551 PBB is the poly_bb_p that contains the data reference DR. */
1553 static void
1554 pdr_add_memory_accesses (ppl_Polyhedron_t accesses, data_reference_p dr,
1555 ppl_dimension_type accessp_nb_dims,
1556 ppl_dimension_type dom_nb_dims,
1557 poly_bb_p pbb)
1559 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1560 mpz_t v;
1561 scop_p scop = PBB_SCOP (pbb);
1562 sese region = SCOP_REGION (scop);
1564 mpz_init (v);
1566 for (i = 0; i < nb_subscripts; i++)
1568 ppl_Linear_Expression_t fn, access;
1569 ppl_Constraint_t cstr;
1570 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1571 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1573 ppl_new_Linear_Expression_with_dimension (&fn, dom_nb_dims);
1574 ppl_new_Linear_Expression_with_dimension (&access, accessp_nb_dims);
1576 mpz_set_si (v, 1);
1577 scan_tree_for_params (region, afn, fn, v);
1578 ppl_assign_Linear_Expression_from_Linear_Expression (access, fn);
1580 ppl_set_coef (access, subscript, -1);
1581 ppl_new_Constraint (&cstr, access, PPL_CONSTRAINT_TYPE_EQUAL);
1582 ppl_Polyhedron_add_constraint (accesses, cstr);
1584 ppl_delete_Linear_Expression (fn);
1585 ppl_delete_Linear_Expression (access);
1586 ppl_delete_Constraint (cstr);
1589 mpz_clear (v);
1592 /* Add constrains representing the size of the accessed data to the
1593 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1594 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1595 domain. */
1597 static void
1598 pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
1599 ppl_dimension_type accessp_nb_dims,
1600 ppl_dimension_type dom_nb_dims)
1602 tree ref = DR_REF (dr);
1603 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
1605 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
1607 ppl_Linear_Expression_t expr;
1608 ppl_Constraint_t cstr;
1609 ppl_dimension_type subscript = dom_nb_dims + 1 + i;
1610 tree low, high;
1612 if (TREE_CODE (ref) != ARRAY_REF)
1613 break;
1615 low = array_ref_low_bound (ref);
1617 /* subscript - low >= 0 */
1618 if (host_integerp (low, 0))
1620 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1621 ppl_set_coef (expr, subscript, 1);
1623 ppl_set_inhomogeneous (expr, -int_cst_value (low));
1625 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1626 ppl_Polyhedron_add_constraint (accesses, cstr);
1627 ppl_delete_Linear_Expression (expr);
1628 ppl_delete_Constraint (cstr);
1631 high = array_ref_up_bound (ref);
1633 /* high - subscript >= 0 */
1634 if (high && host_integerp (high, 0)
1635 /* 1-element arrays at end of structures may extend over
1636 their declared size. */
1637 && !(array_at_struct_end_p (ref)
1638 && operand_equal_p (low, high, 0)))
1640 ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
1641 ppl_set_coef (expr, subscript, -1);
1643 ppl_set_inhomogeneous (expr, int_cst_value (high));
1645 ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
1646 ppl_Polyhedron_add_constraint (accesses, cstr);
1647 ppl_delete_Linear_Expression (expr);
1648 ppl_delete_Constraint (cstr);
1653 /* Build data accesses for DR in PBB. */
1655 static void
1656 build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1658 ppl_Polyhedron_t accesses;
1659 ppl_Pointset_Powerset_C_Polyhedron_t accesses_ps;
1660 ppl_dimension_type dom_nb_dims;
1661 ppl_dimension_type accessp_nb_dims;
1662 int dr_base_object_set;
1664 ppl_Pointset_Powerset_C_Polyhedron_space_dimension (PBB_DOMAIN (pbb),
1665 &dom_nb_dims);
1666 accessp_nb_dims = dom_nb_dims + 1 + DR_NUM_DIMENSIONS (dr);
1668 ppl_new_C_Polyhedron_from_space_dimension (&accesses, accessp_nb_dims, 0);
1670 pdr_add_alias_set (accesses, dr, accessp_nb_dims, dom_nb_dims);
1671 pdr_add_memory_accesses (accesses, dr, accessp_nb_dims, dom_nb_dims, pbb);
1672 pdr_add_data_dimensions (accesses, dr, accessp_nb_dims, dom_nb_dims);
1674 ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&accesses_ps,
1675 accesses);
1676 ppl_delete_Polyhedron (accesses);
1678 gcc_assert (dr->aux);
1679 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
1681 new_poly_dr (pbb, dr_base_object_set, accesses_ps,
1682 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
1683 dr, DR_NUM_DIMENSIONS (dr));
1686 /* Write to FILE the alias graph of data references in DIMACS format. */
1688 static inline bool
1689 write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
1690 VEC (data_reference_p, heap) *drs)
1692 int num_vertex = VEC_length (data_reference_p, drs);
1693 int edge_num = 0;
1694 data_reference_p dr1, dr2;
1695 int i, j;
1697 if (num_vertex == 0)
1698 return true;
1700 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1701 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1702 if (dr_may_alias_p (dr1, dr2))
1703 edge_num++;
1705 fprintf (file, "$\n");
1707 if (comment)
1708 fprintf (file, "c %s\n", comment);
1710 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1712 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1713 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1714 if (dr_may_alias_p (dr1, dr2))
1715 fprintf (file, "e %d %d\n", i + 1, j + 1);
1717 return true;
1720 /* Write to FILE the alias graph of data references in DOT format. */
1722 static inline bool
1723 write_alias_graph_to_ascii_dot (FILE *file, char *comment,
1724 VEC (data_reference_p, heap) *drs)
1726 int num_vertex = VEC_length (data_reference_p, drs);
1727 data_reference_p dr1, dr2;
1728 int i, j;
1730 if (num_vertex == 0)
1731 return true;
1733 fprintf (file, "$\n");
1735 if (comment)
1736 fprintf (file, "c %s\n", comment);
1738 /* First print all the vertices. */
1739 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1740 fprintf (file, "n%d;\n", i);
1742 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1743 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1744 if (dr_may_alias_p (dr1, dr2))
1745 fprintf (file, "n%d n%d\n", i, j);
1747 return true;
1750 /* Write to FILE the alias graph of data references in ECC format. */
1752 static inline bool
1753 write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
1754 VEC (data_reference_p, heap) *drs)
1756 int num_vertex = VEC_length (data_reference_p, drs);
1757 data_reference_p dr1, dr2;
1758 int i, j;
1760 if (num_vertex == 0)
1761 return true;
1763 fprintf (file, "$\n");
1765 if (comment)
1766 fprintf (file, "c %s\n", comment);
1768 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1769 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1770 if (dr_may_alias_p (dr1, dr2))
1771 fprintf (file, "%d %d\n", i, j);
1773 return true;
1776 /* Check if DR1 and DR2 are in the same object set. */
1778 static bool
1779 dr_same_base_object_p (const struct data_reference *dr1,
1780 const struct data_reference *dr2)
1782 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1785 /* Uses DFS component number as representative of alias-sets. Also tests for
1786 optimality by verifying if every connected component is a clique. Returns
1787 true (1) if the above test is true, and false (0) otherwise. */
1789 static int
1790 build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs)
1792 int num_vertices = VEC_length (data_reference_p, drs);
1793 struct graph *g = new_graph (num_vertices);
1794 data_reference_p dr1, dr2;
1795 int i, j;
1796 int num_connected_components;
1797 int v_indx1, v_indx2, num_vertices_in_component;
1798 int *all_vertices;
1799 int *vertices;
1800 struct graph_edge *e;
1801 int this_component_is_clique;
1802 int all_components_are_cliques = 1;
1804 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1805 for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1806 if (dr_may_alias_p (dr1, dr2))
1808 add_edge (g, i, j);
1809 add_edge (g, j, i);
1812 all_vertices = XNEWVEC (int, num_vertices);
1813 vertices = XNEWVEC (int, num_vertices);
1814 for (i = 0; i < num_vertices; i++)
1815 all_vertices[i] = i;
1817 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1818 NULL, true, NULL);
1819 for (i = 0; i < g->n_vertices; i++)
1821 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1822 base_alias_pair *bap;
1824 gcc_assert (dr->aux);
1825 bap = (base_alias_pair *)(dr->aux);
1827 bap->alias_set = XNEW (int);
1828 *(bap->alias_set) = g->vertices[i].component + 1;
1831 /* Verify if the DFS numbering results in optimal solution. */
1832 for (i = 0; i < num_connected_components; i++)
1834 num_vertices_in_component = 0;
1835 /* Get all vertices whose DFS component number is the same as i. */
1836 for (j = 0; j < num_vertices; j++)
1837 if (g->vertices[j].component == i)
1838 vertices[num_vertices_in_component++] = j;
1840 /* Now test if the vertices in 'vertices' form a clique, by testing
1841 for edges among each pair. */
1842 this_component_is_clique = 1;
1843 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1845 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1847 /* Check if the two vertices are connected by iterating
1848 through all the edges which have one of these are source. */
1849 e = g->vertices[vertices[v_indx2]].pred;
1850 while (e)
1852 if (e->src == vertices[v_indx1])
1853 break;
1854 e = e->pred_next;
1856 if (!e)
1858 this_component_is_clique = 0;
1859 break;
1862 if (!this_component_is_clique)
1863 all_components_are_cliques = 0;
1867 free (all_vertices);
1868 free (vertices);
1869 free_graph (g);
1870 return all_components_are_cliques;
1873 /* Group each data reference in DRS with its base object set num. */
1875 static void
1876 build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
1878 int num_vertex = VEC_length (data_reference_p, drs);
1879 struct graph *g = new_graph (num_vertex);
1880 data_reference_p dr1, dr2;
1881 int i, j;
1882 int *queue;
1884 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
1885 for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
1886 if (dr_same_base_object_p (dr1, dr2))
1888 add_edge (g, i, j);
1889 add_edge (g, j, i);
1892 queue = XNEWVEC (int, num_vertex);
1893 for (i = 0; i < num_vertex; i++)
1894 queue[i] = i;
1896 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
1898 for (i = 0; i < g->n_vertices; i++)
1900 data_reference_p dr = VEC_index (data_reference_p, drs, i);
1901 base_alias_pair *bap;
1903 gcc_assert (dr->aux);
1904 bap = (base_alias_pair *)(dr->aux);
1906 bap->base_obj_set = g->vertices[i].component + 1;
1909 free (queue);
1910 free_graph (g);
1913 /* Build the data references for PBB. */
1915 static void
1916 build_pbb_drs (poly_bb_p pbb)
1918 int j;
1919 data_reference_p dr;
1920 VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
1922 FOR_EACH_VEC_ELT (data_reference_p, gbb_drs, j, dr)
1923 build_poly_dr (dr, pbb);
1926 /* Dump to file the alias graphs for the data references in DRS. */
1928 static void
1929 dump_alias_graphs (VEC (data_reference_p, heap) *drs)
1931 char comment[100];
1932 FILE *file_dimacs, *file_ecc, *file_dot;
1934 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1935 if (file_dimacs)
1937 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1938 current_function_name ());
1939 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1940 fclose (file_dimacs);
1943 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1944 if (file_ecc)
1946 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1947 current_function_name ());
1948 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1949 fclose (file_ecc);
1952 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1953 if (file_dot)
1955 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1956 current_function_name ());
1957 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1958 fclose (file_dot);
1962 /* Build data references in SCOP. */
1964 static void
1965 build_scop_drs (scop_p scop)
1967 int i, j;
1968 poly_bb_p pbb;
1969 data_reference_p dr;
1970 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
1972 /* Remove all the PBBs that do not have data references: these basic
1973 blocks are not handled in the polyhedral representation. */
1974 for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1975 if (VEC_empty (data_reference_p, GBB_DATA_REFS (PBB_BLACK_BOX (pbb))))
1977 free_gimple_bb (PBB_BLACK_BOX (pbb));
1978 VEC_ordered_remove (poly_bb_p, SCOP_BBS (scop), i);
1979 i--;
1982 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
1983 for (j = 0; VEC_iterate (data_reference_p,
1984 GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
1985 VEC_safe_push (data_reference_p, heap, drs, dr);
1987 FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr)
1988 dr->aux = XNEW (base_alias_pair);
1990 if (!build_alias_set_optimal_p (drs))
1992 /* TODO: Add support when building alias set is not optimal. */
1996 build_base_obj_set_for_drs (drs);
1998 /* When debugging, enable the following code. This cannot be used
1999 in production compilers. */
2000 if (0)
2001 dump_alias_graphs (drs);
2003 VEC_free (data_reference_p, heap, drs);
2005 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2006 build_pbb_drs (pbb);
2009 /* Return a gsi at the position of the phi node STMT. */
2011 static gimple_stmt_iterator
2012 gsi_for_phi_node (gimple stmt)
2014 gimple_stmt_iterator psi;
2015 basic_block bb = gimple_bb (stmt);
2017 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
2018 if (stmt == gsi_stmt (psi))
2019 return psi;
2021 gcc_unreachable ();
2022 return psi;
2025 /* Analyze all the data references of STMTS and add them to the
2026 GBB_DATA_REFS vector of BB. */
2028 static void
2029 analyze_drs_in_stmts (scop_p scop, basic_block bb, VEC (gimple, heap) *stmts)
2031 loop_p nest;
2032 gimple_bb_p gbb;
2033 gimple stmt;
2034 int i;
2036 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2037 return;
2039 nest = outermost_loop_in_sese (SCOP_REGION (scop), bb);
2040 gbb = gbb_from_bb (bb);
2042 FOR_EACH_VEC_ELT (gimple, stmts, i, stmt)
2043 if (!is_gimple_debug (stmt))
2044 graphite_find_data_references_in_stmt (nest, stmt,
2045 &GBB_DATA_REFS (gbb));
2048 /* Insert STMT at the end of the STMTS sequence and then insert the
2049 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2050 on STMTS. */
2052 static void
2053 insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
2054 gimple_stmt_iterator insert_gsi)
2056 gimple_stmt_iterator gsi;
2057 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2059 if (!stmts)
2060 stmts = gimple_seq_alloc ();
2062 gsi = gsi_last (stmts);
2063 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2064 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2065 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2067 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2068 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
2069 VEC_free (gimple, heap, x);
2072 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2074 static void
2075 insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
2077 gimple_seq stmts;
2078 gimple_stmt_iterator si;
2079 gimple_stmt_iterator gsi;
2080 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2081 gimple stmt = gimple_build_assign (res, var);
2082 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2084 if (!stmts)
2085 stmts = gimple_seq_alloc ();
2086 si = gsi_last (stmts);
2087 gsi_insert_after (&si, stmt, GSI_NEW_STMT);
2088 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2089 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2091 if (gimple_code (after_stmt) == GIMPLE_PHI)
2093 gsi = gsi_after_labels (gimple_bb (after_stmt));
2094 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2096 else
2098 gsi = gsi_for_stmt (after_stmt);
2099 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2102 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
2103 VEC_free (gimple, heap, x);
2106 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2108 static void
2109 new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2111 VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
2112 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2113 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2114 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
2115 int index, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
2117 /* The INDEX of PBB in SCOP_BBS. */
2118 for (index = 0; index < n; index++)
2119 if (VEC_index (poly_bb_p, SCOP_BBS (scop), index) == pbb)
2120 break;
2122 GBB_PBB (gbb1) = pbb1;
2123 ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
2124 (&PBB_DOMAIN (pbb1), PBB_DOMAIN (pbb));
2125 GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
2126 GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
2127 VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
2130 /* Insert on edge E the assignment "RES := EXPR". */
2132 static void
2133 insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
2135 gimple_stmt_iterator gsi;
2136 gimple_seq stmts;
2137 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
2138 gimple stmt = gimple_build_assign (res, var);
2139 basic_block bb;
2140 VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
2142 if (!stmts)
2143 stmts = gimple_seq_alloc ();
2145 gsi = gsi_last (stmts);
2146 gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
2147 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
2148 VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
2150 gsi_insert_seq_on_edge (e, stmts);
2151 gsi_commit_edge_inserts ();
2152 bb = gimple_bb (stmt);
2154 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2155 return;
2157 if (!gbb_from_bb (bb))
2158 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
2160 analyze_drs_in_stmts (scop, bb, x);
2161 VEC_free (gimple, heap, x);
2164 /* Creates a zero dimension array of the same type as VAR. */
2166 static tree
2167 create_zero_dim_array (tree var, const char *base_name)
2169 tree index_type = build_index_type (integer_zero_node);
2170 tree elt_type = TREE_TYPE (var);
2171 tree array_type = build_array_type (elt_type, index_type);
2172 tree base = create_tmp_var (array_type, base_name);
2174 add_referenced_var (base);
2176 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2177 NULL_TREE);
2180 /* Returns true when PHI is a loop close phi node. */
2182 static bool
2183 scalar_close_phi_node_p (gimple phi)
2185 if (gimple_code (phi) != GIMPLE_PHI
2186 || !is_gimple_reg (gimple_phi_result (phi)))
2187 return false;
2189 /* Note that loop close phi nodes should have a single argument
2190 because we translated the representation into a canonical form
2191 before Graphite: see canonicalize_loop_closed_ssa_form. */
2192 return (gimple_phi_num_args (phi) == 1);
2195 /* For a definition DEF in REGION, propagates the expression EXPR in
2196 all the uses of DEF outside REGION. */
2198 static void
2199 propagate_expr_outside_region (tree def, tree expr, sese region)
2201 imm_use_iterator imm_iter;
2202 gimple use_stmt;
2203 gimple_seq stmts;
2204 bool replaced_once = false;
2206 gcc_assert (TREE_CODE (def) == SSA_NAME);
2208 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2209 NULL_TREE);
2211 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2212 if (!is_gimple_debug (use_stmt)
2213 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2215 ssa_op_iter iter;
2216 use_operand_p use_p;
2218 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2219 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2220 && (replaced_once = true))
2221 replace_exp (use_p, expr);
2223 update_stmt (use_stmt);
2226 if (replaced_once)
2228 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2229 gsi_commit_edge_inserts ();
2233 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2234 dimension array for it. */
2236 static void
2237 rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2239 sese region = SCOP_REGION (scop);
2240 gimple phi = gsi_stmt (*psi);
2241 tree res = gimple_phi_result (phi);
2242 tree var = SSA_NAME_VAR (res);
2243 basic_block bb = gimple_bb (phi);
2244 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2245 tree arg = gimple_phi_arg_def (phi, 0);
2246 gimple stmt;
2248 /* Note that loop close phi nodes should have a single argument
2249 because we translated the representation into a canonical form
2250 before Graphite: see canonicalize_loop_closed_ssa_form. */
2251 gcc_assert (gimple_phi_num_args (phi) == 1);
2253 /* The phi node can be a non close phi node, when its argument is
2254 invariant, or a default definition. */
2255 if (is_gimple_min_invariant (arg)
2256 || SSA_NAME_IS_DEFAULT_DEF (arg))
2258 propagate_expr_outside_region (res, arg, region);
2259 gsi_next (psi);
2260 return;
2263 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2265 propagate_expr_outside_region (res, arg, region);
2266 stmt = gimple_build_assign (res, arg);
2267 remove_phi_node (psi, false);
2268 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2269 SSA_NAME_DEF_STMT (res) = stmt;
2270 return;
2273 /* If res is scev analyzable and is not a scalar value, it is safe
2274 to ignore the close phi node: it will be code generated in the
2275 out of Graphite pass. */
2276 else if (scev_analyzable_p (res, region))
2278 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2279 tree scev;
2281 if (!loop_in_sese_p (loop, region))
2283 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2284 scev = scalar_evolution_in_region (region, loop, arg);
2285 scev = compute_overall_effect_of_inner_loop (loop, scev);
2287 else
2288 scev = scalar_evolution_in_region (region, loop, res);
2290 if (tree_does_not_contain_chrecs (scev))
2291 propagate_expr_outside_region (res, scev, region);
2293 gsi_next (psi);
2294 return;
2296 else
2298 tree zero_dim_array = create_zero_dim_array (var, "Close_Phi");
2300 stmt = gimple_build_assign (res, zero_dim_array);
2302 if (TREE_CODE (arg) == SSA_NAME)
2303 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2304 SSA_NAME_DEF_STMT (arg));
2305 else
2306 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
2307 zero_dim_array, arg);
2310 remove_phi_node (psi, false);
2311 SSA_NAME_DEF_STMT (res) = stmt;
2313 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
2316 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2317 dimension array for it. */
2319 static void
2320 rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
2322 size_t i;
2323 gimple phi = gsi_stmt (*psi);
2324 basic_block bb = gimple_bb (phi);
2325 tree res = gimple_phi_result (phi);
2326 tree var = SSA_NAME_VAR (res);
2327 tree zero_dim_array = create_zero_dim_array (var, "phi_out_of_ssa");
2328 gimple stmt;
2329 gimple_seq stmts;
2331 for (i = 0; i < gimple_phi_num_args (phi); i++)
2333 tree arg = gimple_phi_arg_def (phi, i);
2334 edge e = gimple_phi_arg_edge (phi, i);
2336 /* Avoid the insertion of code in the loop latch to please the
2337 pattern matching of the vectorizer. */
2338 if (TREE_CODE (arg) == SSA_NAME
2339 && e->src == bb->loop_father->latch)
2340 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
2341 SSA_NAME_DEF_STMT (arg));
2342 else
2343 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
2346 var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
2348 stmt = gimple_build_assign (res, var);
2349 remove_phi_node (psi, false);
2350 SSA_NAME_DEF_STMT (res) = stmt;
2352 insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
2355 /* Rewrite the degenerate phi node at position PSI from the degenerate
2356 form "x = phi (y, y, ..., y)" to "x = y". */
2358 static void
2359 rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2361 tree rhs;
2362 gimple stmt;
2363 gimple_stmt_iterator gsi;
2364 gimple phi = gsi_stmt (*psi);
2365 tree res = gimple_phi_result (phi);
2366 basic_block bb;
2368 bb = gimple_bb (phi);
2369 rhs = degenerate_phi_result (phi);
2370 gcc_assert (rhs);
2372 stmt = gimple_build_assign (res, rhs);
2373 remove_phi_node (psi, false);
2374 SSA_NAME_DEF_STMT (res) = stmt;
2376 gsi = gsi_after_labels (bb);
2377 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2380 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2382 static void
2383 rewrite_reductions_out_of_ssa (scop_p scop)
2385 basic_block bb;
2386 gimple_stmt_iterator psi;
2387 sese region = SCOP_REGION (scop);
2389 FOR_EACH_BB (bb)
2390 if (bb_in_sese_p (bb, region))
2391 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2393 gimple phi = gsi_stmt (psi);
2395 if (!is_gimple_reg (gimple_phi_result (phi)))
2397 gsi_next (&psi);
2398 continue;
2401 if (gimple_phi_num_args (phi) > 1
2402 && degenerate_phi_result (phi))
2403 rewrite_degenerate_phi (&psi);
2405 else if (scalar_close_phi_node_p (phi))
2406 rewrite_close_phi_out_of_ssa (scop, &psi);
2408 else if (reduction_phi_p (region, &psi))
2409 rewrite_phi_out_of_ssa (scop, &psi);
2412 update_ssa (TODO_update_ssa);
2413 #ifdef ENABLE_CHECKING
2414 verify_loop_closed_ssa (true);
2415 #endif
2418 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2419 read from ZERO_DIM_ARRAY. */
2421 static void
2422 rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
2423 tree def, gimple use_stmt)
2425 tree var = SSA_NAME_VAR (def);
2426 gimple name_stmt = gimple_build_assign (var, zero_dim_array);
2427 tree name = make_ssa_name (var, name_stmt);
2428 ssa_op_iter iter;
2429 use_operand_p use_p;
2431 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
2433 gimple_assign_set_lhs (name_stmt, name);
2434 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
2436 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2437 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2438 replace_exp (use_p, name);
2440 update_stmt (use_stmt);
2443 /* For every definition DEF in the SCOP that is used outside the scop,
2444 insert a closing-scop definition in the basic block just after this
2445 SCOP. */
2447 static void
2448 handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2450 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2451 tree new_name = make_ssa_name (var, stmt);
2452 bool needs_copy = false;
2453 use_operand_p use_p;
2454 imm_use_iterator imm_iter;
2455 gimple use_stmt;
2456 sese region = SCOP_REGION (scop);
2458 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2460 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2462 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2464 SET_USE (use_p, new_name);
2466 update_stmt (use_stmt);
2467 needs_copy = true;
2471 /* Insert in the empty BB just after the scop a use of DEF such
2472 that the rewrite of cross_bb_scalar_dependences won't insert
2473 arrays everywhere else. */
2474 if (needs_copy)
2476 gimple assign = gimple_build_assign (new_name, def);
2477 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2479 add_referenced_var (var);
2480 SSA_NAME_DEF_STMT (new_name) = assign;
2481 update_stmt (assign);
2482 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2486 /* Rewrite the scalar dependences crossing the boundary of the BB
2487 containing STMT with an array. Return true when something has been
2488 changed. */
2490 static bool
2491 rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
2493 sese region = SCOP_REGION (scop);
2494 gimple stmt = gsi_stmt (*gsi);
2495 imm_use_iterator imm_iter;
2496 tree def;
2497 basic_block def_bb;
2498 tree zero_dim_array = NULL_TREE;
2499 gimple use_stmt;
2500 bool res = false;
2502 switch (gimple_code (stmt))
2504 case GIMPLE_ASSIGN:
2505 def = gimple_assign_lhs (stmt);
2506 break;
2508 case GIMPLE_CALL:
2509 def = gimple_call_lhs (stmt);
2510 break;
2512 default:
2513 return false;
2516 if (!def
2517 || !is_gimple_reg (def))
2518 return false;
2520 if (scev_analyzable_p (def, region))
2522 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2523 tree scev = scalar_evolution_in_region (region, loop, def);
2525 if (tree_contains_chrecs (scev, NULL))
2526 return false;
2528 propagate_expr_outside_region (def, scev, region);
2529 return true;
2532 def_bb = gimple_bb (stmt);
2534 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2536 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2537 if (gimple_code (use_stmt) == GIMPLE_PHI
2538 && (res = true))
2540 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
2542 if (scalar_close_phi_node_p (gsi_stmt (psi)))
2543 rewrite_close_phi_out_of_ssa (scop, &psi);
2544 else
2545 rewrite_phi_out_of_ssa (scop, &psi);
2548 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2549 if (gimple_code (use_stmt) != GIMPLE_PHI
2550 && def_bb != gimple_bb (use_stmt)
2551 && !is_gimple_debug (use_stmt)
2552 && (res = true))
2554 if (!zero_dim_array)
2556 zero_dim_array = create_zero_dim_array
2557 (SSA_NAME_VAR (def), "Cross_BB_scalar_dependence");
2558 insert_out_of_ssa_copy (scop, zero_dim_array, def,
2559 SSA_NAME_DEF_STMT (def));
2560 gsi_next (gsi);
2563 rewrite_cross_bb_scalar_dependence (scop, zero_dim_array,
2564 def, use_stmt);
2567 return res;
2570 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2572 static void
2573 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2575 basic_block bb;
2576 gimple_stmt_iterator psi;
2577 sese region = SCOP_REGION (scop);
2578 bool changed = false;
2580 /* Create an extra empty BB after the scop. */
2581 split_edge (SESE_EXIT (region));
2583 FOR_EACH_BB (bb)
2584 if (bb_in_sese_p (bb, region))
2585 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
2586 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
2588 if (changed)
2590 scev_reset_htab ();
2591 update_ssa (TODO_update_ssa);
2592 #ifdef ENABLE_CHECKING
2593 verify_loop_closed_ssa (true);
2594 #endif
2598 /* Returns the number of pbbs that are in loops contained in SCOP. */
2600 static int
2601 nb_pbbs_in_loops (scop_p scop)
2603 int i;
2604 poly_bb_p pbb;
2605 int res = 0;
2607 FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
2608 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2609 res++;
2611 return res;
2614 /* Return the number of data references in BB that write in
2615 memory. */
2617 static int
2618 nb_data_writes_in_bb (basic_block bb)
2620 int res = 0;
2621 gimple_stmt_iterator gsi;
2623 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2624 if (gimple_vdef (gsi_stmt (gsi)))
2625 res++;
2627 return res;
2630 /* Splits at STMT the basic block BB represented as PBB in the
2631 polyhedral form. */
2633 static edge
2634 split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2636 edge e1 = split_block (bb, stmt);
2637 new_pbb_from_pbb (scop, pbb, e1->dest);
2638 return e1;
2641 /* Splits STMT out of its current BB. This is done for reduction
2642 statements for which we want to ignore data dependences. */
2644 static basic_block
2645 split_reduction_stmt (scop_p scop, gimple stmt)
2647 basic_block bb = gimple_bb (stmt);
2648 poly_bb_p pbb = pbb_from_bb (bb);
2649 gimple_bb_p gbb = gbb_from_bb (bb);
2650 edge e1;
2651 int i;
2652 data_reference_p dr;
2654 /* Do not split basic blocks with no writes to memory: the reduction
2655 will be the only write to memory. */
2656 if (nb_data_writes_in_bb (bb) == 0)
2657 return bb;
2659 e1 = split_pbb (scop, pbb, bb, stmt);
2661 /* Split once more only when the reduction stmt is not the only one
2662 left in the original BB. */
2663 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2665 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2666 gsi_prev (&gsi);
2667 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2670 /* A part of the data references will end in a different basic block
2671 after the split: move the DRs from the original GBB to the newly
2672 created GBB1. */
2673 FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
2675 basic_block bb1 = gimple_bb (DR_STMT (dr));
2677 if (bb1 != bb)
2679 gimple_bb_p gbb1 = gbb_from_bb (bb1);
2680 VEC_safe_push (data_reference_p, heap, GBB_DATA_REFS (gbb1), dr);
2681 VEC_ordered_remove (data_reference_p, GBB_DATA_REFS (gbb), i);
2682 i--;
2686 return e1->dest;
2689 /* Return true when stmt is a reduction operation. */
2691 static inline bool
2692 is_reduction_operation_p (gimple stmt)
2694 enum tree_code code;
2696 gcc_assert (is_gimple_assign (stmt));
2697 code = gimple_assign_rhs_code (stmt);
2699 return flag_associative_math
2700 && commutative_tree_code (code)
2701 && associative_tree_code (code);
2704 /* Returns true when PHI contains an argument ARG. */
2706 static bool
2707 phi_contains_arg (gimple phi, tree arg)
2709 size_t i;
2711 for (i = 0; i < gimple_phi_num_args (phi); i++)
2712 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2713 return true;
2715 return false;
2718 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2720 static gimple
2721 follow_ssa_with_commutative_ops (tree arg, tree lhs)
2723 gimple stmt;
2725 if (TREE_CODE (arg) != SSA_NAME)
2726 return NULL;
2728 stmt = SSA_NAME_DEF_STMT (arg);
2730 if (gimple_code (stmt) == GIMPLE_NOP
2731 || gimple_code (stmt) == GIMPLE_CALL)
2732 return NULL;
2734 if (gimple_code (stmt) == GIMPLE_PHI)
2736 if (phi_contains_arg (stmt, lhs))
2737 return stmt;
2738 return NULL;
2741 if (!is_gimple_assign (stmt))
2742 return NULL;
2744 if (gimple_num_ops (stmt) == 2)
2745 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2747 if (is_reduction_operation_p (stmt))
2749 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2751 return res ? res :
2752 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2755 return NULL;
2758 /* Detect commutative and associative scalar reductions starting at
2759 the STMT. Return the phi node of the reduction cycle, or NULL. */
2761 static gimple
2762 detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
2763 VEC (gimple, heap) **in,
2764 VEC (gimple, heap) **out)
2766 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2768 if (!phi)
2769 return NULL;
2771 VEC_safe_push (gimple, heap, *in, stmt);
2772 VEC_safe_push (gimple, heap, *out, stmt);
2773 return phi;
2776 /* Detect commutative and associative scalar reductions starting at
2777 STMT. Return the phi node of the reduction cycle, or NULL. */
2779 static gimple
2780 detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
2781 VEC (gimple, heap) **out)
2783 tree lhs = gimple_assign_lhs (stmt);
2785 if (gimple_num_ops (stmt) == 2)
2786 return detect_commutative_reduction_arg (lhs, stmt,
2787 gimple_assign_rhs1 (stmt),
2788 in, out);
2790 if (is_reduction_operation_p (stmt))
2792 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2793 gimple_assign_rhs1 (stmt),
2794 in, out);
2795 return res ? res
2796 : detect_commutative_reduction_arg (lhs, stmt,
2797 gimple_assign_rhs2 (stmt),
2798 in, out);
2801 return NULL;
2804 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2806 static gimple
2807 follow_inital_value_to_phi (tree arg, tree lhs)
2809 gimple stmt;
2811 if (!arg || TREE_CODE (arg) != SSA_NAME)
2812 return NULL;
2814 stmt = SSA_NAME_DEF_STMT (arg);
2816 if (gimple_code (stmt) == GIMPLE_PHI
2817 && phi_contains_arg (stmt, lhs))
2818 return stmt;
2820 return NULL;
2824 /* Return the argument of the loop PHI that is the inital value coming
2825 from outside the loop. */
2827 static edge
2828 edge_initial_value_for_loop_phi (gimple phi)
2830 size_t i;
2832 for (i = 0; i < gimple_phi_num_args (phi); i++)
2834 edge e = gimple_phi_arg_edge (phi, i);
2836 if (loop_depth (e->src->loop_father)
2837 < loop_depth (e->dest->loop_father))
2838 return e;
2841 return NULL;
2844 /* Return the argument of the loop PHI that is the inital value coming
2845 from outside the loop. */
2847 static tree
2848 initial_value_for_loop_phi (gimple phi)
2850 size_t i;
2852 for (i = 0; i < gimple_phi_num_args (phi); i++)
2854 edge e = gimple_phi_arg_edge (phi, i);
2856 if (loop_depth (e->src->loop_father)
2857 < loop_depth (e->dest->loop_father))
2858 return gimple_phi_arg_def (phi, i);
2861 return NULL_TREE;
2864 /* Detect commutative and associative scalar reductions belonging to
2865 the SCOP starting at the loop closed phi node STMT. Return the phi
2866 node of the reduction cycle, or NULL. */
2868 static gimple
2869 detect_commutative_reduction (scop_p scop, gimple stmt, VEC (gimple, heap) **in,
2870 VEC (gimple, heap) **out)
2872 if (scalar_close_phi_node_p (stmt))
2874 tree arg = gimple_phi_arg_def (stmt, 0);
2875 gimple def, loop_phi;
2877 if (TREE_CODE (arg) != SSA_NAME)
2878 return NULL;
2880 /* Note that loop close phi nodes should have a single argument
2881 because we translated the representation into a canonical form
2882 before Graphite: see canonicalize_loop_closed_ssa_form. */
2883 gcc_assert (gimple_phi_num_args (stmt) == 1);
2885 def = SSA_NAME_DEF_STMT (arg);
2886 if (!stmt_in_sese_p (def, SCOP_REGION (scop)))
2887 return NULL;
2889 loop_phi = detect_commutative_reduction (scop, def, in, out);
2891 if (loop_phi)
2893 tree lhs = gimple_phi_result (stmt);
2894 tree init = initial_value_for_loop_phi (loop_phi);
2895 gimple phi = follow_inital_value_to_phi (init, lhs);
2897 VEC_safe_push (gimple, heap, *in, loop_phi);
2898 VEC_safe_push (gimple, heap, *out, stmt);
2899 return phi;
2901 else
2902 return NULL;
2905 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2906 return detect_commutative_reduction_assign (stmt, in, out);
2908 return NULL;
2911 /* Translate the scalar reduction statement STMT to an array RED
2912 knowing that its recursive phi node is LOOP_PHI. */
2914 static void
2915 translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2916 gimple stmt, gimple loop_phi)
2918 tree res = gimple_phi_result (loop_phi);
2919 gimple assign = gimple_build_assign (res, red);
2920 gimple_stmt_iterator gsi;
2922 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
2924 assign = gimple_build_assign (red, gimple_assign_lhs (stmt));
2925 gsi = gsi_for_stmt (stmt);
2926 gsi_next (&gsi);
2927 insert_stmts (scop, assign, NULL, gsi);
2930 /* Removes the PHI node and resets all the debug stmts that are using
2931 the PHI_RESULT. */
2933 static void
2934 remove_phi (gimple phi)
2936 imm_use_iterator imm_iter;
2937 tree def;
2938 use_operand_p use_p;
2939 gimple_stmt_iterator gsi;
2940 VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
2941 unsigned int i;
2942 gimple stmt;
2944 def = PHI_RESULT (phi);
2945 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2947 stmt = USE_STMT (use_p);
2949 if (is_gimple_debug (stmt))
2951 gimple_debug_bind_reset_value (stmt);
2952 VEC_safe_push (gimple, heap, update, stmt);
2956 FOR_EACH_VEC_ELT (gimple, update, i, stmt)
2957 update_stmt (stmt);
2959 VEC_free (gimple, heap, update);
2961 gsi = gsi_for_phi_node (phi);
2962 remove_phi_node (&gsi, false);
2965 /* Rewrite out of SSA the reduction described by the loop phi nodes
2966 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2967 levels like this:
2969 IN: stmt, loop_n, ..., loop_0
2970 OUT: stmt, close_n, ..., close_0
2972 the first element is the reduction statement, and the next elements
2973 are the loop and close phi nodes of each of the outer loops. */
2975 static void
2976 translate_scalar_reduction_to_array (scop_p scop,
2977 VEC (gimple, heap) *in,
2978 VEC (gimple, heap) *out)
2980 unsigned int i;
2981 gimple loop_phi;
2982 tree red = NULL_TREE;
2984 FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
2986 gimple close_phi = VEC_index (gimple, out, i);
2988 if (i == 0)
2990 gimple stmt = loop_phi;
2991 basic_block bb = split_reduction_stmt (scop, stmt);
2992 poly_bb_p pbb = pbb_from_bb (bb);
2993 PBB_IS_REDUCTION (pbb) = true;
2994 gcc_assert (close_phi == loop_phi);
2996 red = create_zero_dim_array
2997 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
2998 translate_scalar_reduction_to_array_for_stmt
2999 (scop, red, stmt, VEC_index (gimple, in, 1));
3000 continue;
3003 if (i == VEC_length (gimple, in) - 1)
3005 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi), red,
3006 close_phi);
3007 insert_out_of_ssa_copy_on_edge
3008 (scop, edge_initial_value_for_loop_phi (loop_phi),
3009 red, initial_value_for_loop_phi (loop_phi));
3012 remove_phi (loop_phi);
3013 remove_phi (close_phi);
3017 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3018 true when something has been changed. */
3020 static bool
3021 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3022 gimple close_phi)
3024 bool res;
3025 VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
3026 VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
3028 detect_commutative_reduction (scop, close_phi, &in, &out);
3029 res = VEC_length (gimple, in) > 0;
3030 if (res)
3031 translate_scalar_reduction_to_array (scop, in, out);
3033 VEC_free (gimple, heap, in);
3034 VEC_free (gimple, heap, out);
3035 return res;
3038 /* Rewrites all the commutative reductions from LOOP out of SSA.
3039 Returns true when something has been changed. */
3041 static bool
3042 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3043 loop_p loop)
3045 gimple_stmt_iterator gsi;
3046 edge exit = single_exit (loop);
3047 tree res;
3048 bool changed = false;
3050 if (!exit)
3051 return false;
3053 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3054 if ((res = gimple_phi_result (gsi_stmt (gsi)))
3055 && is_gimple_reg (res)
3056 && !scev_analyzable_p (res, SCOP_REGION (scop)))
3057 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
3058 (scop, gsi_stmt (gsi));
3060 return changed;
3063 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3065 static void
3066 rewrite_commutative_reductions_out_of_ssa (scop_p scop)
3068 loop_iterator li;
3069 loop_p loop;
3070 bool changed = false;
3071 sese region = SCOP_REGION (scop);
3073 FOR_EACH_LOOP (li, loop, 0)
3074 if (loop_in_sese_p (loop, region))
3075 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
3077 if (changed)
3079 scev_reset_htab ();
3080 gsi_commit_edge_inserts ();
3081 update_ssa (TODO_update_ssa);
3082 #ifdef ENABLE_CHECKING
3083 verify_loop_closed_ssa (true);
3084 #endif
3088 /* Java does not initialize long_long_integer_type_node. */
3089 #define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
3091 /* Can all ivs be represented by a signed integer?
3092 As CLooG might generate negative values in its expressions, signed loop ivs
3093 are required in the backend. */
3095 static bool
3096 scop_ivs_can_be_represented (scop_p scop)
3098 loop_iterator li;
3099 loop_p loop;
3100 gimple_stmt_iterator psi;
3102 FOR_EACH_LOOP (li, loop, 0)
3104 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3105 continue;
3107 for (psi = gsi_start_phis (loop->header);
3108 !gsi_end_p (psi); gsi_next (&psi))
3110 gimple phi = gsi_stmt (psi);
3111 tree res = PHI_RESULT (phi);
3112 tree type = TREE_TYPE (res);
3114 if (TYPE_UNSIGNED (type)
3115 && TYPE_PRECISION (type) >= TYPE_PRECISION (my_long_long))
3116 return false;
3120 return true;
3123 #undef my_long_long
3125 /* Builds the polyhedral representation for a SESE region. */
3127 void
3128 build_poly_scop (scop_p scop)
3130 sese region = SCOP_REGION (scop);
3131 graphite_dim_t max_dim;
3133 build_scop_bbs (scop);
3135 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3136 Once CLooG is fixed, remove this guard. Anyways, it makes no
3137 sense to optimize a scop containing only PBBs that do not belong
3138 to any loops. */
3139 if (nb_pbbs_in_loops (scop) == 0)
3140 return;
3142 if (!scop_ivs_can_be_represented (scop))
3143 return;
3145 build_sese_loop_nests (region);
3146 build_sese_conditions (region);
3147 find_scop_parameters (scop);
3149 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3150 if (scop_nb_params (scop) > max_dim)
3151 return;
3153 build_scop_iteration_domain (scop);
3154 build_scop_context (scop);
3155 add_conditions_to_constraints (scop);
3157 /* Rewrite out of SSA only after having translated the
3158 representation to the polyhedral representation to avoid scev
3159 analysis failures. That means that these functions will insert
3160 new data references that they create in the right place. */
3161 if (flag_associative_math)
3162 rewrite_commutative_reductions_out_of_ssa (scop);
3163 rewrite_reductions_out_of_ssa (scop);
3164 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3166 build_scop_drs (scop);
3167 scop_to_lst (scop);
3168 build_scop_scattering (scop);
3170 /* This SCoP has been translated to the polyhedral
3171 representation. */
3172 POLY_SCOP_P (scop) = true;
3174 #endif