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"
48 #include "fold-const.h"
51 #include "hard-reg-set.h"
53 #include "dominance.h"
55 #include "basic-block.h"
56 #include "tree-ssa-alias.h"
57 #include "internal-fn.h"
58 #include "gimple-expr.h"
61 #include "gimple-iterator.h"
63 #include "gimplify-me.h"
64 #include "gimple-ssa.h"
66 #include "tree-phinodes.h"
67 #include "ssa-iterators.h"
68 #include "stringpool.h"
69 #include "tree-ssanames.h"
70 #include "tree-ssa-loop-manip.h"
71 #include "tree-ssa-loop-niter.h"
72 #include "tree-ssa-loop.h"
73 #include "tree-into-ssa.h"
74 #include "tree-pass.h"
76 #include "tree-chrec.h"
77 #include "tree-data-ref.h"
78 #include "tree-scalar-evolution.h"
81 #include "tree-ssa-propagate.h"
86 #include "insn-config.h"
95 #include "graphite-poly.h"
96 #include "graphite-sese-to-poly.h"
99 /* Assigns to RES the value of the INTEGER_CST T. */
102 tree_int_to_gmp (tree t
, mpz_t res
)
104 wi::to_mpz (t
, res
, TYPE_SIGN (TREE_TYPE (t
)));
107 /* Returns the index of the PHI argument defined in the outermost
111 phi_arg_in_outermost_loop (gphi
*phi
)
113 loop_p loop
= gimple_bb (phi
)->loop_father
;
116 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
117 if (!flow_bb_inside_loop_p (loop
, gimple_phi_arg_edge (phi
, i
)->src
))
119 loop
= gimple_phi_arg_edge (phi
, i
)->src
->loop_father
;
126 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
127 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
130 remove_simple_copy_phi (gphi_iterator
*psi
)
132 gphi
*phi
= psi
->phi ();
133 tree res
= gimple_phi_result (phi
);
134 size_t entry
= phi_arg_in_outermost_loop (phi
);
135 tree init
= gimple_phi_arg_def (phi
, entry
);
136 gassign
*stmt
= gimple_build_assign (res
, init
);
137 edge e
= gimple_phi_arg_edge (phi
, entry
);
139 remove_phi_node (psi
, false);
140 gsi_insert_on_edge_immediate (e
, stmt
);
143 /* Removes an invariant phi node at position PSI by inserting on the
144 loop ENTRY edge the assignment RES = INIT. */
147 remove_invariant_phi (sese region
, gphi_iterator
*psi
)
149 gphi
*phi
= psi
->phi ();
150 loop_p loop
= loop_containing_stmt (phi
);
151 tree res
= gimple_phi_result (phi
);
152 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
153 size_t entry
= phi_arg_in_outermost_loop (phi
);
154 edge e
= gimple_phi_arg_edge (phi
, entry
);
157 gimple_seq stmts
= NULL
;
159 if (tree_contains_chrecs (scev
, NULL
))
160 scev
= gimple_phi_arg_def (phi
, entry
);
162 var
= force_gimple_operand (scev
, &stmts
, true, NULL_TREE
);
163 stmt
= gimple_build_assign (res
, var
);
164 remove_phi_node (psi
, false);
166 gimple_seq_add_stmt (&stmts
, stmt
);
167 gsi_insert_seq_on_edge (e
, stmts
);
168 gsi_commit_edge_inserts ();
169 SSA_NAME_DEF_STMT (res
) = stmt
;
172 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
175 simple_copy_phi_p (gphi
*phi
)
179 if (gimple_phi_num_args (phi
) != 2)
182 res
= gimple_phi_result (phi
);
183 return (res
== gimple_phi_arg_def (phi
, 0)
184 || res
== gimple_phi_arg_def (phi
, 1));
187 /* Returns true when the phi node at position PSI is a reduction phi
188 node in REGION. Otherwise moves the pointer PSI to the next phi to
192 reduction_phi_p (sese region
, gphi_iterator
*psi
)
195 gphi
*phi
= psi
->phi ();
196 tree res
= gimple_phi_result (phi
);
198 loop
= loop_containing_stmt (phi
);
200 if (simple_copy_phi_p (phi
))
202 /* PRE introduces phi nodes like these, for an example,
203 see id-5.f in the fortran graphite testsuite:
205 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
207 remove_simple_copy_phi (psi
);
211 if (scev_analyzable_p (res
, region
))
213 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
215 if (evolution_function_is_invariant_p (scev
, loop
->num
))
216 remove_invariant_phi (region
, psi
);
223 /* All the other cases are considered reductions. */
227 /* Store the GRAPHITE representation of BB. */
230 new_gimple_bb (basic_block bb
, vec
<data_reference_p
> drs
)
232 struct gimple_bb
*gbb
;
234 gbb
= XNEW (struct gimple_bb
);
237 GBB_DATA_REFS (gbb
) = drs
;
238 GBB_CONDITIONS (gbb
).create (0);
239 GBB_CONDITION_CASES (gbb
).create (0);
245 free_data_refs_aux (vec
<data_reference_p
> datarefs
)
248 struct data_reference
*dr
;
250 FOR_EACH_VEC_ELT (datarefs
, i
, dr
)
253 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
255 free (bap
->alias_set
);
264 free_gimple_bb (struct gimple_bb
*gbb
)
266 free_data_refs_aux (GBB_DATA_REFS (gbb
));
267 free_data_refs (GBB_DATA_REFS (gbb
));
269 GBB_CONDITIONS (gbb
).release ();
270 GBB_CONDITION_CASES (gbb
).release ();
271 GBB_BB (gbb
)->aux
= 0;
275 /* Deletes all gimple bbs in SCOP. */
278 remove_gbbs_in_scop (scop_p scop
)
283 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
284 free_gimple_bb (PBB_BLACK_BOX (pbb
));
287 /* Deletes all scops in SCOPS. */
290 free_scops (vec
<scop_p
> scops
)
295 FOR_EACH_VEC_ELT (scops
, i
, scop
)
297 remove_gbbs_in_scop (scop
);
298 free_sese (SCOP_REGION (scop
));
305 /* Same as outermost_loop_in_sese, returns the outermost loop
306 containing BB in REGION, but makes sure that the returned loop
307 belongs to the REGION, and so this returns the first loop in the
308 REGION when the loop containing BB does not belong to REGION. */
311 outermost_loop_in_sese_1 (sese region
, basic_block bb
)
313 loop_p nest
= outermost_loop_in_sese (region
, bb
);
315 if (loop_in_sese_p (nest
, region
))
318 /* When the basic block BB does not belong to a loop in the region,
319 return the first loop in the region. */
322 if (loop_in_sese_p (nest
, region
))
331 /* Generates a polyhedral black box only if the bb contains interesting
335 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
337 vec
<data_reference_p
> drs
;
339 sese region
= SCOP_REGION (scop
);
340 loop_p nest
= outermost_loop_in_sese_1 (region
, bb
);
341 gimple_stmt_iterator gsi
;
343 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
345 gimple stmt
= gsi_stmt (gsi
);
348 if (is_gimple_debug (stmt
))
351 loop
= loop_containing_stmt (stmt
);
352 if (!loop_in_sese_p (loop
, region
))
355 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
358 return new_gimple_bb (bb
, drs
);
361 /* Returns true if all predecessors of BB, that are not dominated by BB, are
362 marked in MAP. The predecessors dominated by BB are loop latches and will
363 be handled after BB. */
366 all_non_dominated_preds_marked_p (basic_block bb
, sbitmap map
)
371 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
372 if (!bitmap_bit_p (map
, e
->src
->index
)
373 && !dominated_by_p (CDI_DOMINATORS
, e
->src
, bb
))
379 /* Compare the depth of two basic_block's P1 and P2. */
382 compare_bb_depths (const void *p1
, const void *p2
)
384 const_basic_block
const bb1
= *(const_basic_block
const*)p1
;
385 const_basic_block
const bb2
= *(const_basic_block
const*)p2
;
386 int d1
= loop_depth (bb1
->loop_father
);
387 int d2
= loop_depth (bb2
->loop_father
);
398 /* Sort the basic blocks from DOM such that the first are the ones at
399 a deepest loop level. */
402 graphite_sort_dominated_info (vec
<basic_block
> dom
)
404 dom
.qsort (compare_bb_depths
);
407 /* Recursive helper function for build_scops_bbs. */
410 build_scop_bbs_1 (scop_p scop
, sbitmap visited
, basic_block bb
)
412 sese region
= SCOP_REGION (scop
);
413 vec
<basic_block
> dom
;
416 if (bitmap_bit_p (visited
, bb
->index
)
417 || !bb_in_sese_p (bb
, region
))
420 pbb
= new_poly_bb (scop
, try_generate_gimple_bb (scop
, bb
));
421 SCOP_BBS (scop
).safe_push (pbb
);
422 bitmap_set_bit (visited
, bb
->index
);
424 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
429 graphite_sort_dominated_info (dom
);
431 while (!dom
.is_empty ())
436 FOR_EACH_VEC_ELT (dom
, i
, dom_bb
)
437 if (all_non_dominated_preds_marked_p (dom_bb
, visited
))
439 build_scop_bbs_1 (scop
, visited
, dom_bb
);
440 dom
.unordered_remove (i
);
448 /* Gather the basic blocks belonging to the SCOP. */
451 build_scop_bbs (scop_p scop
)
453 sbitmap visited
= sbitmap_alloc (last_basic_block_for_fn (cfun
));
454 sese region
= SCOP_REGION (scop
);
456 bitmap_clear (visited
);
457 build_scop_bbs_1 (scop
, visited
, SESE_ENTRY_BB (region
));
458 sbitmap_free (visited
);
461 /* Return an ISL identifier for the polyhedral basic block PBB. */
464 isl_id_for_pbb (scop_p s
, poly_bb_p pbb
)
467 snprintf (name
, sizeof (name
), "S_%d", pbb_index (pbb
));
468 return isl_id_alloc (s
->ctx
, name
, pbb
);
471 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
472 We generate SCATTERING_DIMENSIONS scattering dimensions.
474 CLooG 0.15.0 and previous versions require, that all
475 scattering functions of one CloogProgram have the same number of
476 scattering dimensions, therefore we allow to specify it. This
477 should be removed in future versions of CLooG.
479 The scattering polyhedron consists of these dimensions: scattering,
480 loop_iterators, parameters.
484 | scattering_dimensions = 5
485 | used_scattering_dimensions = 3
493 | Scattering polyhedron:
495 | scattering: {s1, s2, s3, s4, s5}
496 | loop_iterators: {i}
497 | parameters: {p1, p2}
499 | s1 s2 s3 s4 s5 i p1 p2 1
500 | 1 0 0 0 0 0 0 0 -4 = 0
501 | 0 1 0 0 0 -1 0 0 0 = 0
502 | 0 0 1 0 0 0 0 0 -5 = 0 */
505 build_pbb_scattering_polyhedrons (isl_aff
*static_sched
,
506 poly_bb_p pbb
, int scattering_dimensions
)
509 int nb_iterators
= pbb_dim_iter_domain (pbb
);
510 int used_scattering_dimensions
= nb_iterators
* 2 + 1;
514 gcc_assert (scattering_dimensions
>= used_scattering_dimensions
);
516 dc
= isl_set_get_space (pbb
->domain
);
517 dm
= isl_space_add_dims (isl_space_from_domain (dc
),
518 isl_dim_out
, scattering_dimensions
);
519 pbb
->schedule
= isl_map_universe (dm
);
521 for (i
= 0; i
< scattering_dimensions
; i
++)
523 /* Textual order inside this loop. */
526 isl_constraint
*c
= isl_equality_alloc
527 (isl_local_space_from_space (isl_map_get_space (pbb
->schedule
)));
529 val
= isl_aff_get_coefficient_val (static_sched
, isl_dim_in
, i
/ 2);
531 val
= isl_val_neg (val
);
532 c
= isl_constraint_set_constant_val (c
, val
);
533 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
534 pbb
->schedule
= isl_map_add_constraint (pbb
->schedule
, c
);
537 /* Iterations of this loop. */
538 else /* if ((i % 2) == 1) */
540 int loop
= (i
- 1) / 2;
541 pbb
->schedule
= isl_map_equate (pbb
->schedule
, isl_dim_in
, loop
,
546 pbb
->transformed
= isl_map_copy (pbb
->schedule
);
549 /* Build for BB the static schedule.
551 The static schedule is a Dewey numbering of the abstract syntax
552 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
554 The following example informally defines the static schedule:
573 Static schedules for A to F:
586 build_scop_scattering (scop_p scop
)
590 gimple_bb_p previous_gbb
= NULL
;
591 isl_space
*dc
= isl_set_get_space (scop
->context
);
592 isl_aff
*static_sched
;
594 dc
= isl_space_add_dims (dc
, isl_dim_set
, number_of_loops (cfun
));
595 static_sched
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
597 /* We have to start schedules at 0 on the first component and
598 because we cannot compare_prefix_loops against a previous loop,
599 prefix will be equal to zero, and that index will be
600 incremented before copying. */
601 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
, 0, -1);
603 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
605 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
607 int nb_scat_dims
= pbb_dim_iter_domain (pbb
) * 2 + 1;
610 prefix
= nb_common_loops (SCOP_REGION (scop
), previous_gbb
, gbb
);
616 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
,
618 build_pbb_scattering_polyhedrons (static_sched
, pbb
, nb_scat_dims
);
621 isl_aff_free (static_sched
);
624 static isl_pw_aff
*extract_affine (scop_p
, tree
, __isl_take isl_space
*space
);
626 /* Extract an affine expression from the chain of recurrence E. */
629 extract_affine_chrec (scop_p s
, tree e
, __isl_take isl_space
*space
)
631 isl_pw_aff
*lhs
= extract_affine (s
, CHREC_LEFT (e
), isl_space_copy (space
));
632 isl_pw_aff
*rhs
= extract_affine (s
, CHREC_RIGHT (e
), isl_space_copy (space
));
633 isl_local_space
*ls
= isl_local_space_from_space (space
);
634 unsigned pos
= sese_loop_depth ((sese
) s
->region
, get_chrec_loop (e
)) - 1;
635 isl_aff
*loop
= isl_aff_set_coefficient_si
636 (isl_aff_zero_on_domain (ls
), isl_dim_in
, pos
, 1);
637 isl_pw_aff
*l
= isl_pw_aff_from_aff (loop
);
639 /* Before multiplying, make sure that the result is affine. */
640 gcc_assert (isl_pw_aff_is_cst (rhs
)
641 || isl_pw_aff_is_cst (l
));
643 return isl_pw_aff_add (lhs
, isl_pw_aff_mul (rhs
, l
));
646 /* Extract an affine expression from the mult_expr E. */
649 extract_affine_mul (scop_p s
, tree e
, __isl_take isl_space
*space
)
651 isl_pw_aff
*lhs
= extract_affine (s
, TREE_OPERAND (e
, 0),
652 isl_space_copy (space
));
653 isl_pw_aff
*rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
655 if (!isl_pw_aff_is_cst (lhs
)
656 && !isl_pw_aff_is_cst (rhs
))
658 isl_pw_aff_free (lhs
);
659 isl_pw_aff_free (rhs
);
663 return isl_pw_aff_mul (lhs
, rhs
);
666 /* Return an ISL identifier from the name of the ssa_name E. */
669 isl_id_for_ssa_name (scop_p s
, tree e
)
671 const char *name
= get_name (e
);
675 id
= isl_id_alloc (s
->ctx
, name
, e
);
679 snprintf (name1
, sizeof (name1
), "P_%d", SSA_NAME_VERSION (e
));
680 id
= isl_id_alloc (s
->ctx
, name1
, e
);
686 /* Return an ISL identifier for the data reference DR. */
689 isl_id_for_dr (scop_p s
, data_reference_p dr ATTRIBUTE_UNUSED
)
691 /* Data references all get the same isl_id. They need to be comparable
692 and are distinguished through the first dimension, which contains the
694 return isl_id_alloc (s
->ctx
, "", 0);
697 /* Extract an affine expression from the ssa_name E. */
700 extract_affine_name (scop_p s
, tree e
, __isl_take isl_space
*space
)
707 id
= isl_id_for_ssa_name (s
, e
);
708 dimension
= isl_space_find_dim_by_id (space
, isl_dim_param
, id
);
710 dom
= isl_set_universe (isl_space_copy (space
));
711 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
712 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, dimension
, 1);
713 return isl_pw_aff_alloc (dom
, aff
);
716 /* Extract an affine expression from the gmp constant G. */
719 extract_affine_gmp (mpz_t g
, __isl_take isl_space
*space
)
721 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
722 isl_aff
*aff
= isl_aff_zero_on_domain (ls
);
723 isl_set
*dom
= isl_set_universe (space
);
727 ct
= isl_aff_get_ctx (aff
);
728 v
= isl_val_int_from_gmp (ct
, g
);
729 aff
= isl_aff_add_constant_val (aff
, v
);
731 return isl_pw_aff_alloc (dom
, aff
);
734 /* Extract an affine expression from the integer_cst E. */
737 extract_affine_int (tree e
, __isl_take isl_space
*space
)
743 tree_int_to_gmp (e
, g
);
744 res
= extract_affine_gmp (g
, space
);
750 /* Compute pwaff mod 2^width. */
752 extern isl_ctx
*the_isl_ctx
;
755 wrap (isl_pw_aff
*pwaff
, unsigned width
)
759 mod
= isl_val_int_from_ui(the_isl_ctx
, width
);
760 mod
= isl_val_2exp (mod
);
761 pwaff
= isl_pw_aff_mod_val (pwaff
, mod
);
766 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
767 Otherwise returns -1. */
770 parameter_index_in_region_1 (tree name
, sese region
)
775 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
777 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
784 /* When the parameter NAME is in REGION, returns its index in
785 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
786 and returns the index of NAME. */
789 parameter_index_in_region (tree name
, sese region
)
793 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
795 i
= parameter_index_in_region_1 (name
, region
);
799 gcc_assert (SESE_ADD_PARAMS (region
));
801 i
= SESE_PARAMS (region
).length ();
802 SESE_PARAMS (region
).safe_push (name
);
806 /* Extract an affine expression from the tree E in the scop S. */
809 extract_affine (scop_p s
, tree e
, __isl_take isl_space
*space
)
811 isl_pw_aff
*lhs
, *rhs
, *res
;
814 if (e
== chrec_dont_know
) {
815 isl_space_free (space
);
819 switch (TREE_CODE (e
))
821 case POLYNOMIAL_CHREC
:
822 res
= extract_affine_chrec (s
, e
, space
);
826 res
= extract_affine_mul (s
, e
, space
);
830 case POINTER_PLUS_EXPR
:
831 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
832 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
833 res
= isl_pw_aff_add (lhs
, rhs
);
837 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
838 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
839 res
= isl_pw_aff_sub (lhs
, rhs
);
844 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
845 rhs
= extract_affine (s
, integer_minus_one_node
, space
);
846 res
= isl_pw_aff_mul (lhs
, rhs
);
850 gcc_assert (-1 != parameter_index_in_region_1 (e
, SCOP_REGION (s
)));
851 res
= extract_affine_name (s
, e
, space
);
855 res
= extract_affine_int (e
, space
);
856 /* No need to wrap a single integer. */
860 case NON_LVALUE_EXPR
:
861 res
= extract_affine (s
, TREE_OPERAND (e
, 0), space
);
869 type
= TREE_TYPE (e
);
870 if (TYPE_UNSIGNED (type
))
871 res
= wrap (res
, TYPE_PRECISION (type
));
876 /* In the context of sese S, scan the expression E and translate it to
877 a linear expression C. When parsing a symbolic multiplication, K
878 represents the constant multiplier of an expression containing
882 scan_tree_for_params (sese s
, tree e
)
884 if (e
== chrec_dont_know
)
887 switch (TREE_CODE (e
))
889 case POLYNOMIAL_CHREC
:
890 scan_tree_for_params (s
, CHREC_LEFT (e
));
894 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
895 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
897 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
901 case POINTER_PLUS_EXPR
:
903 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
904 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
910 case NON_LVALUE_EXPR
:
911 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
915 parameter_index_in_region (e
, s
);
928 /* Find parameters with respect to REGION in BB. We are looking in memory
929 access functions, conditions and loop bounds. */
932 find_params_in_bb (sese region
, gimple_bb_p gbb
)
938 loop_p loop
= GBB_BB (gbb
)->loop_father
;
940 /* Find parameters in the access functions of data references. */
941 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
942 for (j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
943 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
945 /* Find parameters in conditional statements. */
946 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
948 tree lhs
= scalar_evolution_in_region (region
, loop
,
949 gimple_cond_lhs (stmt
));
950 tree rhs
= scalar_evolution_in_region (region
, loop
,
951 gimple_cond_rhs (stmt
));
953 scan_tree_for_params (region
, lhs
);
954 scan_tree_for_params (region
, rhs
);
958 /* Record the parameters used in the SCOP. A variable is a parameter
959 in a scop if it does not vary during the execution of that scop. */
962 find_scop_parameters (scop_p scop
)
966 sese region
= SCOP_REGION (scop
);
970 /* Find the parameters used in the loop bounds. */
971 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
973 tree nb_iters
= number_of_latch_executions (loop
);
975 if (!chrec_contains_symbols (nb_iters
))
978 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
979 scan_tree_for_params (region
, nb_iters
);
982 /* Find the parameters used in data accesses. */
983 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
984 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
986 nbp
= sese_nb_params (region
);
987 scop_set_nb_params (scop
, nbp
);
988 SESE_ADD_PARAMS (region
) = false;
992 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, nbp
, 0);
994 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, e
)
995 space
= isl_space_set_dim_id (space
, isl_dim_param
, i
,
996 isl_id_for_ssa_name (scop
, e
));
998 scop
->context
= isl_set_universe (space
);
1002 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1003 the constraints for the surrounding loops. */
1006 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
1008 isl_set
*outer
, isl_set
**doms
)
1010 tree nb_iters
= number_of_latch_executions (loop
);
1011 sese region
= SCOP_REGION (scop
);
1013 isl_set
*inner
= isl_set_copy (outer
);
1016 int pos
= isl_set_dim (outer
, isl_dim_set
);
1022 inner
= isl_set_add_dims (inner
, isl_dim_set
, 1);
1023 space
= isl_set_get_space (inner
);
1026 c
= isl_inequality_alloc
1027 (isl_local_space_from_space (isl_space_copy (space
)));
1028 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, 1);
1029 inner
= isl_set_add_constraint (inner
, c
);
1031 /* loop_i <= cst_nb_iters */
1032 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
1034 c
= isl_inequality_alloc
1035 (isl_local_space_from_space (isl_space_copy (space
)));
1036 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1037 tree_int_to_gmp (nb_iters
, g
);
1038 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1039 c
= isl_constraint_set_constant_val (c
, v
);
1040 inner
= isl_set_add_constraint (inner
, c
);
1043 /* loop_i <= expr_nb_iters */
1044 else if (!chrec_contains_undetermined (nb_iters
))
1049 isl_local_space
*ls
;
1053 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
1055 aff
= extract_affine (scop
, nb_iters
, isl_set_get_space (inner
));
1056 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff
));
1057 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1058 isl_set_dim (valid
, isl_dim_set
));
1059 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1061 ls
= isl_local_space_from_space (isl_space_copy (space
));
1062 al
= isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls
),
1063 isl_dim_in
, pos
, 1);
1064 le
= isl_pw_aff_le_set (isl_pw_aff_from_aff (al
),
1065 isl_pw_aff_copy (aff
));
1066 inner
= isl_set_intersect (inner
, le
);
1068 if (max_stmt_executions (loop
, &nit
))
1070 /* Insert in the context the constraints from the
1071 estimation of the number of iterations NIT and the
1072 symbolic number of iterations (involving parameter
1073 names) NB_ITERS. First, build the affine expression
1074 "NIT - NB_ITERS" and then say that it is positive,
1075 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1082 wi::to_mpz (nit
, g
, SIGNED
);
1083 mpz_sub_ui (g
, g
, 1);
1084 approx
= extract_affine_gmp (g
, isl_set_get_space (inner
));
1085 x
= isl_pw_aff_ge_set (approx
, aff
);
1086 x
= isl_set_project_out (x
, isl_dim_set
, 0,
1087 isl_set_dim (x
, isl_dim_set
));
1088 scop
->context
= isl_set_intersect (scop
->context
, x
);
1090 c
= isl_inequality_alloc
1091 (isl_local_space_from_space (isl_space_copy (space
)));
1092 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1093 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1095 c
= isl_constraint_set_constant_val (c
, v
);
1096 inner
= isl_set_add_constraint (inner
, c
);
1099 isl_pw_aff_free (aff
);
1104 if (loop
->inner
&& loop_in_sese_p (loop
->inner
, region
))
1105 build_loop_iteration_domains (scop
, loop
->inner
, nb
+ 1,
1106 isl_set_copy (inner
), doms
);
1110 && loop_in_sese_p (loop
->next
, region
))
1111 build_loop_iteration_domains (scop
, loop
->next
, nb
,
1112 isl_set_copy (outer
), doms
);
1114 doms
[loop
->num
] = inner
;
1116 isl_set_free (outer
);
1117 isl_space_free (space
);
1121 /* Returns a linear expression for tree T evaluated in PBB. */
1124 create_pw_aff_from_tree (poly_bb_p pbb
, tree t
)
1126 scop_p scop
= PBB_SCOP (pbb
);
1128 t
= scalar_evolution_in_region (SCOP_REGION (scop
), pbb_loop (pbb
), t
);
1129 gcc_assert (!automatically_generated_chrec_p (t
));
1131 return extract_affine (scop
, t
, isl_set_get_space (pbb
->domain
));
1134 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1135 operator. This allows us to invert the condition or to handle
1139 add_condition_to_pbb (poly_bb_p pbb
, gcond
*stmt
, enum tree_code code
)
1141 isl_pw_aff
*lhs
= create_pw_aff_from_tree (pbb
, gimple_cond_lhs (stmt
));
1142 isl_pw_aff
*rhs
= create_pw_aff_from_tree (pbb
, gimple_cond_rhs (stmt
));
1148 cond
= isl_pw_aff_lt_set (lhs
, rhs
);
1152 cond
= isl_pw_aff_gt_set (lhs
, rhs
);
1156 cond
= isl_pw_aff_le_set (lhs
, rhs
);
1160 cond
= isl_pw_aff_ge_set (lhs
, rhs
);
1164 cond
= isl_pw_aff_eq_set (lhs
, rhs
);
1168 cond
= isl_pw_aff_ne_set (lhs
, rhs
);
1172 isl_pw_aff_free (lhs
);
1173 isl_pw_aff_free (rhs
);
1177 cond
= isl_set_coalesce (cond
);
1178 cond
= isl_set_set_tuple_id (cond
, isl_set_get_tuple_id (pbb
->domain
));
1179 pbb
->domain
= isl_set_intersect (pbb
->domain
, cond
);
1182 /* Add conditions to the domain of PBB. */
1185 add_conditions_to_domain (poly_bb_p pbb
)
1189 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1191 if (GBB_CONDITIONS (gbb
).is_empty ())
1194 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1195 switch (gimple_code (stmt
))
1199 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
1200 enum tree_code code
= gimple_cond_code (cond_stmt
);
1202 /* The conditions for ELSE-branches are inverted. */
1203 if (!GBB_CONDITION_CASES (gbb
)[i
])
1204 code
= invert_tree_comparison (code
, false);
1206 add_condition_to_pbb (pbb
, cond_stmt
, code
);
1211 /* Switch statements are not supported right now - fall through. */
1219 /* Traverses all the GBBs of the SCOP and add their constraints to the
1220 iteration domains. */
1223 add_conditions_to_constraints (scop_p scop
)
1228 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1229 add_conditions_to_domain (pbb
);
1232 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1233 edge between BB and its predecessor is not a loop exit edge, and
1234 the last statement of the single predecessor is a COND_EXPR. */
1237 single_pred_cond_non_loop_exit (basic_block bb
)
1239 if (single_pred_p (bb
))
1241 edge e
= single_pred_edge (bb
);
1242 basic_block pred
= e
->src
;
1245 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
1248 stmt
= last_stmt (pred
);
1250 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
1251 return as_a
<gcond
*> (stmt
);
1257 class sese_dom_walker
: public dom_walker
1260 sese_dom_walker (cdi_direction
, sese
);
1262 virtual void before_dom_children (basic_block
);
1263 virtual void after_dom_children (basic_block
);
1266 auto_vec
<gimple
, 3> m_conditions
, m_cases
;
1270 sese_dom_walker::sese_dom_walker (cdi_direction direction
, sese region
)
1271 : dom_walker (direction
), m_region (region
)
1275 /* Call-back for dom_walk executed before visiting the dominated
1279 sese_dom_walker::before_dom_children (basic_block bb
)
1284 if (!bb_in_sese_p (bb
, m_region
))
1287 stmt
= single_pred_cond_non_loop_exit (bb
);
1291 edge e
= single_pred_edge (bb
);
1293 m_conditions
.safe_push (stmt
);
1295 if (e
->flags
& EDGE_TRUE_VALUE
)
1296 m_cases
.safe_push (stmt
);
1298 m_cases
.safe_push (NULL
);
1301 gbb
= gbb_from_bb (bb
);
1305 GBB_CONDITIONS (gbb
) = m_conditions
.copy ();
1306 GBB_CONDITION_CASES (gbb
) = m_cases
.copy ();
1310 /* Call-back for dom_walk executed after visiting the dominated
1314 sese_dom_walker::after_dom_children (basic_block bb
)
1316 if (!bb_in_sese_p (bb
, m_region
))
1319 if (single_pred_cond_non_loop_exit (bb
))
1321 m_conditions
.pop ();
1326 /* Add constraints on the possible values of parameter P from the type
1330 add_param_constraints (scop_p scop
, graphite_dim_t p
)
1332 tree parameter
= SESE_PARAMS (SCOP_REGION (scop
))[p
];
1333 tree type
= TREE_TYPE (parameter
);
1334 tree lb
= NULL_TREE
;
1335 tree ub
= NULL_TREE
;
1337 if (POINTER_TYPE_P (type
) || !TYPE_MIN_VALUE (type
))
1338 lb
= lower_bound_in_type (type
, type
);
1340 lb
= TYPE_MIN_VALUE (type
);
1342 if (POINTER_TYPE_P (type
) || !TYPE_MAX_VALUE (type
))
1343 ub
= upper_bound_in_type (type
, type
);
1345 ub
= TYPE_MAX_VALUE (type
);
1349 isl_space
*space
= isl_set_get_space (scop
->context
);
1354 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1356 tree_int_to_gmp (lb
, g
);
1357 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1358 v
= isl_val_neg (v
);
1360 c
= isl_constraint_set_constant_val (c
, v
);
1361 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, 1);
1363 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1368 isl_space
*space
= isl_set_get_space (scop
->context
);
1373 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1376 tree_int_to_gmp (ub
, g
);
1377 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1379 c
= isl_constraint_set_constant_val (c
, v
);
1380 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, -1);
1382 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1386 /* Build the context of the SCOP. The context usually contains extra
1387 constraints that are added to the iteration domains that constrain
1391 build_scop_context (scop_p scop
)
1393 graphite_dim_t p
, n
= scop_nb_params (scop
);
1395 for (p
= 0; p
< n
; p
++)
1396 add_param_constraints (scop
, p
);
1399 /* Build the iteration domains: the loops belonging to the current
1400 SCOP, and that vary for the execution of the current basic block.
1401 Returns false if there is no loop in SCOP. */
1404 build_scop_iteration_domain (scop_p scop
)
1407 sese region
= SCOP_REGION (scop
);
1410 int nb_loops
= number_of_loops (cfun
);
1411 isl_set
**doms
= XCNEWVEC (isl_set
*, nb_loops
);
1413 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1414 if (!loop_in_sese_p (loop_outer (loop
), region
))
1415 build_loop_iteration_domains (scop
, loop
, 0,
1416 isl_set_copy (scop
->context
), doms
);
1418 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1420 loop
= pbb_loop (pbb
);
1422 if (doms
[loop
->num
])
1423 pbb
->domain
= isl_set_copy (doms
[loop
->num
]);
1425 pbb
->domain
= isl_set_copy (scop
->context
);
1427 pbb
->domain
= isl_set_set_tuple_id (pbb
->domain
,
1428 isl_id_for_pbb (scop
, pbb
));
1431 for (i
= 0; i
< nb_loops
; i
++)
1433 isl_set_free (doms
[i
]);
1438 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1439 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1440 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1444 pdr_add_alias_set (isl_map
*acc
, data_reference_p dr
)
1447 int alias_set_num
= 0;
1448 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1450 if (bap
&& bap
->alias_set
)
1451 alias_set_num
= *(bap
->alias_set
);
1453 c
= isl_equality_alloc
1454 (isl_local_space_from_space (isl_map_get_space (acc
)));
1455 c
= isl_constraint_set_constant_si (c
, -alias_set_num
);
1456 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
1458 return isl_map_add_constraint (acc
, c
);
1461 /* Assign the affine expression INDEX to the output dimension POS of
1462 MAP and return the result. */
1465 set_index (isl_map
*map
, int pos
, isl_pw_aff
*index
)
1468 int len
= isl_map_dim (map
, isl_dim_out
);
1471 index_map
= isl_map_from_pw_aff (index
);
1472 index_map
= isl_map_insert_dims (index_map
, isl_dim_out
, 0, pos
);
1473 index_map
= isl_map_add_dims (index_map
, isl_dim_out
, len
- pos
- 1);
1475 id
= isl_map_get_tuple_id (map
, isl_dim_out
);
1476 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_out
, id
);
1477 id
= isl_map_get_tuple_id (map
, isl_dim_in
);
1478 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_in
, id
);
1480 return isl_map_intersect (map
, index_map
);
1483 /* Add to ACCESSES polyhedron equalities defining the access functions
1484 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1485 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1486 PBB is the poly_bb_p that contains the data reference DR. */
1489 pdr_add_memory_accesses (isl_map
*acc
, data_reference_p dr
, poly_bb_p pbb
)
1491 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1492 scop_p scop
= PBB_SCOP (pbb
);
1494 for (i
= 0; i
< nb_subscripts
; i
++)
1497 tree afn
= DR_ACCESS_FN (dr
, nb_subscripts
- 1 - i
);
1499 aff
= extract_affine (scop
, afn
,
1500 isl_space_domain (isl_map_get_space (acc
)));
1501 acc
= set_index (acc
, i
+ 1, aff
);
1507 /* Add constrains representing the size of the accessed data to the
1508 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1509 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1513 pdr_add_data_dimensions (isl_set
*extent
, scop_p scop
, data_reference_p dr
)
1515 tree ref
= DR_REF (dr
);
1516 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1518 for (i
= nb_subscripts
- 1; i
>= 0; i
--, ref
= TREE_OPERAND (ref
, 0))
1522 if (TREE_CODE (ref
) != ARRAY_REF
)
1525 low
= array_ref_low_bound (ref
);
1526 high
= array_ref_up_bound (ref
);
1528 /* XXX The PPL code dealt separately with
1529 subscript - low >= 0 and high - subscript >= 0 in case one of
1530 the two bounds isn't known. Do the same here? */
1532 if (tree_fits_shwi_p (low
)
1534 && tree_fits_shwi_p (high
)
1535 /* 1-element arrays at end of structures may extend over
1536 their declared size. */
1537 && !(array_at_struct_end_p (ref
)
1538 && operand_equal_p (low
, high
, 0)))
1542 isl_set
*univ
, *lbs
, *ubs
;
1546 isl_pw_aff
*lb
= extract_affine_int (low
, isl_set_get_space (extent
));
1547 isl_pw_aff
*ub
= extract_affine_int (high
, isl_set_get_space (extent
));
1550 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub
));
1551 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1552 isl_set_dim (valid
, isl_dim_set
));
1553 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1555 space
= isl_set_get_space (extent
);
1556 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
1557 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_in
, i
+ 1, 1);
1558 univ
= isl_set_universe (isl_space_domain (isl_aff_get_space (aff
)));
1559 index
= isl_pw_aff_alloc (univ
, aff
);
1561 id
= isl_set_get_tuple_id (extent
);
1562 lb
= isl_pw_aff_set_tuple_id (lb
, isl_dim_in
, isl_id_copy (id
));
1563 ub
= isl_pw_aff_set_tuple_id (ub
, isl_dim_in
, id
);
1565 /* low <= sub_i <= high */
1566 lbs
= isl_pw_aff_ge_set (isl_pw_aff_copy (index
), lb
);
1567 ubs
= isl_pw_aff_le_set (index
, ub
);
1568 extent
= isl_set_intersect (extent
, lbs
);
1569 extent
= isl_set_intersect (extent
, ubs
);
1576 /* Build data accesses for DR in PBB. */
1579 build_poly_dr (data_reference_p dr
, poly_bb_p pbb
)
1581 int dr_base_object_set
;
1584 scop_p scop
= PBB_SCOP (pbb
);
1587 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1588 int nb_out
= 1 + DR_NUM_DIMENSIONS (dr
);
1589 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1590 isl_dim_out
, nb_out
);
1592 acc
= isl_map_universe (space
);
1593 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, isl_id_for_dr (scop
, dr
));
1596 acc
= pdr_add_alias_set (acc
, dr
);
1597 acc
= pdr_add_memory_accesses (acc
, dr
, pbb
);
1600 isl_id
*id
= isl_id_for_dr (scop
, dr
);
1601 int nb
= 1 + DR_NUM_DIMENSIONS (dr
);
1602 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, 0, nb
);
1603 int alias_set_num
= 0;
1604 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1606 if (bap
&& bap
->alias_set
)
1607 alias_set_num
= *(bap
->alias_set
);
1609 space
= isl_space_set_tuple_id (space
, isl_dim_set
, id
);
1610 extent
= isl_set_nat_universe (space
);
1611 extent
= isl_set_fix_si (extent
, isl_dim_set
, 0, alias_set_num
);
1612 extent
= pdr_add_data_dimensions (extent
, scop
, dr
);
1615 gcc_assert (dr
->aux
);
1616 dr_base_object_set
= ((base_alias_pair
*)(dr
->aux
))->base_obj_set
;
1618 new_poly_dr (pbb
, dr_base_object_set
,
1619 DR_IS_READ (dr
) ? PDR_READ
: PDR_WRITE
,
1620 dr
, DR_NUM_DIMENSIONS (dr
), acc
, extent
);
1623 /* Write to FILE the alias graph of data references in DIMACS format. */
1626 write_alias_graph_to_ascii_dimacs (FILE *file
, char *comment
,
1627 vec
<data_reference_p
> drs
)
1629 int num_vertex
= drs
.length ();
1631 data_reference_p dr1
, dr2
;
1634 if (num_vertex
== 0)
1637 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1638 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1639 if (dr_may_alias_p (dr1
, dr2
, true))
1642 fprintf (file
, "$\n");
1645 fprintf (file
, "c %s\n", comment
);
1647 fprintf (file
, "p edge %d %d\n", num_vertex
, edge_num
);
1649 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1650 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1651 if (dr_may_alias_p (dr1
, dr2
, true))
1652 fprintf (file
, "e %d %d\n", i
+ 1, j
+ 1);
1657 /* Write to FILE the alias graph of data references in DOT format. */
1660 write_alias_graph_to_ascii_dot (FILE *file
, char *comment
,
1661 vec
<data_reference_p
> drs
)
1663 int num_vertex
= drs
.length ();
1664 data_reference_p dr1
, dr2
;
1667 if (num_vertex
== 0)
1670 fprintf (file
, "$\n");
1673 fprintf (file
, "c %s\n", comment
);
1675 /* First print all the vertices. */
1676 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1677 fprintf (file
, "n%d;\n", i
);
1679 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1680 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1681 if (dr_may_alias_p (dr1
, dr2
, true))
1682 fprintf (file
, "n%d n%d\n", i
, j
);
1687 /* Write to FILE the alias graph of data references in ECC format. */
1690 write_alias_graph_to_ascii_ecc (FILE *file
, char *comment
,
1691 vec
<data_reference_p
> drs
)
1693 int num_vertex
= drs
.length ();
1694 data_reference_p dr1
, dr2
;
1697 if (num_vertex
== 0)
1700 fprintf (file
, "$\n");
1703 fprintf (file
, "c %s\n", comment
);
1705 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1706 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1707 if (dr_may_alias_p (dr1
, dr2
, true))
1708 fprintf (file
, "%d %d\n", i
, j
);
1713 /* Check if DR1 and DR2 are in the same object set. */
1716 dr_same_base_object_p (const struct data_reference
*dr1
,
1717 const struct data_reference
*dr2
)
1719 return operand_equal_p (DR_BASE_OBJECT (dr1
), DR_BASE_OBJECT (dr2
), 0);
1722 /* Uses DFS component number as representative of alias-sets. Also tests for
1723 optimality by verifying if every connected component is a clique. Returns
1724 true (1) if the above test is true, and false (0) otherwise. */
1727 build_alias_set_optimal_p (vec
<data_reference_p
> drs
)
1729 int num_vertices
= drs
.length ();
1730 struct graph
*g
= new_graph (num_vertices
);
1731 data_reference_p dr1
, dr2
;
1733 int num_connected_components
;
1734 int v_indx1
, v_indx2
, num_vertices_in_component
;
1737 struct graph_edge
*e
;
1738 int this_component_is_clique
;
1739 int all_components_are_cliques
= 1;
1741 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1742 for (j
= i
+1; drs
.iterate (j
, &dr2
); j
++)
1743 if (dr_may_alias_p (dr1
, dr2
, true))
1749 all_vertices
= XNEWVEC (int, num_vertices
);
1750 vertices
= XNEWVEC (int, num_vertices
);
1751 for (i
= 0; i
< num_vertices
; i
++)
1752 all_vertices
[i
] = i
;
1754 num_connected_components
= graphds_dfs (g
, all_vertices
, num_vertices
,
1756 for (i
= 0; i
< g
->n_vertices
; i
++)
1758 data_reference_p dr
= drs
[i
];
1759 base_alias_pair
*bap
;
1761 gcc_assert (dr
->aux
);
1762 bap
= (base_alias_pair
*)(dr
->aux
);
1764 bap
->alias_set
= XNEW (int);
1765 *(bap
->alias_set
) = g
->vertices
[i
].component
+ 1;
1768 /* Verify if the DFS numbering results in optimal solution. */
1769 for (i
= 0; i
< num_connected_components
; i
++)
1771 num_vertices_in_component
= 0;
1772 /* Get all vertices whose DFS component number is the same as i. */
1773 for (j
= 0; j
< num_vertices
; j
++)
1774 if (g
->vertices
[j
].component
== i
)
1775 vertices
[num_vertices_in_component
++] = j
;
1777 /* Now test if the vertices in 'vertices' form a clique, by testing
1778 for edges among each pair. */
1779 this_component_is_clique
= 1;
1780 for (v_indx1
= 0; v_indx1
< num_vertices_in_component
; v_indx1
++)
1782 for (v_indx2
= v_indx1
+1; v_indx2
< num_vertices_in_component
; v_indx2
++)
1784 /* Check if the two vertices are connected by iterating
1785 through all the edges which have one of these are source. */
1786 e
= g
->vertices
[vertices
[v_indx2
]].pred
;
1789 if (e
->src
== vertices
[v_indx1
])
1795 this_component_is_clique
= 0;
1799 if (!this_component_is_clique
)
1800 all_components_are_cliques
= 0;
1804 free (all_vertices
);
1807 return all_components_are_cliques
;
1810 /* Group each data reference in DRS with its base object set num. */
1813 build_base_obj_set_for_drs (vec
<data_reference_p
> drs
)
1815 int num_vertex
= drs
.length ();
1816 struct graph
*g
= new_graph (num_vertex
);
1817 data_reference_p dr1
, dr2
;
1821 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1822 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1823 if (dr_same_base_object_p (dr1
, dr2
))
1829 queue
= XNEWVEC (int, num_vertex
);
1830 for (i
= 0; i
< num_vertex
; i
++)
1833 graphds_dfs (g
, queue
, num_vertex
, NULL
, true, NULL
);
1835 for (i
= 0; i
< g
->n_vertices
; i
++)
1837 data_reference_p dr
= drs
[i
];
1838 base_alias_pair
*bap
;
1840 gcc_assert (dr
->aux
);
1841 bap
= (base_alias_pair
*)(dr
->aux
);
1843 bap
->base_obj_set
= g
->vertices
[i
].component
+ 1;
1850 /* Build the data references for PBB. */
1853 build_pbb_drs (poly_bb_p pbb
)
1856 data_reference_p dr
;
1857 vec
<data_reference_p
> gbb_drs
= GBB_DATA_REFS (PBB_BLACK_BOX (pbb
));
1859 FOR_EACH_VEC_ELT (gbb_drs
, j
, dr
)
1860 build_poly_dr (dr
, pbb
);
1863 /* Dump to file the alias graphs for the data references in DRS. */
1866 dump_alias_graphs (vec
<data_reference_p
> drs
)
1869 FILE *file_dimacs
, *file_ecc
, *file_dot
;
1871 file_dimacs
= fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1874 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1875 current_function_name ());
1876 write_alias_graph_to_ascii_dimacs (file_dimacs
, comment
, drs
);
1877 fclose (file_dimacs
);
1880 file_ecc
= fopen ("/tmp/dr_alias_graph_ecc", "ab");
1883 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1884 current_function_name ());
1885 write_alias_graph_to_ascii_ecc (file_ecc
, comment
, drs
);
1889 file_dot
= fopen ("/tmp/dr_alias_graph_dot", "ab");
1892 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1893 current_function_name ());
1894 write_alias_graph_to_ascii_dot (file_dot
, comment
, drs
);
1899 /* Build data references in SCOP. */
1902 build_scop_drs (scop_p scop
)
1906 data_reference_p dr
;
1907 auto_vec
<data_reference_p
, 3> drs
;
1909 /* Remove all the PBBs that do not have data references: these basic
1910 blocks are not handled in the polyhedral representation. */
1911 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1912 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).is_empty ())
1914 free_gimple_bb (PBB_BLACK_BOX (pbb
));
1916 SCOP_BBS (scop
).ordered_remove (i
);
1920 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1921 for (j
= 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).iterate (j
, &dr
); j
++)
1924 FOR_EACH_VEC_ELT (drs
, i
, dr
)
1925 dr
->aux
= XNEW (base_alias_pair
);
1927 if (!build_alias_set_optimal_p (drs
))
1929 /* TODO: Add support when building alias set is not optimal. */
1933 build_base_obj_set_for_drs (drs
);
1935 /* When debugging, enable the following code. This cannot be used
1936 in production compilers. */
1938 dump_alias_graphs (drs
);
1942 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1943 build_pbb_drs (pbb
);
1946 /* Return a gsi at the position of the phi node STMT. */
1948 static gphi_iterator
1949 gsi_for_phi_node (gphi
*stmt
)
1952 basic_block bb
= gimple_bb (stmt
);
1954 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
1955 if (stmt
== psi
.phi ())
1962 /* Analyze all the data references of STMTS and add them to the
1963 GBB_DATA_REFS vector of BB. */
1966 analyze_drs_in_stmts (scop_p scop
, basic_block bb
, vec
<gimple
> stmts
)
1972 sese region
= SCOP_REGION (scop
);
1974 if (!bb_in_sese_p (bb
, region
))
1977 nest
= outermost_loop_in_sese_1 (region
, bb
);
1978 gbb
= gbb_from_bb (bb
);
1980 FOR_EACH_VEC_ELT (stmts
, i
, stmt
)
1984 if (is_gimple_debug (stmt
))
1987 loop
= loop_containing_stmt (stmt
);
1988 if (!loop_in_sese_p (loop
, region
))
1991 graphite_find_data_references_in_stmt (nest
, loop
, stmt
,
1992 &GBB_DATA_REFS (gbb
));
1996 /* Insert STMT at the end of the STMTS sequence and then insert the
1997 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
2001 insert_stmts (scop_p scop
, gimple stmt
, gimple_seq stmts
,
2002 gimple_stmt_iterator insert_gsi
)
2004 gimple_stmt_iterator gsi
;
2005 auto_vec
<gimple
, 3> x
;
2007 gimple_seq_add_stmt (&stmts
, stmt
);
2008 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2009 x
.safe_push (gsi_stmt (gsi
));
2011 gsi_insert_seq_before (&insert_gsi
, stmts
, GSI_SAME_STMT
);
2012 analyze_drs_in_stmts (scop
, gsi_bb (insert_gsi
), x
);
2015 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2018 insert_out_of_ssa_copy (scop_p scop
, tree res
, tree expr
, gimple after_stmt
)
2021 gimple_stmt_iterator gsi
;
2022 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2023 gassign
*stmt
= gimple_build_assign (unshare_expr (res
), var
);
2024 auto_vec
<gimple
, 3> x
;
2026 gimple_seq_add_stmt (&stmts
, stmt
);
2027 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2028 x
.safe_push (gsi_stmt (gsi
));
2030 if (gimple_code (after_stmt
) == GIMPLE_PHI
)
2032 gsi
= gsi_after_labels (gimple_bb (after_stmt
));
2033 gsi_insert_seq_before (&gsi
, stmts
, GSI_NEW_STMT
);
2037 gsi
= gsi_for_stmt (after_stmt
);
2038 gsi_insert_seq_after (&gsi
, stmts
, GSI_NEW_STMT
);
2041 analyze_drs_in_stmts (scop
, gimple_bb (after_stmt
), x
);
2044 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2047 new_pbb_from_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
)
2049 vec
<data_reference_p
> drs
;
2051 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
2052 gimple_bb_p gbb1
= new_gimple_bb (bb
, drs
);
2053 poly_bb_p pbb1
= new_poly_bb (scop
, gbb1
);
2054 int index
, n
= SCOP_BBS (scop
).length ();
2056 /* The INDEX of PBB in SCOP_BBS. */
2057 for (index
= 0; index
< n
; index
++)
2058 if (SCOP_BBS (scop
)[index
] == pbb
)
2061 pbb1
->domain
= isl_set_copy (pbb
->domain
);
2062 pbb1
->domain
= isl_set_set_tuple_id (pbb1
->domain
,
2063 isl_id_for_pbb (scop
, pbb1
));
2065 GBB_PBB (gbb1
) = pbb1
;
2066 GBB_CONDITIONS (gbb1
) = GBB_CONDITIONS (gbb
).copy ();
2067 GBB_CONDITION_CASES (gbb1
) = GBB_CONDITION_CASES (gbb
).copy ();
2068 SCOP_BBS (scop
).safe_insert (index
+ 1, pbb1
);
2071 /* Insert on edge E the assignment "RES := EXPR". */
2074 insert_out_of_ssa_copy_on_edge (scop_p scop
, edge e
, tree res
, tree expr
)
2076 gimple_stmt_iterator gsi
;
2077 gimple_seq stmts
= NULL
;
2078 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2079 gimple stmt
= gimple_build_assign (unshare_expr (res
), var
);
2081 auto_vec
<gimple
, 3> x
;
2083 gimple_seq_add_stmt (&stmts
, stmt
);
2084 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2085 x
.safe_push (gsi_stmt (gsi
));
2087 gsi_insert_seq_on_edge (e
, stmts
);
2088 gsi_commit_edge_inserts ();
2089 bb
= gimple_bb (stmt
);
2091 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
2094 if (!gbb_from_bb (bb
))
2095 new_pbb_from_pbb (scop
, pbb_from_bb (e
->src
), bb
);
2097 analyze_drs_in_stmts (scop
, bb
, x
);
2100 /* Creates a zero dimension array of the same type as VAR. */
2103 create_zero_dim_array (tree var
, const char *base_name
)
2105 tree index_type
= build_index_type (integer_zero_node
);
2106 tree elt_type
= TREE_TYPE (var
);
2107 tree array_type
= build_array_type (elt_type
, index_type
);
2108 tree base
= create_tmp_var (array_type
, base_name
);
2110 return build4 (ARRAY_REF
, elt_type
, base
, integer_zero_node
, NULL_TREE
,
2114 /* Returns true when PHI is a loop close phi node. */
2117 scalar_close_phi_node_p (gimple phi
)
2119 if (gimple_code (phi
) != GIMPLE_PHI
2120 || virtual_operand_p (gimple_phi_result (phi
)))
2123 /* Note that loop close phi nodes should have a single argument
2124 because we translated the representation into a canonical form
2125 before Graphite: see canonicalize_loop_closed_ssa_form. */
2126 return (gimple_phi_num_args (phi
) == 1);
2129 /* For a definition DEF in REGION, propagates the expression EXPR in
2130 all the uses of DEF outside REGION. */
2133 propagate_expr_outside_region (tree def
, tree expr
, sese region
)
2135 imm_use_iterator imm_iter
;
2138 bool replaced_once
= false;
2140 gcc_assert (TREE_CODE (def
) == SSA_NAME
);
2142 expr
= force_gimple_operand (unshare_expr (expr
), &stmts
, true,
2145 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2146 if (!is_gimple_debug (use_stmt
)
2147 && !bb_in_sese_p (gimple_bb (use_stmt
), region
))
2150 use_operand_p use_p
;
2152 FOR_EACH_PHI_OR_STMT_USE (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2153 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0)
2154 && (replaced_once
= true))
2155 replace_exp (use_p
, expr
);
2157 update_stmt (use_stmt
);
2162 gsi_insert_seq_on_edge (SESE_ENTRY (region
), stmts
);
2163 gsi_commit_edge_inserts ();
2167 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2168 dimension array for it. */
2171 rewrite_close_phi_out_of_ssa (scop_p scop
, gimple_stmt_iterator
*psi
)
2173 sese region
= SCOP_REGION (scop
);
2174 gimple phi
= gsi_stmt (*psi
);
2175 tree res
= gimple_phi_result (phi
);
2176 basic_block bb
= gimple_bb (phi
);
2177 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
2178 tree arg
= gimple_phi_arg_def (phi
, 0);
2181 /* Note that loop close phi nodes should have a single argument
2182 because we translated the representation into a canonical form
2183 before Graphite: see canonicalize_loop_closed_ssa_form. */
2184 gcc_assert (gimple_phi_num_args (phi
) == 1);
2186 /* The phi node can be a non close phi node, when its argument is
2187 invariant, or a default definition. */
2188 if (is_gimple_min_invariant (arg
)
2189 || SSA_NAME_IS_DEFAULT_DEF (arg
))
2191 propagate_expr_outside_region (res
, arg
, region
);
2196 else if (gimple_bb (SSA_NAME_DEF_STMT (arg
))->loop_father
== bb
->loop_father
)
2198 propagate_expr_outside_region (res
, arg
, region
);
2199 stmt
= gimple_build_assign (res
, arg
);
2200 remove_phi_node (psi
, false);
2201 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2205 /* If res is scev analyzable and is not a scalar value, it is safe
2206 to ignore the close phi node: it will be code generated in the
2207 out of Graphite pass. */
2208 else if (scev_analyzable_p (res
, region
))
2210 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (res
));
2213 if (!loop_in_sese_p (loop
, region
))
2215 loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2216 scev
= scalar_evolution_in_region (region
, loop
, arg
);
2217 scev
= compute_overall_effect_of_inner_loop (loop
, scev
);
2220 scev
= scalar_evolution_in_region (region
, loop
, res
);
2222 if (tree_does_not_contain_chrecs (scev
))
2223 propagate_expr_outside_region (res
, scev
, region
);
2230 tree zero_dim_array
= create_zero_dim_array (res
, "Close_Phi");
2232 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2234 if (TREE_CODE (arg
) == SSA_NAME
)
2235 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2236 SSA_NAME_DEF_STMT (arg
));
2238 insert_out_of_ssa_copy_on_edge (scop
, single_pred_edge (bb
),
2239 zero_dim_array
, arg
);
2242 remove_phi_node (psi
, false);
2243 SSA_NAME_DEF_STMT (res
) = stmt
;
2245 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2248 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2249 dimension array for it. */
2252 rewrite_phi_out_of_ssa (scop_p scop
, gphi_iterator
*psi
)
2255 gphi
*phi
= psi
->phi ();
2256 basic_block bb
= gimple_bb (phi
);
2257 tree res
= gimple_phi_result (phi
);
2258 tree zero_dim_array
= create_zero_dim_array (res
, "phi_out_of_ssa");
2261 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2263 tree arg
= gimple_phi_arg_def (phi
, i
);
2264 edge e
= gimple_phi_arg_edge (phi
, i
);
2266 /* Avoid the insertion of code in the loop latch to please the
2267 pattern matching of the vectorizer. */
2268 if (TREE_CODE (arg
) == SSA_NAME
2269 && !SSA_NAME_IS_DEFAULT_DEF (arg
)
2270 && e
->src
== bb
->loop_father
->latch
)
2271 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2272 SSA_NAME_DEF_STMT (arg
));
2274 insert_out_of_ssa_copy_on_edge (scop
, e
, zero_dim_array
, arg
);
2277 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2278 remove_phi_node (psi
, false);
2279 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2282 /* Rewrite the degenerate phi node at position PSI from the degenerate
2283 form "x = phi (y, y, ..., y)" to "x = y". */
2286 rewrite_degenerate_phi (gphi_iterator
*psi
)
2290 gimple_stmt_iterator gsi
;
2291 gphi
*phi
= psi
->phi ();
2292 tree res
= gimple_phi_result (phi
);
2295 bb
= gimple_bb (phi
);
2296 rhs
= degenerate_phi_result (phi
);
2299 stmt
= gimple_build_assign (res
, rhs
);
2300 remove_phi_node (psi
, false);
2302 gsi
= gsi_after_labels (bb
);
2303 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2306 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2309 rewrite_reductions_out_of_ssa (scop_p scop
)
2313 sese region
= SCOP_REGION (scop
);
2315 FOR_EACH_BB_FN (bb
, cfun
)
2316 if (bb_in_sese_p (bb
, region
))
2317 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);)
2319 gphi
*phi
= psi
.phi ();
2321 if (virtual_operand_p (gimple_phi_result (phi
)))
2327 if (gimple_phi_num_args (phi
) > 1
2328 && degenerate_phi_result (phi
))
2329 rewrite_degenerate_phi (&psi
);
2331 else if (scalar_close_phi_node_p (phi
))
2332 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2334 else if (reduction_phi_p (region
, &psi
))
2335 rewrite_phi_out_of_ssa (scop
, &psi
);
2338 update_ssa (TODO_update_ssa
);
2339 #ifdef ENABLE_CHECKING
2340 verify_loop_closed_ssa (true);
2344 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2345 read from ZERO_DIM_ARRAY. */
2348 rewrite_cross_bb_scalar_dependence (scop_p scop
, tree zero_dim_array
,
2349 tree def
, gimple use_stmt
)
2354 use_operand_p use_p
;
2356 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
2358 name
= copy_ssa_name (def
);
2359 name_stmt
= gimple_build_assign (name
, zero_dim_array
);
2361 gimple_assign_set_lhs (name_stmt
, name
);
2362 insert_stmts (scop
, name_stmt
, NULL
, gsi_for_stmt (use_stmt
));
2364 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2365 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0))
2366 replace_exp (use_p
, name
);
2368 update_stmt (use_stmt
);
2371 /* For every definition DEF in the SCOP that is used outside the scop,
2372 insert a closing-scop definition in the basic block just after this
2376 handle_scalar_deps_crossing_scop_limits (scop_p scop
, tree def
, gimple stmt
)
2378 tree var
= create_tmp_reg (TREE_TYPE (def
));
2379 tree new_name
= make_ssa_name (var
, stmt
);
2380 bool needs_copy
= false;
2381 use_operand_p use_p
;
2382 imm_use_iterator imm_iter
;
2384 sese region
= SCOP_REGION (scop
);
2386 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2388 if (!bb_in_sese_p (gimple_bb (use_stmt
), region
))
2390 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
2392 SET_USE (use_p
, new_name
);
2394 update_stmt (use_stmt
);
2399 /* Insert in the empty BB just after the scop a use of DEF such
2400 that the rewrite of cross_bb_scalar_dependences won't insert
2401 arrays everywhere else. */
2404 gimple assign
= gimple_build_assign (new_name
, def
);
2405 gimple_stmt_iterator psi
= gsi_after_labels (SESE_EXIT (region
)->dest
);
2407 update_stmt (assign
);
2408 gsi_insert_before (&psi
, assign
, GSI_SAME_STMT
);
2412 /* Rewrite the scalar dependences crossing the boundary of the BB
2413 containing STMT with an array. Return true when something has been
2417 rewrite_cross_bb_scalar_deps (scop_p scop
, gimple_stmt_iterator
*gsi
)
2419 sese region
= SCOP_REGION (scop
);
2420 gimple stmt
= gsi_stmt (*gsi
);
2421 imm_use_iterator imm_iter
;
2424 tree zero_dim_array
= NULL_TREE
;
2428 switch (gimple_code (stmt
))
2431 def
= gimple_assign_lhs (stmt
);
2435 def
= gimple_call_lhs (stmt
);
2443 || !is_gimple_reg (def
))
2446 if (scev_analyzable_p (def
, region
))
2448 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (def
));
2449 tree scev
= scalar_evolution_in_region (region
, loop
, def
);
2451 if (tree_contains_chrecs (scev
, NULL
))
2454 propagate_expr_outside_region (def
, scev
, region
);
2458 def_bb
= gimple_bb (stmt
);
2460 handle_scalar_deps_crossing_scop_limits (scop
, def
, stmt
);
2462 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2463 if (gimple_code (use_stmt
) == GIMPLE_PHI
2466 gphi_iterator psi
= gsi_start_phis (gimple_bb (use_stmt
));
2468 if (scalar_close_phi_node_p (gsi_stmt (psi
)))
2469 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2471 rewrite_phi_out_of_ssa (scop
, &psi
);
2474 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2475 if (gimple_code (use_stmt
) != GIMPLE_PHI
2476 && def_bb
!= gimple_bb (use_stmt
)
2477 && !is_gimple_debug (use_stmt
)
2480 if (!zero_dim_array
)
2482 zero_dim_array
= create_zero_dim_array
2483 (def
, "Cross_BB_scalar_dependence");
2484 insert_out_of_ssa_copy (scop
, zero_dim_array
, def
,
2485 SSA_NAME_DEF_STMT (def
));
2489 rewrite_cross_bb_scalar_dependence (scop
, unshare_expr (zero_dim_array
),
2496 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2499 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop
)
2502 gimple_stmt_iterator psi
;
2503 sese region
= SCOP_REGION (scop
);
2504 bool changed
= false;
2506 /* Create an extra empty BB after the scop. */
2507 split_edge (SESE_EXIT (region
));
2509 FOR_EACH_BB_FN (bb
, cfun
)
2510 if (bb_in_sese_p (bb
, region
))
2511 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
2512 changed
|= rewrite_cross_bb_scalar_deps (scop
, &psi
);
2517 update_ssa (TODO_update_ssa
);
2518 #ifdef ENABLE_CHECKING
2519 verify_loop_closed_ssa (true);
2524 /* Returns the number of pbbs that are in loops contained in SCOP. */
2527 nb_pbbs_in_loops (scop_p scop
)
2533 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
2534 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), SCOP_REGION (scop
)))
2540 /* Return the number of data references in BB that write in
2544 nb_data_writes_in_bb (basic_block bb
)
2547 gimple_stmt_iterator gsi
;
2549 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2550 if (gimple_vdef (gsi_stmt (gsi
)))
2556 /* Splits at STMT the basic block BB represented as PBB in the
2560 split_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
, gimple stmt
)
2562 edge e1
= split_block (bb
, stmt
);
2563 new_pbb_from_pbb (scop
, pbb
, e1
->dest
);
2567 /* Splits STMT out of its current BB. This is done for reduction
2568 statements for which we want to ignore data dependences. */
2571 split_reduction_stmt (scop_p scop
, gimple stmt
)
2573 basic_block bb
= gimple_bb (stmt
);
2574 poly_bb_p pbb
= pbb_from_bb (bb
);
2575 gimple_bb_p gbb
= gbb_from_bb (bb
);
2578 data_reference_p dr
;
2580 /* Do not split basic blocks with no writes to memory: the reduction
2581 will be the only write to memory. */
2582 if (nb_data_writes_in_bb (bb
) == 0
2583 /* Or if we have already marked BB as a reduction. */
2584 || PBB_IS_REDUCTION (pbb_from_bb (bb
)))
2587 e1
= split_pbb (scop
, pbb
, bb
, stmt
);
2589 /* Split once more only when the reduction stmt is not the only one
2590 left in the original BB. */
2591 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb
)))
2593 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
2595 e1
= split_pbb (scop
, pbb
, bb
, gsi_stmt (gsi
));
2598 /* A part of the data references will end in a different basic block
2599 after the split: move the DRs from the original GBB to the newly
2601 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
2603 basic_block bb1
= gimple_bb (DR_STMT (dr
));
2607 gimple_bb_p gbb1
= gbb_from_bb (bb1
);
2608 GBB_DATA_REFS (gbb1
).safe_push (dr
);
2609 GBB_DATA_REFS (gbb
).ordered_remove (i
);
2617 /* Return true when stmt is a reduction operation. */
2620 is_reduction_operation_p (gimple stmt
)
2622 enum tree_code code
;
2624 gcc_assert (is_gimple_assign (stmt
));
2625 code
= gimple_assign_rhs_code (stmt
);
2627 return flag_associative_math
2628 && commutative_tree_code (code
)
2629 && associative_tree_code (code
);
2632 /* Returns true when PHI contains an argument ARG. */
2635 phi_contains_arg (gphi
*phi
, tree arg
)
2639 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2640 if (operand_equal_p (arg
, gimple_phi_arg_def (phi
, i
), 0))
2646 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2649 follow_ssa_with_commutative_ops (tree arg
, tree lhs
)
2653 if (TREE_CODE (arg
) != SSA_NAME
)
2656 stmt
= SSA_NAME_DEF_STMT (arg
);
2658 if (gimple_code (stmt
) == GIMPLE_NOP
2659 || gimple_code (stmt
) == GIMPLE_CALL
)
2662 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2664 if (phi_contains_arg (phi
, lhs
))
2669 if (!is_gimple_assign (stmt
))
2672 if (gimple_num_ops (stmt
) == 2)
2673 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2675 if (is_reduction_operation_p (stmt
))
2678 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2681 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt
), lhs
);
2687 /* Detect commutative and associative scalar reductions starting at
2688 the STMT. Return the phi node of the reduction cycle, or NULL. */
2691 detect_commutative_reduction_arg (tree lhs
, gimple stmt
, tree arg
,
2695 gphi
*phi
= follow_ssa_with_commutative_ops (arg
, lhs
);
2700 in
->safe_push (stmt
);
2701 out
->safe_push (stmt
);
2705 /* Detect commutative and associative scalar reductions starting at
2706 STMT. Return the phi node of the reduction cycle, or NULL. */
2709 detect_commutative_reduction_assign (gimple stmt
, vec
<gimple
> *in
,
2712 tree lhs
= gimple_assign_lhs (stmt
);
2714 if (gimple_num_ops (stmt
) == 2)
2715 return detect_commutative_reduction_arg (lhs
, stmt
,
2716 gimple_assign_rhs1 (stmt
),
2719 if (is_reduction_operation_p (stmt
))
2721 gphi
*res
= detect_commutative_reduction_arg (lhs
, stmt
,
2722 gimple_assign_rhs1 (stmt
),
2725 : detect_commutative_reduction_arg (lhs
, stmt
,
2726 gimple_assign_rhs2 (stmt
),
2733 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2736 follow_inital_value_to_phi (tree arg
, tree lhs
)
2740 if (!arg
|| TREE_CODE (arg
) != SSA_NAME
)
2743 stmt
= SSA_NAME_DEF_STMT (arg
);
2745 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2746 if (phi_contains_arg (phi
, lhs
))
2753 /* Return the argument of the loop PHI that is the initial value coming
2754 from outside the loop. */
2757 edge_initial_value_for_loop_phi (gphi
*phi
)
2761 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2763 edge e
= gimple_phi_arg_edge (phi
, i
);
2765 if (loop_depth (e
->src
->loop_father
)
2766 < loop_depth (e
->dest
->loop_father
))
2773 /* Return the argument of the loop PHI that is the initial value coming
2774 from outside the loop. */
2777 initial_value_for_loop_phi (gphi
*phi
)
2781 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2783 edge e
= gimple_phi_arg_edge (phi
, i
);
2785 if (loop_depth (e
->src
->loop_father
)
2786 < loop_depth (e
->dest
->loop_father
))
2787 return gimple_phi_arg_def (phi
, i
);
2793 /* Returns true when DEF is used outside the reduction cycle of
2797 used_outside_reduction (tree def
, gimple loop_phi
)
2799 use_operand_p use_p
;
2800 imm_use_iterator imm_iter
;
2801 loop_p loop
= loop_containing_stmt (loop_phi
);
2803 /* In LOOP, DEF should be used only in LOOP_PHI. */
2804 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2806 gimple stmt
= USE_STMT (use_p
);
2808 if (stmt
!= loop_phi
2809 && !is_gimple_debug (stmt
)
2810 && flow_bb_inside_loop_p (loop
, gimple_bb (stmt
)))
2817 /* Detect commutative and associative scalar reductions belonging to
2818 the SCOP starting at the loop closed phi node STMT. Return the phi
2819 node of the reduction cycle, or NULL. */
2822 detect_commutative_reduction (scop_p scop
, gimple stmt
, vec
<gimple
> *in
,
2825 if (scalar_close_phi_node_p (stmt
))
2828 gphi
*loop_phi
, *phi
, *close_phi
= as_a
<gphi
*> (stmt
);
2829 tree init
, lhs
, arg
= gimple_phi_arg_def (close_phi
, 0);
2831 if (TREE_CODE (arg
) != SSA_NAME
)
2834 /* Note that loop close phi nodes should have a single argument
2835 because we translated the representation into a canonical form
2836 before Graphite: see canonicalize_loop_closed_ssa_form. */
2837 gcc_assert (gimple_phi_num_args (close_phi
) == 1);
2839 def
= SSA_NAME_DEF_STMT (arg
);
2840 if (!stmt_in_sese_p (def
, SCOP_REGION (scop
))
2841 || !(loop_phi
= detect_commutative_reduction (scop
, def
, in
, out
)))
2844 lhs
= gimple_phi_result (close_phi
);
2845 init
= initial_value_for_loop_phi (loop_phi
);
2846 phi
= follow_inital_value_to_phi (init
, lhs
);
2848 if (phi
&& (used_outside_reduction (lhs
, phi
)
2849 || !has_single_use (gimple_phi_result (phi
))))
2852 in
->safe_push (loop_phi
);
2853 out
->safe_push (close_phi
);
2857 if (gimple_code (stmt
) == GIMPLE_ASSIGN
)
2858 return detect_commutative_reduction_assign (stmt
, in
, out
);
2863 /* Translate the scalar reduction statement STMT to an array RED
2864 knowing that its recursive phi node is LOOP_PHI. */
2867 translate_scalar_reduction_to_array_for_stmt (scop_p scop
, tree red
,
2868 gimple stmt
, gphi
*loop_phi
)
2870 tree res
= gimple_phi_result (loop_phi
);
2871 gassign
*assign
= gimple_build_assign (res
, unshare_expr (red
));
2872 gimple_stmt_iterator gsi
;
2874 insert_stmts (scop
, assign
, NULL
, gsi_after_labels (gimple_bb (loop_phi
)));
2876 assign
= gimple_build_assign (unshare_expr (red
), gimple_assign_lhs (stmt
));
2877 gsi
= gsi_for_stmt (stmt
);
2879 insert_stmts (scop
, assign
, NULL
, gsi
);
2882 /* Removes the PHI node and resets all the debug stmts that are using
2886 remove_phi (gphi
*phi
)
2888 imm_use_iterator imm_iter
;
2890 use_operand_p use_p
;
2891 gimple_stmt_iterator gsi
;
2892 auto_vec
<gimple
, 3> update
;
2896 def
= PHI_RESULT (phi
);
2897 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2899 stmt
= USE_STMT (use_p
);
2901 if (is_gimple_debug (stmt
))
2903 gimple_debug_bind_reset_value (stmt
);
2904 update
.safe_push (stmt
);
2908 FOR_EACH_VEC_ELT (update
, i
, stmt
)
2911 gsi
= gsi_for_phi_node (phi
);
2912 remove_phi_node (&gsi
, false);
2915 /* Helper function for for_each_index. For each INDEX of the data
2916 reference REF, returns true when its indices are valid in the loop
2917 nest LOOP passed in as DATA. */
2920 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED
, tree
*index
, void *data
)
2923 basic_block header
, def_bb
;
2926 if (TREE_CODE (*index
) != SSA_NAME
)
2929 loop
= *((loop_p
*) data
);
2930 header
= loop
->header
;
2931 stmt
= SSA_NAME_DEF_STMT (*index
);
2936 def_bb
= gimple_bb (stmt
);
2941 return dominated_by_p (CDI_DOMINATORS
, header
, def_bb
);
2944 /* When the result of a CLOSE_PHI is written to a memory location,
2945 return a pointer to that memory reference, otherwise return
2949 close_phi_written_to_memory (gphi
*close_phi
)
2951 imm_use_iterator imm_iter
;
2952 use_operand_p use_p
;
2954 tree res
, def
= gimple_phi_result (close_phi
);
2956 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2957 if ((stmt
= USE_STMT (use_p
))
2958 && gimple_code (stmt
) == GIMPLE_ASSIGN
2959 && (res
= gimple_assign_lhs (stmt
)))
2961 switch (TREE_CODE (res
))
2971 tree arg
= gimple_phi_arg_def (close_phi
, 0);
2972 loop_p nest
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2974 /* FIXME: this restriction is for id-{24,25}.f and
2975 could be handled by duplicating the computation of
2976 array indices before the loop of the close_phi. */
2977 if (for_each_index (&res
, dr_indices_valid_in_loop
, &nest
))
2989 /* Rewrite out of SSA the reduction described by the loop phi nodes
2990 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2993 IN: stmt, loop_n, ..., loop_0
2994 OUT: stmt, close_n, ..., close_0
2996 the first element is the reduction statement, and the next elements
2997 are the loop and close phi nodes of each of the outer loops. */
3000 translate_scalar_reduction_to_array (scop_p scop
,
3005 unsigned int i
= out
.length () - 1;
3006 tree red
= close_phi_written_to_memory (as_a
<gphi
*> (out
[i
]));
3008 FOR_EACH_VEC_ELT (in
, i
, loop_stmt
)
3010 gimple close_stmt
= out
[i
];
3014 basic_block bb
= split_reduction_stmt (scop
, loop_stmt
);
3015 poly_bb_p pbb
= pbb_from_bb (bb
);
3016 PBB_IS_REDUCTION (pbb
) = true;
3017 gcc_assert (close_stmt
== loop_stmt
);
3020 red
= create_zero_dim_array
3021 (gimple_assign_lhs (loop_stmt
), "Commutative_Associative_Reduction");
3023 translate_scalar_reduction_to_array_for_stmt (scop
, red
, loop_stmt
,
3024 as_a
<gphi
*> (in
[1]));
3028 gphi
*loop_phi
= as_a
<gphi
*> (loop_stmt
);
3029 gphi
*close_phi
= as_a
<gphi
*> (close_stmt
);
3031 if (i
== in
.length () - 1)
3033 insert_out_of_ssa_copy (scop
, gimple_phi_result (close_phi
),
3034 unshare_expr (red
), close_phi
);
3035 insert_out_of_ssa_copy_on_edge
3036 (scop
, edge_initial_value_for_loop_phi (loop_phi
),
3037 unshare_expr (red
), initial_value_for_loop_phi (loop_phi
));
3040 remove_phi (loop_phi
);
3041 remove_phi (close_phi
);
3045 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3046 true when something has been changed. */
3049 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop
,
3053 auto_vec
<gimple
, 10> in
;
3054 auto_vec
<gimple
, 10> out
;
3056 detect_commutative_reduction (scop
, close_phi
, &in
, &out
);
3057 res
= in
.length () > 1;
3059 translate_scalar_reduction_to_array (scop
, in
, out
);
3064 /* Rewrites all the commutative reductions from LOOP out of SSA.
3065 Returns true when something has been changed. */
3068 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop
,
3072 edge exit
= single_exit (loop
);
3074 bool changed
= false;
3079 for (gsi
= gsi_start_phis (exit
->dest
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3080 if ((res
= gimple_phi_result (gsi
.phi ()))
3081 && !virtual_operand_p (res
)
3082 && !scev_analyzable_p (res
, SCOP_REGION (scop
)))
3083 changed
|= rewrite_commutative_reductions_out_of_ssa_close_phi
3089 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3092 rewrite_commutative_reductions_out_of_ssa (scop_p scop
)
3095 bool changed
= false;
3096 sese region
= SCOP_REGION (scop
);
3098 FOR_EACH_LOOP (loop
, 0)
3099 if (loop_in_sese_p (loop
, region
))
3100 changed
|= rewrite_commutative_reductions_out_of_ssa_loop (scop
, loop
);
3105 gsi_commit_edge_inserts ();
3106 update_ssa (TODO_update_ssa
);
3107 #ifdef ENABLE_CHECKING
3108 verify_loop_closed_ssa (true);
3113 /* Can all ivs be represented by a signed integer?
3114 As CLooG might generate negative values in its expressions, signed loop ivs
3115 are required in the backend. */
3118 scop_ivs_can_be_represented (scop_p scop
)
3124 FOR_EACH_LOOP (loop
, 0)
3126 if (!loop_in_sese_p (loop
, SCOP_REGION (scop
)))
3129 for (psi
= gsi_start_phis (loop
->header
);
3130 !gsi_end_p (psi
); gsi_next (&psi
))
3132 gphi
*phi
= psi
.phi ();
3133 tree res
= PHI_RESULT (phi
);
3134 tree type
= TREE_TYPE (res
);
3136 if (TYPE_UNSIGNED (type
)
3137 && TYPE_PRECISION (type
) >= TYPE_PRECISION (long_long_integer_type_node
))
3150 /* Builds the polyhedral representation for a SESE region. */
3153 build_poly_scop (scop_p scop
)
3155 sese region
= SCOP_REGION (scop
);
3156 graphite_dim_t max_dim
;
3158 build_scop_bbs (scop
);
3160 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3161 Once CLooG is fixed, remove this guard. Anyways, it makes no
3162 sense to optimize a scop containing only PBBs that do not belong
3164 if (nb_pbbs_in_loops (scop
) == 0)
3167 if (!scop_ivs_can_be_represented (scop
))
3170 if (flag_associative_math
)
3171 rewrite_commutative_reductions_out_of_ssa (scop
);
3173 build_sese_loop_nests (region
);
3174 /* Record all conditions in REGION. */
3175 sese_dom_walker (CDI_DOMINATORS
, region
).walk (cfun
->cfg
->x_entry_block_ptr
);
3176 find_scop_parameters (scop
);
3178 max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
3179 if (scop_nb_params (scop
) > max_dim
)
3182 build_scop_iteration_domain (scop
);
3183 build_scop_context (scop
);
3184 add_conditions_to_constraints (scop
);
3186 /* Rewrite out of SSA only after having translated the
3187 representation to the polyhedral representation to avoid scev
3188 analysis failures. That means that these functions will insert
3189 new data references that they create in the right place. */
3190 rewrite_reductions_out_of_ssa (scop
);
3191 rewrite_cross_bb_scalar_deps_out_of_ssa (scop
);
3193 build_scop_drs (scop
);
3195 build_scop_scattering (scop
);
3197 /* This SCoP has been translated to the polyhedral
3199 POLY_SCOP_P (scop
) = true;