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)
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/>. */
26 #include <isl/union_map.h>
27 #include <isl/constraint.h>
31 /* Since ISL-0.13, the extern is in val_gmp.h. */
32 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
35 #include <isl/val_gmp.h>
36 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
42 #include "coretypes.h"
46 #include "double-int.h"
54 #include "fold-const.h"
57 #include "hard-reg-set.h"
59 #include "dominance.h"
61 #include "basic-block.h"
62 #include "tree-ssa-alias.h"
63 #include "internal-fn.h"
64 #include "gimple-expr.h"
67 #include "gimple-iterator.h"
69 #include "gimplify-me.h"
70 #include "gimple-ssa.h"
72 #include "tree-phinodes.h"
73 #include "ssa-iterators.h"
74 #include "stringpool.h"
75 #include "tree-ssanames.h"
76 #include "tree-ssa-loop-manip.h"
77 #include "tree-ssa-loop-niter.h"
78 #include "tree-ssa-loop.h"
79 #include "tree-into-ssa.h"
80 #include "tree-pass.h"
82 #include "tree-chrec.h"
83 #include "tree-data-ref.h"
84 #include "tree-scalar-evolution.h"
87 #include "tree-ssa-propagate.h"
93 #include "statistics.h"
95 #include "fixed-value.h"
96 #include "insn-config.h"
101 #include "emit-rtl.h"
105 #include "graphite-poly.h"
106 #include "graphite-sese-to-poly.h"
109 /* Assigns to RES the value of the INTEGER_CST T. */
112 tree_int_to_gmp (tree t
, mpz_t res
)
114 wi::to_mpz (t
, res
, TYPE_SIGN (TREE_TYPE (t
)));
117 /* Returns the index of the PHI argument defined in the outermost
121 phi_arg_in_outermost_loop (gphi
*phi
)
123 loop_p loop
= gimple_bb (phi
)->loop_father
;
126 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
127 if (!flow_bb_inside_loop_p (loop
, gimple_phi_arg_edge (phi
, i
)->src
))
129 loop
= gimple_phi_arg_edge (phi
, i
)->src
->loop_father
;
136 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
137 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
140 remove_simple_copy_phi (gphi_iterator
*psi
)
142 gphi
*phi
= psi
->phi ();
143 tree res
= gimple_phi_result (phi
);
144 size_t entry
= phi_arg_in_outermost_loop (phi
);
145 tree init
= gimple_phi_arg_def (phi
, entry
);
146 gassign
*stmt
= gimple_build_assign (res
, init
);
147 edge e
= gimple_phi_arg_edge (phi
, entry
);
149 remove_phi_node (psi
, false);
150 gsi_insert_on_edge_immediate (e
, stmt
);
153 /* Removes an invariant phi node at position PSI by inserting on the
154 loop ENTRY edge the assignment RES = INIT. */
157 remove_invariant_phi (sese region
, gphi_iterator
*psi
)
159 gphi
*phi
= psi
->phi ();
160 loop_p loop
= loop_containing_stmt (phi
);
161 tree res
= gimple_phi_result (phi
);
162 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
163 size_t entry
= phi_arg_in_outermost_loop (phi
);
164 edge e
= gimple_phi_arg_edge (phi
, entry
);
167 gimple_seq stmts
= NULL
;
169 if (tree_contains_chrecs (scev
, NULL
))
170 scev
= gimple_phi_arg_def (phi
, entry
);
172 var
= force_gimple_operand (scev
, &stmts
, true, NULL_TREE
);
173 stmt
= gimple_build_assign (res
, var
);
174 remove_phi_node (psi
, false);
176 gimple_seq_add_stmt (&stmts
, stmt
);
177 gsi_insert_seq_on_edge (e
, stmts
);
178 gsi_commit_edge_inserts ();
179 SSA_NAME_DEF_STMT (res
) = stmt
;
182 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
185 simple_copy_phi_p (gphi
*phi
)
189 if (gimple_phi_num_args (phi
) != 2)
192 res
= gimple_phi_result (phi
);
193 return (res
== gimple_phi_arg_def (phi
, 0)
194 || res
== gimple_phi_arg_def (phi
, 1));
197 /* Returns true when the phi node at position PSI is a reduction phi
198 node in REGION. Otherwise moves the pointer PSI to the next phi to
202 reduction_phi_p (sese region
, gphi_iterator
*psi
)
205 gphi
*phi
= psi
->phi ();
206 tree res
= gimple_phi_result (phi
);
208 loop
= loop_containing_stmt (phi
);
210 if (simple_copy_phi_p (phi
))
212 /* PRE introduces phi nodes like these, for an example,
213 see id-5.f in the fortran graphite testsuite:
215 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
217 remove_simple_copy_phi (psi
);
221 if (scev_analyzable_p (res
, region
))
223 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
225 if (evolution_function_is_invariant_p (scev
, loop
->num
))
226 remove_invariant_phi (region
, psi
);
233 /* All the other cases are considered reductions. */
237 /* Store the GRAPHITE representation of BB. */
240 new_gimple_bb (basic_block bb
, vec
<data_reference_p
> drs
)
242 struct gimple_bb
*gbb
;
244 gbb
= XNEW (struct gimple_bb
);
247 GBB_DATA_REFS (gbb
) = drs
;
248 GBB_CONDITIONS (gbb
).create (0);
249 GBB_CONDITION_CASES (gbb
).create (0);
255 free_data_refs_aux (vec
<data_reference_p
> datarefs
)
258 struct data_reference
*dr
;
260 FOR_EACH_VEC_ELT (datarefs
, i
, dr
)
263 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
265 free (bap
->alias_set
);
274 free_gimple_bb (struct gimple_bb
*gbb
)
276 free_data_refs_aux (GBB_DATA_REFS (gbb
));
277 free_data_refs (GBB_DATA_REFS (gbb
));
279 GBB_CONDITIONS (gbb
).release ();
280 GBB_CONDITION_CASES (gbb
).release ();
281 GBB_BB (gbb
)->aux
= 0;
285 /* Deletes all gimple bbs in SCOP. */
288 remove_gbbs_in_scop (scop_p scop
)
293 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
294 free_gimple_bb (PBB_BLACK_BOX (pbb
));
297 /* Deletes all scops in SCOPS. */
300 free_scops (vec
<scop_p
> scops
)
305 FOR_EACH_VEC_ELT (scops
, i
, scop
)
307 remove_gbbs_in_scop (scop
);
308 free_sese (SCOP_REGION (scop
));
315 /* Same as outermost_loop_in_sese, returns the outermost loop
316 containing BB in REGION, but makes sure that the returned loop
317 belongs to the REGION, and so this returns the first loop in the
318 REGION when the loop containing BB does not belong to REGION. */
321 outermost_loop_in_sese_1 (sese region
, basic_block bb
)
323 loop_p nest
= outermost_loop_in_sese (region
, bb
);
325 if (loop_in_sese_p (nest
, region
))
328 /* When the basic block BB does not belong to a loop in the region,
329 return the first loop in the region. */
332 if (loop_in_sese_p (nest
, region
))
341 /* Generates a polyhedral black box only if the bb contains interesting
345 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
347 vec
<data_reference_p
> drs
;
349 sese region
= SCOP_REGION (scop
);
350 loop_p nest
= outermost_loop_in_sese_1 (region
, bb
);
351 gimple_stmt_iterator gsi
;
353 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
355 gimple stmt
= gsi_stmt (gsi
);
358 if (is_gimple_debug (stmt
))
361 loop
= loop_containing_stmt (stmt
);
362 if (!loop_in_sese_p (loop
, region
))
365 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
368 return new_gimple_bb (bb
, drs
);
371 /* Returns true if all predecessors of BB, that are not dominated by BB, are
372 marked in MAP. The predecessors dominated by BB are loop latches and will
373 be handled after BB. */
376 all_non_dominated_preds_marked_p (basic_block bb
, sbitmap map
)
381 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
382 if (!bitmap_bit_p (map
, e
->src
->index
)
383 && !dominated_by_p (CDI_DOMINATORS
, e
->src
, bb
))
389 /* Compare the depth of two basic_block's P1 and P2. */
392 compare_bb_depths (const void *p1
, const void *p2
)
394 const_basic_block
const bb1
= *(const_basic_block
const*)p1
;
395 const_basic_block
const bb2
= *(const_basic_block
const*)p2
;
396 int d1
= loop_depth (bb1
->loop_father
);
397 int d2
= loop_depth (bb2
->loop_father
);
408 /* Sort the basic blocks from DOM such that the first are the ones at
409 a deepest loop level. */
412 graphite_sort_dominated_info (vec
<basic_block
> dom
)
414 dom
.qsort (compare_bb_depths
);
417 /* Recursive helper function for build_scops_bbs. */
420 build_scop_bbs_1 (scop_p scop
, sbitmap visited
, basic_block bb
)
422 sese region
= SCOP_REGION (scop
);
423 vec
<basic_block
> dom
;
426 if (bitmap_bit_p (visited
, bb
->index
)
427 || !bb_in_sese_p (bb
, region
))
430 pbb
= new_poly_bb (scop
, try_generate_gimple_bb (scop
, bb
));
431 SCOP_BBS (scop
).safe_push (pbb
);
432 bitmap_set_bit (visited
, bb
->index
);
434 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
439 graphite_sort_dominated_info (dom
);
441 while (!dom
.is_empty ())
446 FOR_EACH_VEC_ELT (dom
, i
, dom_bb
)
447 if (all_non_dominated_preds_marked_p (dom_bb
, visited
))
449 build_scop_bbs_1 (scop
, visited
, dom_bb
);
450 dom
.unordered_remove (i
);
458 /* Gather the basic blocks belonging to the SCOP. */
461 build_scop_bbs (scop_p scop
)
463 sbitmap visited
= sbitmap_alloc (last_basic_block_for_fn (cfun
));
464 sese region
= SCOP_REGION (scop
);
466 bitmap_clear (visited
);
467 build_scop_bbs_1 (scop
, visited
, SESE_ENTRY_BB (region
));
468 sbitmap_free (visited
);
471 /* Return an ISL identifier for the polyhedral basic block PBB. */
474 isl_id_for_pbb (scop_p s
, poly_bb_p pbb
)
477 snprintf (name
, sizeof (name
), "S_%d", pbb_index (pbb
));
478 return isl_id_alloc (s
->ctx
, name
, pbb
);
481 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
482 We generate SCATTERING_DIMENSIONS scattering dimensions.
484 CLooG 0.15.0 and previous versions require, that all
485 scattering functions of one CloogProgram have the same number of
486 scattering dimensions, therefore we allow to specify it. This
487 should be removed in future versions of CLooG.
489 The scattering polyhedron consists of these dimensions: scattering,
490 loop_iterators, parameters.
494 | scattering_dimensions = 5
495 | used_scattering_dimensions = 3
503 | Scattering polyhedron:
505 | scattering: {s1, s2, s3, s4, s5}
506 | loop_iterators: {i}
507 | parameters: {p1, p2}
509 | s1 s2 s3 s4 s5 i p1 p2 1
510 | 1 0 0 0 0 0 0 0 -4 = 0
511 | 0 1 0 0 0 -1 0 0 0 = 0
512 | 0 0 1 0 0 0 0 0 -5 = 0 */
515 build_pbb_scattering_polyhedrons (isl_aff
*static_sched
,
516 poly_bb_p pbb
, int scattering_dimensions
)
519 int nb_iterators
= pbb_dim_iter_domain (pbb
);
520 int used_scattering_dimensions
= nb_iterators
* 2 + 1;
524 gcc_assert (scattering_dimensions
>= used_scattering_dimensions
);
526 dc
= isl_set_get_space (pbb
->domain
);
527 dm
= isl_space_add_dims (isl_space_from_domain (dc
),
528 isl_dim_out
, scattering_dimensions
);
529 pbb
->schedule
= isl_map_universe (dm
);
531 for (i
= 0; i
< scattering_dimensions
; i
++)
533 /* Textual order inside this loop. */
536 isl_constraint
*c
= isl_equality_alloc
537 (isl_local_space_from_space (isl_map_get_space (pbb
->schedule
)));
539 val
= isl_aff_get_coefficient_val (static_sched
, isl_dim_in
, i
/ 2);
541 val
= isl_val_neg (val
);
542 c
= isl_constraint_set_constant_val (c
, val
);
543 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
544 pbb
->schedule
= isl_map_add_constraint (pbb
->schedule
, c
);
547 /* Iterations of this loop. */
548 else /* if ((i % 2) == 1) */
550 int loop
= (i
- 1) / 2;
551 pbb
->schedule
= isl_map_equate (pbb
->schedule
, isl_dim_in
, loop
,
556 pbb
->transformed
= isl_map_copy (pbb
->schedule
);
559 /* Build for BB the static schedule.
561 The static schedule is a Dewey numbering of the abstract syntax
562 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
564 The following example informally defines the static schedule:
583 Static schedules for A to F:
596 build_scop_scattering (scop_p scop
)
600 gimple_bb_p previous_gbb
= NULL
;
601 isl_space
*dc
= isl_set_get_space (scop
->context
);
602 isl_aff
*static_sched
;
604 dc
= isl_space_add_dims (dc
, isl_dim_set
, number_of_loops (cfun
));
605 static_sched
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
607 /* We have to start schedules at 0 on the first component and
608 because we cannot compare_prefix_loops against a previous loop,
609 prefix will be equal to zero, and that index will be
610 incremented before copying. */
611 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
, 0, -1);
613 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
615 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
617 int nb_scat_dims
= pbb_dim_iter_domain (pbb
) * 2 + 1;
620 prefix
= nb_common_loops (SCOP_REGION (scop
), previous_gbb
, gbb
);
626 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
,
628 build_pbb_scattering_polyhedrons (static_sched
, pbb
, nb_scat_dims
);
631 isl_aff_free (static_sched
);
634 static isl_pw_aff
*extract_affine (scop_p
, tree
, __isl_take isl_space
*space
);
636 /* Extract an affine expression from the chain of recurrence E. */
639 extract_affine_chrec (scop_p s
, tree e
, __isl_take isl_space
*space
)
641 isl_pw_aff
*lhs
= extract_affine (s
, CHREC_LEFT (e
), isl_space_copy (space
));
642 isl_pw_aff
*rhs
= extract_affine (s
, CHREC_RIGHT (e
), isl_space_copy (space
));
643 isl_local_space
*ls
= isl_local_space_from_space (space
);
644 unsigned pos
= sese_loop_depth ((sese
) s
->region
, get_chrec_loop (e
)) - 1;
645 isl_aff
*loop
= isl_aff_set_coefficient_si
646 (isl_aff_zero_on_domain (ls
), isl_dim_in
, pos
, 1);
647 isl_pw_aff
*l
= isl_pw_aff_from_aff (loop
);
649 /* Before multiplying, make sure that the result is affine. */
650 gcc_assert (isl_pw_aff_is_cst (rhs
)
651 || isl_pw_aff_is_cst (l
));
653 return isl_pw_aff_add (lhs
, isl_pw_aff_mul (rhs
, l
));
656 /* Extract an affine expression from the mult_expr E. */
659 extract_affine_mul (scop_p s
, tree e
, __isl_take isl_space
*space
)
661 isl_pw_aff
*lhs
= extract_affine (s
, TREE_OPERAND (e
, 0),
662 isl_space_copy (space
));
663 isl_pw_aff
*rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
665 if (!isl_pw_aff_is_cst (lhs
)
666 && !isl_pw_aff_is_cst (rhs
))
668 isl_pw_aff_free (lhs
);
669 isl_pw_aff_free (rhs
);
673 return isl_pw_aff_mul (lhs
, rhs
);
676 /* Return an ISL identifier from the name of the ssa_name E. */
679 isl_id_for_ssa_name (scop_p s
, tree e
)
681 const char *name
= get_name (e
);
685 id
= isl_id_alloc (s
->ctx
, name
, e
);
689 snprintf (name1
, sizeof (name1
), "P_%d", SSA_NAME_VERSION (e
));
690 id
= isl_id_alloc (s
->ctx
, name1
, e
);
696 /* Return an ISL identifier for the data reference DR. */
699 isl_id_for_dr (scop_p s
, data_reference_p dr ATTRIBUTE_UNUSED
)
701 /* Data references all get the same isl_id. They need to be comparable
702 and are distinguished through the first dimension, which contains the
704 return isl_id_alloc (s
->ctx
, "", 0);
707 /* Extract an affine expression from the ssa_name E. */
710 extract_affine_name (scop_p s
, tree e
, __isl_take isl_space
*space
)
717 id
= isl_id_for_ssa_name (s
, e
);
718 dimension
= isl_space_find_dim_by_id (space
, isl_dim_param
, id
);
720 dom
= isl_set_universe (isl_space_copy (space
));
721 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
722 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, dimension
, 1);
723 return isl_pw_aff_alloc (dom
, aff
);
726 /* Extract an affine expression from the gmp constant G. */
729 extract_affine_gmp (mpz_t g
, __isl_take isl_space
*space
)
731 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
732 isl_aff
*aff
= isl_aff_zero_on_domain (ls
);
733 isl_set
*dom
= isl_set_universe (space
);
737 ct
= isl_aff_get_ctx (aff
);
738 v
= isl_val_int_from_gmp (ct
, g
);
739 aff
= isl_aff_add_constant_val (aff
, v
);
741 return isl_pw_aff_alloc (dom
, aff
);
744 /* Extract an affine expression from the integer_cst E. */
747 extract_affine_int (tree e
, __isl_take isl_space
*space
)
753 tree_int_to_gmp (e
, g
);
754 res
= extract_affine_gmp (g
, space
);
760 /* Compute pwaff mod 2^width. */
762 extern isl_ctx
*the_isl_ctx
;
765 wrap (isl_pw_aff
*pwaff
, unsigned width
)
769 mod
= isl_val_int_from_ui(the_isl_ctx
, width
);
770 mod
= isl_val_2exp (mod
);
771 pwaff
= isl_pw_aff_mod_val (pwaff
, mod
);
776 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
777 Otherwise returns -1. */
780 parameter_index_in_region_1 (tree name
, sese region
)
785 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
787 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
794 /* When the parameter NAME is in REGION, returns its index in
795 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
796 and returns the index of NAME. */
799 parameter_index_in_region (tree name
, sese region
)
803 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
805 i
= parameter_index_in_region_1 (name
, region
);
809 gcc_assert (SESE_ADD_PARAMS (region
));
811 i
= SESE_PARAMS (region
).length ();
812 SESE_PARAMS (region
).safe_push (name
);
816 /* Extract an affine expression from the tree E in the scop S. */
819 extract_affine (scop_p s
, tree e
, __isl_take isl_space
*space
)
821 isl_pw_aff
*lhs
, *rhs
, *res
;
824 if (e
== chrec_dont_know
) {
825 isl_space_free (space
);
829 switch (TREE_CODE (e
))
831 case POLYNOMIAL_CHREC
:
832 res
= extract_affine_chrec (s
, e
, space
);
836 res
= extract_affine_mul (s
, e
, space
);
840 case POINTER_PLUS_EXPR
:
841 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
842 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
843 res
= isl_pw_aff_add (lhs
, rhs
);
847 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
848 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
849 res
= isl_pw_aff_sub (lhs
, rhs
);
854 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
855 rhs
= extract_affine (s
, integer_minus_one_node
, space
);
856 res
= isl_pw_aff_mul (lhs
, rhs
);
860 gcc_assert (-1 != parameter_index_in_region_1 (e
, SCOP_REGION (s
)));
861 res
= extract_affine_name (s
, e
, space
);
865 res
= extract_affine_int (e
, space
);
866 /* No need to wrap a single integer. */
870 case NON_LVALUE_EXPR
:
871 res
= extract_affine (s
, TREE_OPERAND (e
, 0), space
);
879 type
= TREE_TYPE (e
);
880 if (TYPE_UNSIGNED (type
))
881 res
= wrap (res
, TYPE_PRECISION (type
));
886 /* In the context of sese S, scan the expression E and translate it to
887 a linear expression C. When parsing a symbolic multiplication, K
888 represents the constant multiplier of an expression containing
892 scan_tree_for_params (sese s
, tree e
)
894 if (e
== chrec_dont_know
)
897 switch (TREE_CODE (e
))
899 case POLYNOMIAL_CHREC
:
900 scan_tree_for_params (s
, CHREC_LEFT (e
));
904 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
905 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
907 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
911 case POINTER_PLUS_EXPR
:
913 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
914 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
920 case NON_LVALUE_EXPR
:
921 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
925 parameter_index_in_region (e
, s
);
938 /* Find parameters with respect to REGION in BB. We are looking in memory
939 access functions, conditions and loop bounds. */
942 find_params_in_bb (sese region
, gimple_bb_p gbb
)
948 loop_p loop
= GBB_BB (gbb
)->loop_father
;
950 /* Find parameters in the access functions of data references. */
951 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
952 for (j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
953 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
955 /* Find parameters in conditional statements. */
956 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
958 tree lhs
= scalar_evolution_in_region (region
, loop
,
959 gimple_cond_lhs (stmt
));
960 tree rhs
= scalar_evolution_in_region (region
, loop
,
961 gimple_cond_rhs (stmt
));
963 scan_tree_for_params (region
, lhs
);
964 scan_tree_for_params (region
, rhs
);
968 /* Record the parameters used in the SCOP. A variable is a parameter
969 in a scop if it does not vary during the execution of that scop. */
972 find_scop_parameters (scop_p scop
)
976 sese region
= SCOP_REGION (scop
);
980 /* Find the parameters used in the loop bounds. */
981 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
983 tree nb_iters
= number_of_latch_executions (loop
);
985 if (!chrec_contains_symbols (nb_iters
))
988 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
989 scan_tree_for_params (region
, nb_iters
);
992 /* Find the parameters used in data accesses. */
993 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
994 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
996 nbp
= sese_nb_params (region
);
997 scop_set_nb_params (scop
, nbp
);
998 SESE_ADD_PARAMS (region
) = false;
1002 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, nbp
, 0);
1004 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, e
)
1005 space
= isl_space_set_dim_id (space
, isl_dim_param
, i
,
1006 isl_id_for_ssa_name (scop
, e
));
1008 scop
->context
= isl_set_universe (space
);
1012 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1013 the constraints for the surrounding loops. */
1016 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
1018 isl_set
*outer
, isl_set
**doms
)
1020 tree nb_iters
= number_of_latch_executions (loop
);
1021 sese region
= SCOP_REGION (scop
);
1023 isl_set
*inner
= isl_set_copy (outer
);
1026 int pos
= isl_set_dim (outer
, isl_dim_set
);
1032 inner
= isl_set_add_dims (inner
, isl_dim_set
, 1);
1033 space
= isl_set_get_space (inner
);
1036 c
= isl_inequality_alloc
1037 (isl_local_space_from_space (isl_space_copy (space
)));
1038 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, 1);
1039 inner
= isl_set_add_constraint (inner
, c
);
1041 /* loop_i <= cst_nb_iters */
1042 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
1044 c
= isl_inequality_alloc
1045 (isl_local_space_from_space (isl_space_copy (space
)));
1046 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1047 tree_int_to_gmp (nb_iters
, g
);
1048 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1049 c
= isl_constraint_set_constant_val (c
, v
);
1050 inner
= isl_set_add_constraint (inner
, c
);
1053 /* loop_i <= expr_nb_iters */
1054 else if (!chrec_contains_undetermined (nb_iters
))
1059 isl_local_space
*ls
;
1063 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
1065 aff
= extract_affine (scop
, nb_iters
, isl_set_get_space (inner
));
1066 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff
));
1067 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1068 isl_set_dim (valid
, isl_dim_set
));
1069 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1071 ls
= isl_local_space_from_space (isl_space_copy (space
));
1072 al
= isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls
),
1073 isl_dim_in
, pos
, 1);
1074 le
= isl_pw_aff_le_set (isl_pw_aff_from_aff (al
),
1075 isl_pw_aff_copy (aff
));
1076 inner
= isl_set_intersect (inner
, le
);
1078 if (max_stmt_executions (loop
, &nit
))
1080 /* Insert in the context the constraints from the
1081 estimation of the number of iterations NIT and the
1082 symbolic number of iterations (involving parameter
1083 names) NB_ITERS. First, build the affine expression
1084 "NIT - NB_ITERS" and then say that it is positive,
1085 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1092 wi::to_mpz (nit
, g
, SIGNED
);
1093 mpz_sub_ui (g
, g
, 1);
1094 approx
= extract_affine_gmp (g
, isl_set_get_space (inner
));
1095 x
= isl_pw_aff_ge_set (approx
, aff
);
1096 x
= isl_set_project_out (x
, isl_dim_set
, 0,
1097 isl_set_dim (x
, isl_dim_set
));
1098 scop
->context
= isl_set_intersect (scop
->context
, x
);
1100 c
= isl_inequality_alloc
1101 (isl_local_space_from_space (isl_space_copy (space
)));
1102 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1103 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1105 c
= isl_constraint_set_constant_val (c
, v
);
1106 inner
= isl_set_add_constraint (inner
, c
);
1109 isl_pw_aff_free (aff
);
1114 if (loop
->inner
&& loop_in_sese_p (loop
->inner
, region
))
1115 build_loop_iteration_domains (scop
, loop
->inner
, nb
+ 1,
1116 isl_set_copy (inner
), doms
);
1120 && loop_in_sese_p (loop
->next
, region
))
1121 build_loop_iteration_domains (scop
, loop
->next
, nb
,
1122 isl_set_copy (outer
), doms
);
1124 doms
[loop
->num
] = inner
;
1126 isl_set_free (outer
);
1127 isl_space_free (space
);
1131 /* Returns a linear expression for tree T evaluated in PBB. */
1134 create_pw_aff_from_tree (poly_bb_p pbb
, tree t
)
1136 scop_p scop
= PBB_SCOP (pbb
);
1138 t
= scalar_evolution_in_region (SCOP_REGION (scop
), pbb_loop (pbb
), t
);
1139 gcc_assert (!automatically_generated_chrec_p (t
));
1141 return extract_affine (scop
, t
, isl_set_get_space (pbb
->domain
));
1144 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1145 operator. This allows us to invert the condition or to handle
1149 add_condition_to_pbb (poly_bb_p pbb
, gcond
*stmt
, enum tree_code code
)
1151 isl_pw_aff
*lhs
= create_pw_aff_from_tree (pbb
, gimple_cond_lhs (stmt
));
1152 isl_pw_aff
*rhs
= create_pw_aff_from_tree (pbb
, gimple_cond_rhs (stmt
));
1158 cond
= isl_pw_aff_lt_set (lhs
, rhs
);
1162 cond
= isl_pw_aff_gt_set (lhs
, rhs
);
1166 cond
= isl_pw_aff_le_set (lhs
, rhs
);
1170 cond
= isl_pw_aff_ge_set (lhs
, rhs
);
1174 cond
= isl_pw_aff_eq_set (lhs
, rhs
);
1178 cond
= isl_pw_aff_ne_set (lhs
, rhs
);
1182 isl_pw_aff_free (lhs
);
1183 isl_pw_aff_free (rhs
);
1187 cond
= isl_set_coalesce (cond
);
1188 cond
= isl_set_set_tuple_id (cond
, isl_set_get_tuple_id (pbb
->domain
));
1189 pbb
->domain
= isl_set_intersect (pbb
->domain
, cond
);
1192 /* Add conditions to the domain of PBB. */
1195 add_conditions_to_domain (poly_bb_p pbb
)
1199 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1201 if (GBB_CONDITIONS (gbb
).is_empty ())
1204 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1205 switch (gimple_code (stmt
))
1209 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
1210 enum tree_code code
= gimple_cond_code (cond_stmt
);
1212 /* The conditions for ELSE-branches are inverted. */
1213 if (!GBB_CONDITION_CASES (gbb
)[i
])
1214 code
= invert_tree_comparison (code
, false);
1216 add_condition_to_pbb (pbb
, cond_stmt
, code
);
1221 /* Switch statements are not supported right now - fall through. */
1229 /* Traverses all the GBBs of the SCOP and add their constraints to the
1230 iteration domains. */
1233 add_conditions_to_constraints (scop_p scop
)
1238 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1239 add_conditions_to_domain (pbb
);
1242 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1243 edge between BB and its predecessor is not a loop exit edge, and
1244 the last statement of the single predecessor is a COND_EXPR. */
1247 single_pred_cond_non_loop_exit (basic_block bb
)
1249 if (single_pred_p (bb
))
1251 edge e
= single_pred_edge (bb
);
1252 basic_block pred
= e
->src
;
1255 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
1258 stmt
= last_stmt (pred
);
1260 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
1261 return as_a
<gcond
*> (stmt
);
1267 class sese_dom_walker
: public dom_walker
1270 sese_dom_walker (cdi_direction
, sese
);
1272 virtual void before_dom_children (basic_block
);
1273 virtual void after_dom_children (basic_block
);
1276 auto_vec
<gimple
, 3> m_conditions
, m_cases
;
1280 sese_dom_walker::sese_dom_walker (cdi_direction direction
, sese region
)
1281 : dom_walker (direction
), m_region (region
)
1285 /* Call-back for dom_walk executed before visiting the dominated
1289 sese_dom_walker::before_dom_children (basic_block bb
)
1294 if (!bb_in_sese_p (bb
, m_region
))
1297 stmt
= single_pred_cond_non_loop_exit (bb
);
1301 edge e
= single_pred_edge (bb
);
1303 m_conditions
.safe_push (stmt
);
1305 if (e
->flags
& EDGE_TRUE_VALUE
)
1306 m_cases
.safe_push (stmt
);
1308 m_cases
.safe_push (NULL
);
1311 gbb
= gbb_from_bb (bb
);
1315 GBB_CONDITIONS (gbb
) = m_conditions
.copy ();
1316 GBB_CONDITION_CASES (gbb
) = m_cases
.copy ();
1320 /* Call-back for dom_walk executed after visiting the dominated
1324 sese_dom_walker::after_dom_children (basic_block bb
)
1326 if (!bb_in_sese_p (bb
, m_region
))
1329 if (single_pred_cond_non_loop_exit (bb
))
1331 m_conditions
.pop ();
1336 /* Add constraints on the possible values of parameter P from the type
1340 add_param_constraints (scop_p scop
, graphite_dim_t p
)
1342 tree parameter
= SESE_PARAMS (SCOP_REGION (scop
))[p
];
1343 tree type
= TREE_TYPE (parameter
);
1344 tree lb
= NULL_TREE
;
1345 tree ub
= NULL_TREE
;
1347 if (POINTER_TYPE_P (type
) || !TYPE_MIN_VALUE (type
))
1348 lb
= lower_bound_in_type (type
, type
);
1350 lb
= TYPE_MIN_VALUE (type
);
1352 if (POINTER_TYPE_P (type
) || !TYPE_MAX_VALUE (type
))
1353 ub
= upper_bound_in_type (type
, type
);
1355 ub
= TYPE_MAX_VALUE (type
);
1359 isl_space
*space
= isl_set_get_space (scop
->context
);
1364 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1366 tree_int_to_gmp (lb
, g
);
1367 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1368 v
= isl_val_neg (v
);
1370 c
= isl_constraint_set_constant_val (c
, v
);
1371 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, 1);
1373 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1378 isl_space
*space
= isl_set_get_space (scop
->context
);
1383 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1386 tree_int_to_gmp (ub
, g
);
1387 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1389 c
= isl_constraint_set_constant_val (c
, v
);
1390 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, -1);
1392 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1396 /* Build the context of the SCOP. The context usually contains extra
1397 constraints that are added to the iteration domains that constrain
1401 build_scop_context (scop_p scop
)
1403 graphite_dim_t p
, n
= scop_nb_params (scop
);
1405 for (p
= 0; p
< n
; p
++)
1406 add_param_constraints (scop
, p
);
1409 /* Build the iteration domains: the loops belonging to the current
1410 SCOP, and that vary for the execution of the current basic block.
1411 Returns false if there is no loop in SCOP. */
1414 build_scop_iteration_domain (scop_p scop
)
1417 sese region
= SCOP_REGION (scop
);
1420 int nb_loops
= number_of_loops (cfun
);
1421 isl_set
**doms
= XCNEWVEC (isl_set
*, nb_loops
);
1423 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1424 if (!loop_in_sese_p (loop_outer (loop
), region
))
1425 build_loop_iteration_domains (scop
, loop
, 0,
1426 isl_set_copy (scop
->context
), doms
);
1428 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1430 loop
= pbb_loop (pbb
);
1432 if (doms
[loop
->num
])
1433 pbb
->domain
= isl_set_copy (doms
[loop
->num
]);
1435 pbb
->domain
= isl_set_copy (scop
->context
);
1437 pbb
->domain
= isl_set_set_tuple_id (pbb
->domain
,
1438 isl_id_for_pbb (scop
, pbb
));
1441 for (i
= 0; i
< nb_loops
; i
++)
1443 isl_set_free (doms
[i
]);
1448 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1449 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1450 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1454 pdr_add_alias_set (isl_map
*acc
, data_reference_p dr
)
1457 int alias_set_num
= 0;
1458 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1460 if (bap
&& bap
->alias_set
)
1461 alias_set_num
= *(bap
->alias_set
);
1463 c
= isl_equality_alloc
1464 (isl_local_space_from_space (isl_map_get_space (acc
)));
1465 c
= isl_constraint_set_constant_si (c
, -alias_set_num
);
1466 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
1468 return isl_map_add_constraint (acc
, c
);
1471 /* Assign the affine expression INDEX to the output dimension POS of
1472 MAP and return the result. */
1475 set_index (isl_map
*map
, int pos
, isl_pw_aff
*index
)
1478 int len
= isl_map_dim (map
, isl_dim_out
);
1481 index_map
= isl_map_from_pw_aff (index
);
1482 index_map
= isl_map_insert_dims (index_map
, isl_dim_out
, 0, pos
);
1483 index_map
= isl_map_add_dims (index_map
, isl_dim_out
, len
- pos
- 1);
1485 id
= isl_map_get_tuple_id (map
, isl_dim_out
);
1486 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_out
, id
);
1487 id
= isl_map_get_tuple_id (map
, isl_dim_in
);
1488 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_in
, id
);
1490 return isl_map_intersect (map
, index_map
);
1493 /* Add to ACCESSES polyhedron equalities defining the access functions
1494 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1495 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1496 PBB is the poly_bb_p that contains the data reference DR. */
1499 pdr_add_memory_accesses (isl_map
*acc
, data_reference_p dr
, poly_bb_p pbb
)
1501 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1502 scop_p scop
= PBB_SCOP (pbb
);
1504 for (i
= 0; i
< nb_subscripts
; i
++)
1507 tree afn
= DR_ACCESS_FN (dr
, nb_subscripts
- 1 - i
);
1509 aff
= extract_affine (scop
, afn
,
1510 isl_space_domain (isl_map_get_space (acc
)));
1511 acc
= set_index (acc
, i
+ 1, aff
);
1517 /* Add constrains representing the size of the accessed data to the
1518 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1519 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1523 pdr_add_data_dimensions (isl_set
*extent
, scop_p scop
, data_reference_p dr
)
1525 tree ref
= DR_REF (dr
);
1526 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1528 for (i
= nb_subscripts
- 1; i
>= 0; i
--, ref
= TREE_OPERAND (ref
, 0))
1532 if (TREE_CODE (ref
) != ARRAY_REF
)
1535 low
= array_ref_low_bound (ref
);
1536 high
= array_ref_up_bound (ref
);
1538 /* XXX The PPL code dealt separately with
1539 subscript - low >= 0 and high - subscript >= 0 in case one of
1540 the two bounds isn't known. Do the same here? */
1542 if (tree_fits_shwi_p (low
)
1544 && tree_fits_shwi_p (high
)
1545 /* 1-element arrays at end of structures may extend over
1546 their declared size. */
1547 && !(array_at_struct_end_p (ref
)
1548 && operand_equal_p (low
, high
, 0)))
1552 isl_set
*univ
, *lbs
, *ubs
;
1556 isl_pw_aff
*lb
= extract_affine_int (low
, isl_set_get_space (extent
));
1557 isl_pw_aff
*ub
= extract_affine_int (high
, isl_set_get_space (extent
));
1560 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub
));
1561 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1562 isl_set_dim (valid
, isl_dim_set
));
1563 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1565 space
= isl_set_get_space (extent
);
1566 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
1567 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_in
, i
+ 1, 1);
1568 univ
= isl_set_universe (isl_space_domain (isl_aff_get_space (aff
)));
1569 index
= isl_pw_aff_alloc (univ
, aff
);
1571 id
= isl_set_get_tuple_id (extent
);
1572 lb
= isl_pw_aff_set_tuple_id (lb
, isl_dim_in
, isl_id_copy (id
));
1573 ub
= isl_pw_aff_set_tuple_id (ub
, isl_dim_in
, id
);
1575 /* low <= sub_i <= high */
1576 lbs
= isl_pw_aff_ge_set (isl_pw_aff_copy (index
), lb
);
1577 ubs
= isl_pw_aff_le_set (index
, ub
);
1578 extent
= isl_set_intersect (extent
, lbs
);
1579 extent
= isl_set_intersect (extent
, ubs
);
1586 /* Build data accesses for DR in PBB. */
1589 build_poly_dr (data_reference_p dr
, poly_bb_p pbb
)
1591 int dr_base_object_set
;
1594 scop_p scop
= PBB_SCOP (pbb
);
1597 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1598 int nb_out
= 1 + DR_NUM_DIMENSIONS (dr
);
1599 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1600 isl_dim_out
, nb_out
);
1602 acc
= isl_map_universe (space
);
1603 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, isl_id_for_dr (scop
, dr
));
1606 acc
= pdr_add_alias_set (acc
, dr
);
1607 acc
= pdr_add_memory_accesses (acc
, dr
, pbb
);
1610 isl_id
*id
= isl_id_for_dr (scop
, dr
);
1611 int nb
= 1 + DR_NUM_DIMENSIONS (dr
);
1612 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, 0, nb
);
1613 int alias_set_num
= 0;
1614 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1616 if (bap
&& bap
->alias_set
)
1617 alias_set_num
= *(bap
->alias_set
);
1619 space
= isl_space_set_tuple_id (space
, isl_dim_set
, id
);
1620 extent
= isl_set_nat_universe (space
);
1621 extent
= isl_set_fix_si (extent
, isl_dim_set
, 0, alias_set_num
);
1622 extent
= pdr_add_data_dimensions (extent
, scop
, dr
);
1625 gcc_assert (dr
->aux
);
1626 dr_base_object_set
= ((base_alias_pair
*)(dr
->aux
))->base_obj_set
;
1628 new_poly_dr (pbb
, dr_base_object_set
,
1629 DR_IS_READ (dr
) ? PDR_READ
: PDR_WRITE
,
1630 dr
, DR_NUM_DIMENSIONS (dr
), acc
, extent
);
1633 /* Write to FILE the alias graph of data references in DIMACS format. */
1636 write_alias_graph_to_ascii_dimacs (FILE *file
, char *comment
,
1637 vec
<data_reference_p
> drs
)
1639 int num_vertex
= drs
.length ();
1641 data_reference_p dr1
, dr2
;
1644 if (num_vertex
== 0)
1647 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1648 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1649 if (dr_may_alias_p (dr1
, dr2
, true))
1652 fprintf (file
, "$\n");
1655 fprintf (file
, "c %s\n", comment
);
1657 fprintf (file
, "p edge %d %d\n", num_vertex
, edge_num
);
1659 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1660 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1661 if (dr_may_alias_p (dr1
, dr2
, true))
1662 fprintf (file
, "e %d %d\n", i
+ 1, j
+ 1);
1667 /* Write to FILE the alias graph of data references in DOT format. */
1670 write_alias_graph_to_ascii_dot (FILE *file
, char *comment
,
1671 vec
<data_reference_p
> drs
)
1673 int num_vertex
= drs
.length ();
1674 data_reference_p dr1
, dr2
;
1677 if (num_vertex
== 0)
1680 fprintf (file
, "$\n");
1683 fprintf (file
, "c %s\n", comment
);
1685 /* First print all the vertices. */
1686 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1687 fprintf (file
, "n%d;\n", i
);
1689 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1690 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1691 if (dr_may_alias_p (dr1
, dr2
, true))
1692 fprintf (file
, "n%d n%d\n", i
, j
);
1697 /* Write to FILE the alias graph of data references in ECC format. */
1700 write_alias_graph_to_ascii_ecc (FILE *file
, char *comment
,
1701 vec
<data_reference_p
> drs
)
1703 int num_vertex
= drs
.length ();
1704 data_reference_p dr1
, dr2
;
1707 if (num_vertex
== 0)
1710 fprintf (file
, "$\n");
1713 fprintf (file
, "c %s\n", comment
);
1715 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1716 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1717 if (dr_may_alias_p (dr1
, dr2
, true))
1718 fprintf (file
, "%d %d\n", i
, j
);
1723 /* Check if DR1 and DR2 are in the same object set. */
1726 dr_same_base_object_p (const struct data_reference
*dr1
,
1727 const struct data_reference
*dr2
)
1729 return operand_equal_p (DR_BASE_OBJECT (dr1
), DR_BASE_OBJECT (dr2
), 0);
1732 /* Uses DFS component number as representative of alias-sets. Also tests for
1733 optimality by verifying if every connected component is a clique. Returns
1734 true (1) if the above test is true, and false (0) otherwise. */
1737 build_alias_set_optimal_p (vec
<data_reference_p
> drs
)
1739 int num_vertices
= drs
.length ();
1740 struct graph
*g
= new_graph (num_vertices
);
1741 data_reference_p dr1
, dr2
;
1743 int num_connected_components
;
1744 int v_indx1
, v_indx2
, num_vertices_in_component
;
1747 struct graph_edge
*e
;
1748 int this_component_is_clique
;
1749 int all_components_are_cliques
= 1;
1751 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1752 for (j
= i
+1; drs
.iterate (j
, &dr2
); j
++)
1753 if (dr_may_alias_p (dr1
, dr2
, true))
1759 all_vertices
= XNEWVEC (int, num_vertices
);
1760 vertices
= XNEWVEC (int, num_vertices
);
1761 for (i
= 0; i
< num_vertices
; i
++)
1762 all_vertices
[i
] = i
;
1764 num_connected_components
= graphds_dfs (g
, all_vertices
, num_vertices
,
1766 for (i
= 0; i
< g
->n_vertices
; i
++)
1768 data_reference_p dr
= drs
[i
];
1769 base_alias_pair
*bap
;
1771 gcc_assert (dr
->aux
);
1772 bap
= (base_alias_pair
*)(dr
->aux
);
1774 bap
->alias_set
= XNEW (int);
1775 *(bap
->alias_set
) = g
->vertices
[i
].component
+ 1;
1778 /* Verify if the DFS numbering results in optimal solution. */
1779 for (i
= 0; i
< num_connected_components
; i
++)
1781 num_vertices_in_component
= 0;
1782 /* Get all vertices whose DFS component number is the same as i. */
1783 for (j
= 0; j
< num_vertices
; j
++)
1784 if (g
->vertices
[j
].component
== i
)
1785 vertices
[num_vertices_in_component
++] = j
;
1787 /* Now test if the vertices in 'vertices' form a clique, by testing
1788 for edges among each pair. */
1789 this_component_is_clique
= 1;
1790 for (v_indx1
= 0; v_indx1
< num_vertices_in_component
; v_indx1
++)
1792 for (v_indx2
= v_indx1
+1; v_indx2
< num_vertices_in_component
; v_indx2
++)
1794 /* Check if the two vertices are connected by iterating
1795 through all the edges which have one of these are source. */
1796 e
= g
->vertices
[vertices
[v_indx2
]].pred
;
1799 if (e
->src
== vertices
[v_indx1
])
1805 this_component_is_clique
= 0;
1809 if (!this_component_is_clique
)
1810 all_components_are_cliques
= 0;
1814 free (all_vertices
);
1817 return all_components_are_cliques
;
1820 /* Group each data reference in DRS with its base object set num. */
1823 build_base_obj_set_for_drs (vec
<data_reference_p
> drs
)
1825 int num_vertex
= drs
.length ();
1826 struct graph
*g
= new_graph (num_vertex
);
1827 data_reference_p dr1
, dr2
;
1831 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1832 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1833 if (dr_same_base_object_p (dr1
, dr2
))
1839 queue
= XNEWVEC (int, num_vertex
);
1840 for (i
= 0; i
< num_vertex
; i
++)
1843 graphds_dfs (g
, queue
, num_vertex
, NULL
, true, NULL
);
1845 for (i
= 0; i
< g
->n_vertices
; i
++)
1847 data_reference_p dr
= drs
[i
];
1848 base_alias_pair
*bap
;
1850 gcc_assert (dr
->aux
);
1851 bap
= (base_alias_pair
*)(dr
->aux
);
1853 bap
->base_obj_set
= g
->vertices
[i
].component
+ 1;
1860 /* Build the data references for PBB. */
1863 build_pbb_drs (poly_bb_p pbb
)
1866 data_reference_p dr
;
1867 vec
<data_reference_p
> gbb_drs
= GBB_DATA_REFS (PBB_BLACK_BOX (pbb
));
1869 FOR_EACH_VEC_ELT (gbb_drs
, j
, dr
)
1870 build_poly_dr (dr
, pbb
);
1873 /* Dump to file the alias graphs for the data references in DRS. */
1876 dump_alias_graphs (vec
<data_reference_p
> drs
)
1879 FILE *file_dimacs
, *file_ecc
, *file_dot
;
1881 file_dimacs
= fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1884 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1885 current_function_name ());
1886 write_alias_graph_to_ascii_dimacs (file_dimacs
, comment
, drs
);
1887 fclose (file_dimacs
);
1890 file_ecc
= fopen ("/tmp/dr_alias_graph_ecc", "ab");
1893 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1894 current_function_name ());
1895 write_alias_graph_to_ascii_ecc (file_ecc
, comment
, drs
);
1899 file_dot
= fopen ("/tmp/dr_alias_graph_dot", "ab");
1902 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1903 current_function_name ());
1904 write_alias_graph_to_ascii_dot (file_dot
, comment
, drs
);
1909 /* Build data references in SCOP. */
1912 build_scop_drs (scop_p scop
)
1916 data_reference_p dr
;
1917 auto_vec
<data_reference_p
, 3> drs
;
1919 /* Remove all the PBBs that do not have data references: these basic
1920 blocks are not handled in the polyhedral representation. */
1921 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1922 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).is_empty ())
1924 free_gimple_bb (PBB_BLACK_BOX (pbb
));
1926 SCOP_BBS (scop
).ordered_remove (i
);
1930 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1931 for (j
= 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).iterate (j
, &dr
); j
++)
1934 FOR_EACH_VEC_ELT (drs
, i
, dr
)
1935 dr
->aux
= XNEW (base_alias_pair
);
1937 if (!build_alias_set_optimal_p (drs
))
1939 /* TODO: Add support when building alias set is not optimal. */
1943 build_base_obj_set_for_drs (drs
);
1945 /* When debugging, enable the following code. This cannot be used
1946 in production compilers. */
1948 dump_alias_graphs (drs
);
1952 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1953 build_pbb_drs (pbb
);
1956 /* Return a gsi at the position of the phi node STMT. */
1958 static gphi_iterator
1959 gsi_for_phi_node (gphi
*stmt
)
1962 basic_block bb
= gimple_bb (stmt
);
1964 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
1965 if (stmt
== psi
.phi ())
1972 /* Analyze all the data references of STMTS and add them to the
1973 GBB_DATA_REFS vector of BB. */
1976 analyze_drs_in_stmts (scop_p scop
, basic_block bb
, vec
<gimple
> stmts
)
1982 sese region
= SCOP_REGION (scop
);
1984 if (!bb_in_sese_p (bb
, region
))
1987 nest
= outermost_loop_in_sese_1 (region
, bb
);
1988 gbb
= gbb_from_bb (bb
);
1990 FOR_EACH_VEC_ELT (stmts
, i
, stmt
)
1994 if (is_gimple_debug (stmt
))
1997 loop
= loop_containing_stmt (stmt
);
1998 if (!loop_in_sese_p (loop
, region
))
2001 graphite_find_data_references_in_stmt (nest
, loop
, stmt
,
2002 &GBB_DATA_REFS (gbb
));
2006 /* Insert STMT at the end of the STMTS sequence and then insert the
2007 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2011 insert_stmts (scop_p scop
, gimple stmt
, gimple_seq stmts
,
2012 gimple_stmt_iterator insert_gsi
)
2014 gimple_stmt_iterator gsi
;
2015 auto_vec
<gimple
, 3> x
;
2017 gimple_seq_add_stmt (&stmts
, stmt
);
2018 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2019 x
.safe_push (gsi_stmt (gsi
));
2021 gsi_insert_seq_before (&insert_gsi
, stmts
, GSI_SAME_STMT
);
2022 analyze_drs_in_stmts (scop
, gsi_bb (insert_gsi
), x
);
2025 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2028 insert_out_of_ssa_copy (scop_p scop
, tree res
, tree expr
, gimple after_stmt
)
2031 gimple_stmt_iterator gsi
;
2032 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2033 gassign
*stmt
= gimple_build_assign (unshare_expr (res
), var
);
2034 auto_vec
<gimple
, 3> x
;
2036 gimple_seq_add_stmt (&stmts
, stmt
);
2037 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2038 x
.safe_push (gsi_stmt (gsi
));
2040 if (gimple_code (after_stmt
) == GIMPLE_PHI
)
2042 gsi
= gsi_after_labels (gimple_bb (after_stmt
));
2043 gsi_insert_seq_before (&gsi
, stmts
, GSI_NEW_STMT
);
2047 gsi
= gsi_for_stmt (after_stmt
);
2048 gsi_insert_seq_after (&gsi
, stmts
, GSI_NEW_STMT
);
2051 analyze_drs_in_stmts (scop
, gimple_bb (after_stmt
), x
);
2054 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2057 new_pbb_from_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
)
2059 vec
<data_reference_p
> drs
;
2061 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
2062 gimple_bb_p gbb1
= new_gimple_bb (bb
, drs
);
2063 poly_bb_p pbb1
= new_poly_bb (scop
, gbb1
);
2064 int index
, n
= SCOP_BBS (scop
).length ();
2066 /* The INDEX of PBB in SCOP_BBS. */
2067 for (index
= 0; index
< n
; index
++)
2068 if (SCOP_BBS (scop
)[index
] == pbb
)
2071 pbb1
->domain
= isl_set_copy (pbb
->domain
);
2072 pbb1
->domain
= isl_set_set_tuple_id (pbb1
->domain
,
2073 isl_id_for_pbb (scop
, pbb1
));
2075 GBB_PBB (gbb1
) = pbb1
;
2076 GBB_CONDITIONS (gbb1
) = GBB_CONDITIONS (gbb
).copy ();
2077 GBB_CONDITION_CASES (gbb1
) = GBB_CONDITION_CASES (gbb
).copy ();
2078 SCOP_BBS (scop
).safe_insert (index
+ 1, pbb1
);
2081 /* Insert on edge E the assignment "RES := EXPR". */
2084 insert_out_of_ssa_copy_on_edge (scop_p scop
, edge e
, tree res
, tree expr
)
2086 gimple_stmt_iterator gsi
;
2087 gimple_seq stmts
= NULL
;
2088 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2089 gimple stmt
= gimple_build_assign (unshare_expr (res
), var
);
2091 auto_vec
<gimple
, 3> x
;
2093 gimple_seq_add_stmt (&stmts
, stmt
);
2094 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2095 x
.safe_push (gsi_stmt (gsi
));
2097 gsi_insert_seq_on_edge (e
, stmts
);
2098 gsi_commit_edge_inserts ();
2099 bb
= gimple_bb (stmt
);
2101 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
2104 if (!gbb_from_bb (bb
))
2105 new_pbb_from_pbb (scop
, pbb_from_bb (e
->src
), bb
);
2107 analyze_drs_in_stmts (scop
, bb
, x
);
2110 /* Creates a zero dimension array of the same type as VAR. */
2113 create_zero_dim_array (tree var
, const char *base_name
)
2115 tree index_type
= build_index_type (integer_zero_node
);
2116 tree elt_type
= TREE_TYPE (var
);
2117 tree array_type
= build_array_type (elt_type
, index_type
);
2118 tree base
= create_tmp_var (array_type
, base_name
);
2120 return build4 (ARRAY_REF
, elt_type
, base
, integer_zero_node
, NULL_TREE
,
2124 /* Returns true when PHI is a loop close phi node. */
2127 scalar_close_phi_node_p (gimple phi
)
2129 if (gimple_code (phi
) != GIMPLE_PHI
2130 || virtual_operand_p (gimple_phi_result (phi
)))
2133 /* Note that loop close phi nodes should have a single argument
2134 because we translated the representation into a canonical form
2135 before Graphite: see canonicalize_loop_closed_ssa_form. */
2136 return (gimple_phi_num_args (phi
) == 1);
2139 /* For a definition DEF in REGION, propagates the expression EXPR in
2140 all the uses of DEF outside REGION. */
2143 propagate_expr_outside_region (tree def
, tree expr
, sese region
)
2145 imm_use_iterator imm_iter
;
2148 bool replaced_once
= false;
2150 gcc_assert (TREE_CODE (def
) == SSA_NAME
);
2152 expr
= force_gimple_operand (unshare_expr (expr
), &stmts
, true,
2155 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2156 if (!is_gimple_debug (use_stmt
)
2157 && !bb_in_sese_p (gimple_bb (use_stmt
), region
))
2160 use_operand_p use_p
;
2162 FOR_EACH_PHI_OR_STMT_USE (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2163 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0)
2164 && (replaced_once
= true))
2165 replace_exp (use_p
, expr
);
2167 update_stmt (use_stmt
);
2172 gsi_insert_seq_on_edge (SESE_ENTRY (region
), stmts
);
2173 gsi_commit_edge_inserts ();
2177 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2178 dimension array for it. */
2181 rewrite_close_phi_out_of_ssa (scop_p scop
, gimple_stmt_iterator
*psi
)
2183 sese region
= SCOP_REGION (scop
);
2184 gimple phi
= gsi_stmt (*psi
);
2185 tree res
= gimple_phi_result (phi
);
2186 basic_block bb
= gimple_bb (phi
);
2187 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
2188 tree arg
= gimple_phi_arg_def (phi
, 0);
2191 /* Note that loop close phi nodes should have a single argument
2192 because we translated the representation into a canonical form
2193 before Graphite: see canonicalize_loop_closed_ssa_form. */
2194 gcc_assert (gimple_phi_num_args (phi
) == 1);
2196 /* The phi node can be a non close phi node, when its argument is
2197 invariant, or a default definition. */
2198 if (is_gimple_min_invariant (arg
)
2199 || SSA_NAME_IS_DEFAULT_DEF (arg
))
2201 propagate_expr_outside_region (res
, arg
, region
);
2206 else if (gimple_bb (SSA_NAME_DEF_STMT (arg
))->loop_father
== bb
->loop_father
)
2208 propagate_expr_outside_region (res
, arg
, region
);
2209 stmt
= gimple_build_assign (res
, arg
);
2210 remove_phi_node (psi
, false);
2211 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2215 /* If res is scev analyzable and is not a scalar value, it is safe
2216 to ignore the close phi node: it will be code generated in the
2217 out of Graphite pass. */
2218 else if (scev_analyzable_p (res
, region
))
2220 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (res
));
2223 if (!loop_in_sese_p (loop
, region
))
2225 loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2226 scev
= scalar_evolution_in_region (region
, loop
, arg
);
2227 scev
= compute_overall_effect_of_inner_loop (loop
, scev
);
2230 scev
= scalar_evolution_in_region (region
, loop
, res
);
2232 if (tree_does_not_contain_chrecs (scev
))
2233 propagate_expr_outside_region (res
, scev
, region
);
2240 tree zero_dim_array
= create_zero_dim_array (res
, "Close_Phi");
2242 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2244 if (TREE_CODE (arg
) == SSA_NAME
)
2245 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2246 SSA_NAME_DEF_STMT (arg
));
2248 insert_out_of_ssa_copy_on_edge (scop
, single_pred_edge (bb
),
2249 zero_dim_array
, arg
);
2252 remove_phi_node (psi
, false);
2253 SSA_NAME_DEF_STMT (res
) = stmt
;
2255 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2258 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2259 dimension array for it. */
2262 rewrite_phi_out_of_ssa (scop_p scop
, gphi_iterator
*psi
)
2265 gphi
*phi
= psi
->phi ();
2266 basic_block bb
= gimple_bb (phi
);
2267 tree res
= gimple_phi_result (phi
);
2268 tree zero_dim_array
= create_zero_dim_array (res
, "phi_out_of_ssa");
2271 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2273 tree arg
= gimple_phi_arg_def (phi
, i
);
2274 edge e
= gimple_phi_arg_edge (phi
, i
);
2276 /* Avoid the insertion of code in the loop latch to please the
2277 pattern matching of the vectorizer. */
2278 if (TREE_CODE (arg
) == SSA_NAME
2279 && !SSA_NAME_IS_DEFAULT_DEF (arg
)
2280 && e
->src
== bb
->loop_father
->latch
)
2281 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2282 SSA_NAME_DEF_STMT (arg
));
2284 insert_out_of_ssa_copy_on_edge (scop
, e
, zero_dim_array
, arg
);
2287 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2288 remove_phi_node (psi
, false);
2289 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2292 /* Rewrite the degenerate phi node at position PSI from the degenerate
2293 form "x = phi (y, y, ..., y)" to "x = y". */
2296 rewrite_degenerate_phi (gphi_iterator
*psi
)
2300 gimple_stmt_iterator gsi
;
2301 gphi
*phi
= psi
->phi ();
2302 tree res
= gimple_phi_result (phi
);
2305 bb
= gimple_bb (phi
);
2306 rhs
= degenerate_phi_result (phi
);
2309 stmt
= gimple_build_assign (res
, rhs
);
2310 remove_phi_node (psi
, false);
2312 gsi
= gsi_after_labels (bb
);
2313 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2316 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2319 rewrite_reductions_out_of_ssa (scop_p scop
)
2323 sese region
= SCOP_REGION (scop
);
2325 FOR_EACH_BB_FN (bb
, cfun
)
2326 if (bb_in_sese_p (bb
, region
))
2327 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);)
2329 gphi
*phi
= psi
.phi ();
2331 if (virtual_operand_p (gimple_phi_result (phi
)))
2337 if (gimple_phi_num_args (phi
) > 1
2338 && degenerate_phi_result (phi
))
2339 rewrite_degenerate_phi (&psi
);
2341 else if (scalar_close_phi_node_p (phi
))
2342 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2344 else if (reduction_phi_p (region
, &psi
))
2345 rewrite_phi_out_of_ssa (scop
, &psi
);
2348 update_ssa (TODO_update_ssa
);
2349 #ifdef ENABLE_CHECKING
2350 verify_loop_closed_ssa (true);
2354 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2355 read from ZERO_DIM_ARRAY. */
2358 rewrite_cross_bb_scalar_dependence (scop_p scop
, tree zero_dim_array
,
2359 tree def
, gimple use_stmt
)
2364 use_operand_p use_p
;
2366 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
2368 name
= copy_ssa_name (def
);
2369 name_stmt
= gimple_build_assign (name
, zero_dim_array
);
2371 gimple_assign_set_lhs (name_stmt
, name
);
2372 insert_stmts (scop
, name_stmt
, NULL
, gsi_for_stmt (use_stmt
));
2374 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2375 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0))
2376 replace_exp (use_p
, name
);
2378 update_stmt (use_stmt
);
2381 /* For every definition DEF in the SCOP that is used outside the scop,
2382 insert a closing-scop definition in the basic block just after this
2386 handle_scalar_deps_crossing_scop_limits (scop_p scop
, tree def
, gimple stmt
)
2388 tree var
= create_tmp_reg (TREE_TYPE (def
));
2389 tree new_name
= make_ssa_name (var
, stmt
);
2390 bool needs_copy
= false;
2391 use_operand_p use_p
;
2392 imm_use_iterator imm_iter
;
2394 sese region
= SCOP_REGION (scop
);
2396 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2398 if (!bb_in_sese_p (gimple_bb (use_stmt
), region
))
2400 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
2402 SET_USE (use_p
, new_name
);
2404 update_stmt (use_stmt
);
2409 /* Insert in the empty BB just after the scop a use of DEF such
2410 that the rewrite of cross_bb_scalar_dependences won't insert
2411 arrays everywhere else. */
2414 gimple assign
= gimple_build_assign (new_name
, def
);
2415 gimple_stmt_iterator psi
= gsi_after_labels (SESE_EXIT (region
)->dest
);
2417 update_stmt (assign
);
2418 gsi_insert_before (&psi
, assign
, GSI_SAME_STMT
);
2422 /* Rewrite the scalar dependences crossing the boundary of the BB
2423 containing STMT with an array. Return true when something has been
2427 rewrite_cross_bb_scalar_deps (scop_p scop
, gimple_stmt_iterator
*gsi
)
2429 sese region
= SCOP_REGION (scop
);
2430 gimple stmt
= gsi_stmt (*gsi
);
2431 imm_use_iterator imm_iter
;
2434 tree zero_dim_array
= NULL_TREE
;
2438 switch (gimple_code (stmt
))
2441 def
= gimple_assign_lhs (stmt
);
2445 def
= gimple_call_lhs (stmt
);
2453 || !is_gimple_reg (def
))
2456 if (scev_analyzable_p (def
, region
))
2458 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (def
));
2459 tree scev
= scalar_evolution_in_region (region
, loop
, def
);
2461 if (tree_contains_chrecs (scev
, NULL
))
2464 propagate_expr_outside_region (def
, scev
, region
);
2468 def_bb
= gimple_bb (stmt
);
2470 handle_scalar_deps_crossing_scop_limits (scop
, def
, stmt
);
2472 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2473 if (gimple_code (use_stmt
) == GIMPLE_PHI
2476 gphi_iterator psi
= gsi_start_phis (gimple_bb (use_stmt
));
2478 if (scalar_close_phi_node_p (gsi_stmt (psi
)))
2479 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2481 rewrite_phi_out_of_ssa (scop
, &psi
);
2484 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2485 if (gimple_code (use_stmt
) != GIMPLE_PHI
2486 && def_bb
!= gimple_bb (use_stmt
)
2487 && !is_gimple_debug (use_stmt
)
2490 if (!zero_dim_array
)
2492 zero_dim_array
= create_zero_dim_array
2493 (def
, "Cross_BB_scalar_dependence");
2494 insert_out_of_ssa_copy (scop
, zero_dim_array
, def
,
2495 SSA_NAME_DEF_STMT (def
));
2499 rewrite_cross_bb_scalar_dependence (scop
, unshare_expr (zero_dim_array
),
2506 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2509 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop
)
2512 gimple_stmt_iterator psi
;
2513 sese region
= SCOP_REGION (scop
);
2514 bool changed
= false;
2516 /* Create an extra empty BB after the scop. */
2517 split_edge (SESE_EXIT (region
));
2519 FOR_EACH_BB_FN (bb
, cfun
)
2520 if (bb_in_sese_p (bb
, region
))
2521 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
2522 changed
|= rewrite_cross_bb_scalar_deps (scop
, &psi
);
2527 update_ssa (TODO_update_ssa
);
2528 #ifdef ENABLE_CHECKING
2529 verify_loop_closed_ssa (true);
2534 /* Returns the number of pbbs that are in loops contained in SCOP. */
2537 nb_pbbs_in_loops (scop_p scop
)
2543 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
2544 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), SCOP_REGION (scop
)))
2550 /* Return the number of data references in BB that write in
2554 nb_data_writes_in_bb (basic_block bb
)
2557 gimple_stmt_iterator gsi
;
2559 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2560 if (gimple_vdef (gsi_stmt (gsi
)))
2566 /* Splits at STMT the basic block BB represented as PBB in the
2570 split_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
, gimple stmt
)
2572 edge e1
= split_block (bb
, stmt
);
2573 new_pbb_from_pbb (scop
, pbb
, e1
->dest
);
2577 /* Splits STMT out of its current BB. This is done for reduction
2578 statements for which we want to ignore data dependences. */
2581 split_reduction_stmt (scop_p scop
, gimple stmt
)
2583 basic_block bb
= gimple_bb (stmt
);
2584 poly_bb_p pbb
= pbb_from_bb (bb
);
2585 gimple_bb_p gbb
= gbb_from_bb (bb
);
2588 data_reference_p dr
;
2590 /* Do not split basic blocks with no writes to memory: the reduction
2591 will be the only write to memory. */
2592 if (nb_data_writes_in_bb (bb
) == 0
2593 /* Or if we have already marked BB as a reduction. */
2594 || PBB_IS_REDUCTION (pbb_from_bb (bb
)))
2597 e1
= split_pbb (scop
, pbb
, bb
, stmt
);
2599 /* Split once more only when the reduction stmt is not the only one
2600 left in the original BB. */
2601 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb
)))
2603 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
2605 e1
= split_pbb (scop
, pbb
, bb
, gsi_stmt (gsi
));
2608 /* A part of the data references will end in a different basic block
2609 after the split: move the DRs from the original GBB to the newly
2611 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
2613 basic_block bb1
= gimple_bb (DR_STMT (dr
));
2617 gimple_bb_p gbb1
= gbb_from_bb (bb1
);
2618 GBB_DATA_REFS (gbb1
).safe_push (dr
);
2619 GBB_DATA_REFS (gbb
).ordered_remove (i
);
2627 /* Return true when stmt is a reduction operation. */
2630 is_reduction_operation_p (gimple stmt
)
2632 enum tree_code code
;
2634 gcc_assert (is_gimple_assign (stmt
));
2635 code
= gimple_assign_rhs_code (stmt
);
2637 return flag_associative_math
2638 && commutative_tree_code (code
)
2639 && associative_tree_code (code
);
2642 /* Returns true when PHI contains an argument ARG. */
2645 phi_contains_arg (gphi
*phi
, tree arg
)
2649 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2650 if (operand_equal_p (arg
, gimple_phi_arg_def (phi
, i
), 0))
2656 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2659 follow_ssa_with_commutative_ops (tree arg
, tree lhs
)
2663 if (TREE_CODE (arg
) != SSA_NAME
)
2666 stmt
= SSA_NAME_DEF_STMT (arg
);
2668 if (gimple_code (stmt
) == GIMPLE_NOP
2669 || gimple_code (stmt
) == GIMPLE_CALL
)
2672 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2674 if (phi_contains_arg (phi
, lhs
))
2679 if (!is_gimple_assign (stmt
))
2682 if (gimple_num_ops (stmt
) == 2)
2683 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2685 if (is_reduction_operation_p (stmt
))
2688 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2691 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt
), lhs
);
2697 /* Detect commutative and associative scalar reductions starting at
2698 the STMT. Return the phi node of the reduction cycle, or NULL. */
2701 detect_commutative_reduction_arg (tree lhs
, gimple stmt
, tree arg
,
2705 gphi
*phi
= follow_ssa_with_commutative_ops (arg
, lhs
);
2710 in
->safe_push (stmt
);
2711 out
->safe_push (stmt
);
2715 /* Detect commutative and associative scalar reductions starting at
2716 STMT. Return the phi node of the reduction cycle, or NULL. */
2719 detect_commutative_reduction_assign (gimple stmt
, vec
<gimple
> *in
,
2722 tree lhs
= gimple_assign_lhs (stmt
);
2724 if (gimple_num_ops (stmt
) == 2)
2725 return detect_commutative_reduction_arg (lhs
, stmt
,
2726 gimple_assign_rhs1 (stmt
),
2729 if (is_reduction_operation_p (stmt
))
2731 gphi
*res
= detect_commutative_reduction_arg (lhs
, stmt
,
2732 gimple_assign_rhs1 (stmt
),
2735 : detect_commutative_reduction_arg (lhs
, stmt
,
2736 gimple_assign_rhs2 (stmt
),
2743 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2746 follow_inital_value_to_phi (tree arg
, tree lhs
)
2750 if (!arg
|| TREE_CODE (arg
) != SSA_NAME
)
2753 stmt
= SSA_NAME_DEF_STMT (arg
);
2755 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2756 if (phi_contains_arg (phi
, lhs
))
2763 /* Return the argument of the loop PHI that is the initial value coming
2764 from outside the loop. */
2767 edge_initial_value_for_loop_phi (gphi
*phi
)
2771 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2773 edge e
= gimple_phi_arg_edge (phi
, i
);
2775 if (loop_depth (e
->src
->loop_father
)
2776 < loop_depth (e
->dest
->loop_father
))
2783 /* Return the argument of the loop PHI that is the initial value coming
2784 from outside the loop. */
2787 initial_value_for_loop_phi (gphi
*phi
)
2791 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2793 edge e
= gimple_phi_arg_edge (phi
, i
);
2795 if (loop_depth (e
->src
->loop_father
)
2796 < loop_depth (e
->dest
->loop_father
))
2797 return gimple_phi_arg_def (phi
, i
);
2803 /* Returns true when DEF is used outside the reduction cycle of
2807 used_outside_reduction (tree def
, gimple loop_phi
)
2809 use_operand_p use_p
;
2810 imm_use_iterator imm_iter
;
2811 loop_p loop
= loop_containing_stmt (loop_phi
);
2813 /* In LOOP, DEF should be used only in LOOP_PHI. */
2814 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2816 gimple stmt
= USE_STMT (use_p
);
2818 if (stmt
!= loop_phi
2819 && !is_gimple_debug (stmt
)
2820 && flow_bb_inside_loop_p (loop
, gimple_bb (stmt
)))
2827 /* Detect commutative and associative scalar reductions belonging to
2828 the SCOP starting at the loop closed phi node STMT. Return the phi
2829 node of the reduction cycle, or NULL. */
2832 detect_commutative_reduction (scop_p scop
, gimple stmt
, vec
<gimple
> *in
,
2835 if (scalar_close_phi_node_p (stmt
))
2838 gphi
*loop_phi
, *phi
, *close_phi
= as_a
<gphi
*> (stmt
);
2839 tree init
, lhs
, arg
= gimple_phi_arg_def (close_phi
, 0);
2841 if (TREE_CODE (arg
) != SSA_NAME
)
2844 /* Note that loop close phi nodes should have a single argument
2845 because we translated the representation into a canonical form
2846 before Graphite: see canonicalize_loop_closed_ssa_form. */
2847 gcc_assert (gimple_phi_num_args (close_phi
) == 1);
2849 def
= SSA_NAME_DEF_STMT (arg
);
2850 if (!stmt_in_sese_p (def
, SCOP_REGION (scop
))
2851 || !(loop_phi
= detect_commutative_reduction (scop
, def
, in
, out
)))
2854 lhs
= gimple_phi_result (close_phi
);
2855 init
= initial_value_for_loop_phi (loop_phi
);
2856 phi
= follow_inital_value_to_phi (init
, lhs
);
2858 if (phi
&& (used_outside_reduction (lhs
, phi
)
2859 || !has_single_use (gimple_phi_result (phi
))))
2862 in
->safe_push (loop_phi
);
2863 out
->safe_push (close_phi
);
2867 if (gimple_code (stmt
) == GIMPLE_ASSIGN
)
2868 return detect_commutative_reduction_assign (stmt
, in
, out
);
2873 /* Translate the scalar reduction statement STMT to an array RED
2874 knowing that its recursive phi node is LOOP_PHI. */
2877 translate_scalar_reduction_to_array_for_stmt (scop_p scop
, tree red
,
2878 gimple stmt
, gphi
*loop_phi
)
2880 tree res
= gimple_phi_result (loop_phi
);
2881 gassign
*assign
= gimple_build_assign (res
, unshare_expr (red
));
2882 gimple_stmt_iterator gsi
;
2884 insert_stmts (scop
, assign
, NULL
, gsi_after_labels (gimple_bb (loop_phi
)));
2886 assign
= gimple_build_assign (unshare_expr (red
), gimple_assign_lhs (stmt
));
2887 gsi
= gsi_for_stmt (stmt
);
2889 insert_stmts (scop
, assign
, NULL
, gsi
);
2892 /* Removes the PHI node and resets all the debug stmts that are using
2896 remove_phi (gphi
*phi
)
2898 imm_use_iterator imm_iter
;
2900 use_operand_p use_p
;
2901 gimple_stmt_iterator gsi
;
2902 auto_vec
<gimple
, 3> update
;
2906 def
= PHI_RESULT (phi
);
2907 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2909 stmt
= USE_STMT (use_p
);
2911 if (is_gimple_debug (stmt
))
2913 gimple_debug_bind_reset_value (stmt
);
2914 update
.safe_push (stmt
);
2918 FOR_EACH_VEC_ELT (update
, i
, stmt
)
2921 gsi
= gsi_for_phi_node (phi
);
2922 remove_phi_node (&gsi
, false);
2925 /* Helper function for for_each_index. For each INDEX of the data
2926 reference REF, returns true when its indices are valid in the loop
2927 nest LOOP passed in as DATA. */
2930 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED
, tree
*index
, void *data
)
2933 basic_block header
, def_bb
;
2936 if (TREE_CODE (*index
) != SSA_NAME
)
2939 loop
= *((loop_p
*) data
);
2940 header
= loop
->header
;
2941 stmt
= SSA_NAME_DEF_STMT (*index
);
2946 def_bb
= gimple_bb (stmt
);
2951 return dominated_by_p (CDI_DOMINATORS
, header
, def_bb
);
2954 /* When the result of a CLOSE_PHI is written to a memory location,
2955 return a pointer to that memory reference, otherwise return
2959 close_phi_written_to_memory (gphi
*close_phi
)
2961 imm_use_iterator imm_iter
;
2962 use_operand_p use_p
;
2964 tree res
, def
= gimple_phi_result (close_phi
);
2966 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2967 if ((stmt
= USE_STMT (use_p
))
2968 && gimple_code (stmt
) == GIMPLE_ASSIGN
2969 && (res
= gimple_assign_lhs (stmt
)))
2971 switch (TREE_CODE (res
))
2981 tree arg
= gimple_phi_arg_def (close_phi
, 0);
2982 loop_p nest
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2984 /* FIXME: this restriction is for id-{24,25}.f and
2985 could be handled by duplicating the computation of
2986 array indices before the loop of the close_phi. */
2987 if (for_each_index (&res
, dr_indices_valid_in_loop
, &nest
))
2999 /* Rewrite out of SSA the reduction described by the loop phi nodes
3000 IN, and the close phi nodes OUT. IN and OUT are structured by loop
3003 IN: stmt, loop_n, ..., loop_0
3004 OUT: stmt, close_n, ..., close_0
3006 the first element is the reduction statement, and the next elements
3007 are the loop and close phi nodes of each of the outer loops. */
3010 translate_scalar_reduction_to_array (scop_p scop
,
3015 unsigned int i
= out
.length () - 1;
3016 tree red
= close_phi_written_to_memory (as_a
<gphi
*> (out
[i
]));
3018 FOR_EACH_VEC_ELT (in
, i
, loop_stmt
)
3020 gimple close_stmt
= out
[i
];
3024 basic_block bb
= split_reduction_stmt (scop
, loop_stmt
);
3025 poly_bb_p pbb
= pbb_from_bb (bb
);
3026 PBB_IS_REDUCTION (pbb
) = true;
3027 gcc_assert (close_stmt
== loop_stmt
);
3030 red
= create_zero_dim_array
3031 (gimple_assign_lhs (loop_stmt
), "Commutative_Associative_Reduction");
3033 translate_scalar_reduction_to_array_for_stmt (scop
, red
, loop_stmt
,
3034 as_a
<gphi
*> (in
[1]));
3038 gphi
*loop_phi
= as_a
<gphi
*> (loop_stmt
);
3039 gphi
*close_phi
= as_a
<gphi
*> (close_stmt
);
3041 if (i
== in
.length () - 1)
3043 insert_out_of_ssa_copy (scop
, gimple_phi_result (close_phi
),
3044 unshare_expr (red
), close_phi
);
3045 insert_out_of_ssa_copy_on_edge
3046 (scop
, edge_initial_value_for_loop_phi (loop_phi
),
3047 unshare_expr (red
), initial_value_for_loop_phi (loop_phi
));
3050 remove_phi (loop_phi
);
3051 remove_phi (close_phi
);
3055 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3056 true when something has been changed. */
3059 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop
,
3063 auto_vec
<gimple
, 10> in
;
3064 auto_vec
<gimple
, 10> out
;
3066 detect_commutative_reduction (scop
, close_phi
, &in
, &out
);
3067 res
= in
.length () > 1;
3069 translate_scalar_reduction_to_array (scop
, in
, out
);
3074 /* Rewrites all the commutative reductions from LOOP out of SSA.
3075 Returns true when something has been changed. */
3078 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop
,
3082 edge exit
= single_exit (loop
);
3084 bool changed
= false;
3089 for (gsi
= gsi_start_phis (exit
->dest
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3090 if ((res
= gimple_phi_result (gsi
.phi ()))
3091 && !virtual_operand_p (res
)
3092 && !scev_analyzable_p (res
, SCOP_REGION (scop
)))
3093 changed
|= rewrite_commutative_reductions_out_of_ssa_close_phi
3099 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3102 rewrite_commutative_reductions_out_of_ssa (scop_p scop
)
3105 bool changed
= false;
3106 sese region
= SCOP_REGION (scop
);
3108 FOR_EACH_LOOP (loop
, 0)
3109 if (loop_in_sese_p (loop
, region
))
3110 changed
|= rewrite_commutative_reductions_out_of_ssa_loop (scop
, loop
);
3115 gsi_commit_edge_inserts ();
3116 update_ssa (TODO_update_ssa
);
3117 #ifdef ENABLE_CHECKING
3118 verify_loop_closed_ssa (true);
3123 /* Can all ivs be represented by a signed integer?
3124 As CLooG might generate negative values in its expressions, signed loop ivs
3125 are required in the backend. */
3128 scop_ivs_can_be_represented (scop_p scop
)
3134 FOR_EACH_LOOP (loop
, 0)
3136 if (!loop_in_sese_p (loop
, SCOP_REGION (scop
)))
3139 for (psi
= gsi_start_phis (loop
->header
);
3140 !gsi_end_p (psi
); gsi_next (&psi
))
3142 gphi
*phi
= psi
.phi ();
3143 tree res
= PHI_RESULT (phi
);
3144 tree type
= TREE_TYPE (res
);
3146 if (TYPE_UNSIGNED (type
)
3147 && TYPE_PRECISION (type
) >= TYPE_PRECISION (long_long_integer_type_node
))
3160 /* Builds the polyhedral representation for a SESE region. */
3163 build_poly_scop (scop_p scop
)
3165 sese region
= SCOP_REGION (scop
);
3166 graphite_dim_t max_dim
;
3168 build_scop_bbs (scop
);
3170 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3171 Once CLooG is fixed, remove this guard. Anyways, it makes no
3172 sense to optimize a scop containing only PBBs that do not belong
3174 if (nb_pbbs_in_loops (scop
) == 0)
3177 if (!scop_ivs_can_be_represented (scop
))
3180 if (flag_associative_math
)
3181 rewrite_commutative_reductions_out_of_ssa (scop
);
3183 build_sese_loop_nests (region
);
3184 /* Record all conditions in REGION. */
3185 sese_dom_walker (CDI_DOMINATORS
, region
).walk (cfun
->cfg
->x_entry_block_ptr
);
3186 find_scop_parameters (scop
);
3188 max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
3189 if (scop_nb_params (scop
) > max_dim
)
3192 build_scop_iteration_domain (scop
);
3193 build_scop_context (scop
);
3194 add_conditions_to_constraints (scop
);
3196 /* Rewrite out of SSA only after having translated the
3197 representation to the polyhedral representation to avoid scev
3198 analysis failures. That means that these functions will insert
3199 new data references that they create in the right place. */
3200 rewrite_reductions_out_of_ssa (scop
);
3201 rewrite_cross_bb_scalar_deps_out_of_ssa (scop
);
3203 build_scop_drs (scop
);
3205 build_scop_scattering (scop
);
3207 /* This SCoP has been translated to the polyhedral
3209 POLY_SCOP_P (scop
) = true;