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/>. */
24 /* Workaround for GMP 5.1.3 bug, see PR56019. */
29 #include <isl/union_map.h>
30 #include <isl/constraint.h>
34 /* Since ISL-0.13, the extern is in val_gmp.h. */
35 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
38 #include <isl/val_gmp.h>
39 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
45 #include "coretypes.h"
53 #include "fold-const.h"
54 #include "internal-fn.h"
55 #include "gimple-iterator.h"
57 #include "gimplify-me.h"
59 #include "tree-ssa-loop-manip.h"
60 #include "tree-ssa-loop-niter.h"
61 #include "tree-ssa-loop.h"
62 #include "tree-into-ssa.h"
63 #include "tree-pass.h"
65 #include "tree-chrec.h"
66 #include "tree-data-ref.h"
67 #include "tree-scalar-evolution.h"
70 #include "tree-ssa-propagate.h"
74 #include "insn-config.h"
83 #include "graphite-poly.h"
84 #include "graphite-sese-to-poly.h"
87 /* Assigns to RES the value of the INTEGER_CST T. */
90 tree_int_to_gmp (tree t
, mpz_t res
)
92 wi::to_mpz (t
, res
, TYPE_SIGN (TREE_TYPE (t
)));
95 /* Returns the index of the PHI argument defined in the outermost
99 phi_arg_in_outermost_loop (gphi
*phi
)
101 loop_p loop
= gimple_bb (phi
)->loop_father
;
104 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
105 if (!flow_bb_inside_loop_p (loop
, gimple_phi_arg_edge (phi
, i
)->src
))
107 loop
= gimple_phi_arg_edge (phi
, i
)->src
->loop_father
;
114 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
115 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
118 remove_simple_copy_phi (gphi_iterator
*psi
)
120 gphi
*phi
= psi
->phi ();
121 tree res
= gimple_phi_result (phi
);
122 size_t entry
= phi_arg_in_outermost_loop (phi
);
123 tree init
= gimple_phi_arg_def (phi
, entry
);
124 gassign
*stmt
= gimple_build_assign (res
, init
);
125 edge e
= gimple_phi_arg_edge (phi
, entry
);
127 remove_phi_node (psi
, false);
128 gsi_insert_on_edge_immediate (e
, stmt
);
131 /* Removes an invariant phi node at position PSI by inserting on the
132 loop ENTRY edge the assignment RES = INIT. */
135 remove_invariant_phi (sese region
, gphi_iterator
*psi
)
137 gphi
*phi
= psi
->phi ();
138 loop_p loop
= loop_containing_stmt (phi
);
139 tree res
= gimple_phi_result (phi
);
140 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
141 size_t entry
= phi_arg_in_outermost_loop (phi
);
142 edge e
= gimple_phi_arg_edge (phi
, entry
);
145 gimple_seq stmts
= NULL
;
147 if (tree_contains_chrecs (scev
, NULL
))
148 scev
= gimple_phi_arg_def (phi
, entry
);
150 var
= force_gimple_operand (scev
, &stmts
, true, NULL_TREE
);
151 stmt
= gimple_build_assign (res
, var
);
152 remove_phi_node (psi
, false);
154 gimple_seq_add_stmt (&stmts
, stmt
);
155 gsi_insert_seq_on_edge (e
, stmts
);
156 gsi_commit_edge_inserts ();
157 SSA_NAME_DEF_STMT (res
) = stmt
;
160 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
163 simple_copy_phi_p (gphi
*phi
)
167 if (gimple_phi_num_args (phi
) != 2)
170 res
= gimple_phi_result (phi
);
171 return (res
== gimple_phi_arg_def (phi
, 0)
172 || res
== gimple_phi_arg_def (phi
, 1));
175 /* Returns true when the phi node at position PSI is a reduction phi
176 node in REGION. Otherwise moves the pointer PSI to the next phi to
180 reduction_phi_p (sese region
, gphi_iterator
*psi
)
183 gphi
*phi
= psi
->phi ();
184 tree res
= gimple_phi_result (phi
);
186 loop
= loop_containing_stmt (phi
);
188 if (simple_copy_phi_p (phi
))
190 /* PRE introduces phi nodes like these, for an example,
191 see id-5.f in the fortran graphite testsuite:
193 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
195 remove_simple_copy_phi (psi
);
199 if (scev_analyzable_p (res
, region
))
201 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
203 if (evolution_function_is_invariant_p (scev
, loop
->num
))
204 remove_invariant_phi (region
, psi
);
211 /* All the other cases are considered reductions. */
215 /* Store the GRAPHITE representation of BB. */
218 new_gimple_bb (basic_block bb
, vec
<data_reference_p
> drs
)
220 struct gimple_bb
*gbb
;
222 gbb
= XNEW (struct gimple_bb
);
225 GBB_DATA_REFS (gbb
) = drs
;
226 GBB_CONDITIONS (gbb
).create (0);
227 GBB_CONDITION_CASES (gbb
).create (0);
233 free_data_refs_aux (vec
<data_reference_p
> datarefs
)
236 struct data_reference
*dr
;
238 FOR_EACH_VEC_ELT (datarefs
, i
, dr
)
241 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
243 free (bap
->alias_set
);
252 free_gimple_bb (struct gimple_bb
*gbb
)
254 free_data_refs_aux (GBB_DATA_REFS (gbb
));
255 free_data_refs (GBB_DATA_REFS (gbb
));
257 GBB_CONDITIONS (gbb
).release ();
258 GBB_CONDITION_CASES (gbb
).release ();
259 GBB_BB (gbb
)->aux
= 0;
263 /* Deletes all gimple bbs in SCOP. */
266 remove_gbbs_in_scop (scop_p scop
)
271 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
272 free_gimple_bb (PBB_BLACK_BOX (pbb
));
275 /* Deletes all scops in SCOPS. */
278 free_scops (vec
<scop_p
> scops
)
283 FOR_EACH_VEC_ELT (scops
, i
, scop
)
285 remove_gbbs_in_scop (scop
);
286 free_sese (SCOP_REGION (scop
));
293 /* Same as outermost_loop_in_sese, returns the outermost loop
294 containing BB in REGION, but makes sure that the returned loop
295 belongs to the REGION, and so this returns the first loop in the
296 REGION when the loop containing BB does not belong to REGION. */
299 outermost_loop_in_sese_1 (sese region
, basic_block bb
)
301 loop_p nest
= outermost_loop_in_sese (region
, bb
);
303 if (loop_in_sese_p (nest
, region
))
306 /* When the basic block BB does not belong to a loop in the region,
307 return the first loop in the region. */
310 if (loop_in_sese_p (nest
, region
))
319 /* Generates a polyhedral black box only if the bb contains interesting
323 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
325 vec
<data_reference_p
> drs
;
327 sese region
= SCOP_REGION (scop
);
328 loop_p nest
= outermost_loop_in_sese_1 (region
, bb
);
329 gimple_stmt_iterator gsi
;
331 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
333 gimple stmt
= gsi_stmt (gsi
);
336 if (is_gimple_debug (stmt
))
339 loop
= loop_containing_stmt (stmt
);
340 if (!loop_in_sese_p (loop
, region
))
343 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
346 return new_gimple_bb (bb
, drs
);
349 /* Returns true if all predecessors of BB, that are not dominated by BB, are
350 marked in MAP. The predecessors dominated by BB are loop latches and will
351 be handled after BB. */
354 all_non_dominated_preds_marked_p (basic_block bb
, sbitmap map
)
359 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
360 if (!bitmap_bit_p (map
, e
->src
->index
)
361 && !dominated_by_p (CDI_DOMINATORS
, e
->src
, bb
))
367 /* Compare the depth of two basic_block's P1 and P2. */
370 compare_bb_depths (const void *p1
, const void *p2
)
372 const_basic_block
const bb1
= *(const_basic_block
const*)p1
;
373 const_basic_block
const bb2
= *(const_basic_block
const*)p2
;
374 int d1
= loop_depth (bb1
->loop_father
);
375 int d2
= loop_depth (bb2
->loop_father
);
386 /* Sort the basic blocks from DOM such that the first are the ones at
387 a deepest loop level. */
390 graphite_sort_dominated_info (vec
<basic_block
> dom
)
392 dom
.qsort (compare_bb_depths
);
395 /* Recursive helper function for build_scops_bbs. */
398 build_scop_bbs_1 (scop_p scop
, sbitmap visited
, basic_block bb
)
400 sese region
= SCOP_REGION (scop
);
401 vec
<basic_block
> dom
;
404 if (bitmap_bit_p (visited
, bb
->index
)
405 || !bb_in_sese_p (bb
, region
))
408 pbb
= new_poly_bb (scop
, try_generate_gimple_bb (scop
, bb
));
409 SCOP_BBS (scop
).safe_push (pbb
);
410 bitmap_set_bit (visited
, bb
->index
);
412 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
417 graphite_sort_dominated_info (dom
);
419 while (!dom
.is_empty ())
424 FOR_EACH_VEC_ELT (dom
, i
, dom_bb
)
425 if (all_non_dominated_preds_marked_p (dom_bb
, visited
))
427 build_scop_bbs_1 (scop
, visited
, dom_bb
);
428 dom
.unordered_remove (i
);
436 /* Gather the basic blocks belonging to the SCOP. */
439 build_scop_bbs (scop_p scop
)
441 sbitmap visited
= sbitmap_alloc (last_basic_block_for_fn (cfun
));
442 sese region
= SCOP_REGION (scop
);
444 bitmap_clear (visited
);
445 build_scop_bbs_1 (scop
, visited
, SESE_ENTRY_BB (region
));
446 sbitmap_free (visited
);
449 /* Return an ISL identifier for the polyhedral basic block PBB. */
452 isl_id_for_pbb (scop_p s
, poly_bb_p pbb
)
455 snprintf (name
, sizeof (name
), "S_%d", pbb_index (pbb
));
456 return isl_id_alloc (s
->ctx
, name
, pbb
);
459 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
460 We generate SCATTERING_DIMENSIONS scattering dimensions.
462 CLooG 0.15.0 and previous versions require, that all
463 scattering functions of one CloogProgram have the same number of
464 scattering dimensions, therefore we allow to specify it. This
465 should be removed in future versions of CLooG.
467 The scattering polyhedron consists of these dimensions: scattering,
468 loop_iterators, parameters.
472 | scattering_dimensions = 5
473 | used_scattering_dimensions = 3
481 | Scattering polyhedron:
483 | scattering: {s1, s2, s3, s4, s5}
484 | loop_iterators: {i}
485 | parameters: {p1, p2}
487 | s1 s2 s3 s4 s5 i p1 p2 1
488 | 1 0 0 0 0 0 0 0 -4 = 0
489 | 0 1 0 0 0 -1 0 0 0 = 0
490 | 0 0 1 0 0 0 0 0 -5 = 0 */
493 build_pbb_scattering_polyhedrons (isl_aff
*static_sched
,
494 poly_bb_p pbb
, int scattering_dimensions
)
497 int nb_iterators
= pbb_dim_iter_domain (pbb
);
498 int used_scattering_dimensions
= nb_iterators
* 2 + 1;
502 gcc_assert (scattering_dimensions
>= used_scattering_dimensions
);
504 dc
= isl_set_get_space (pbb
->domain
);
505 dm
= isl_space_add_dims (isl_space_from_domain (dc
),
506 isl_dim_out
, scattering_dimensions
);
507 pbb
->schedule
= isl_map_universe (dm
);
509 for (i
= 0; i
< scattering_dimensions
; i
++)
511 /* Textual order inside this loop. */
514 isl_constraint
*c
= isl_equality_alloc
515 (isl_local_space_from_space (isl_map_get_space (pbb
->schedule
)));
517 val
= isl_aff_get_coefficient_val (static_sched
, isl_dim_in
, i
/ 2);
519 val
= isl_val_neg (val
);
520 c
= isl_constraint_set_constant_val (c
, val
);
521 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
522 pbb
->schedule
= isl_map_add_constraint (pbb
->schedule
, c
);
525 /* Iterations of this loop. */
526 else /* if ((i % 2) == 1) */
528 int loop
= (i
- 1) / 2;
529 pbb
->schedule
= isl_map_equate (pbb
->schedule
, isl_dim_in
, loop
,
534 pbb
->transformed
= isl_map_copy (pbb
->schedule
);
537 /* Build for BB the static schedule.
539 The static schedule is a Dewey numbering of the abstract syntax
540 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
542 The following example informally defines the static schedule:
561 Static schedules for A to F:
574 build_scop_scattering (scop_p scop
)
578 gimple_bb_p previous_gbb
= NULL
;
579 isl_space
*dc
= isl_set_get_space (scop
->context
);
580 isl_aff
*static_sched
;
582 dc
= isl_space_add_dims (dc
, isl_dim_set
, number_of_loops (cfun
));
583 static_sched
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
585 /* We have to start schedules at 0 on the first component and
586 because we cannot compare_prefix_loops against a previous loop,
587 prefix will be equal to zero, and that index will be
588 incremented before copying. */
589 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
, 0, -1);
591 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
593 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
595 int nb_scat_dims
= pbb_dim_iter_domain (pbb
) * 2 + 1;
598 prefix
= nb_common_loops (SCOP_REGION (scop
), previous_gbb
, gbb
);
604 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
,
606 build_pbb_scattering_polyhedrons (static_sched
, pbb
, nb_scat_dims
);
609 isl_aff_free (static_sched
);
612 static isl_pw_aff
*extract_affine (scop_p
, tree
, __isl_take isl_space
*space
);
614 /* Extract an affine expression from the chain of recurrence E. */
617 extract_affine_chrec (scop_p s
, tree e
, __isl_take isl_space
*space
)
619 isl_pw_aff
*lhs
= extract_affine (s
, CHREC_LEFT (e
), isl_space_copy (space
));
620 isl_pw_aff
*rhs
= extract_affine (s
, CHREC_RIGHT (e
), isl_space_copy (space
));
621 isl_local_space
*ls
= isl_local_space_from_space (space
);
622 unsigned pos
= sese_loop_depth ((sese
) s
->region
, get_chrec_loop (e
)) - 1;
623 isl_aff
*loop
= isl_aff_set_coefficient_si
624 (isl_aff_zero_on_domain (ls
), isl_dim_in
, pos
, 1);
625 isl_pw_aff
*l
= isl_pw_aff_from_aff (loop
);
627 /* Before multiplying, make sure that the result is affine. */
628 gcc_assert (isl_pw_aff_is_cst (rhs
)
629 || isl_pw_aff_is_cst (l
));
631 return isl_pw_aff_add (lhs
, isl_pw_aff_mul (rhs
, l
));
634 /* Extract an affine expression from the mult_expr E. */
637 extract_affine_mul (scop_p s
, tree e
, __isl_take isl_space
*space
)
639 isl_pw_aff
*lhs
= extract_affine (s
, TREE_OPERAND (e
, 0),
640 isl_space_copy (space
));
641 isl_pw_aff
*rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
643 if (!isl_pw_aff_is_cst (lhs
)
644 && !isl_pw_aff_is_cst (rhs
))
646 isl_pw_aff_free (lhs
);
647 isl_pw_aff_free (rhs
);
651 return isl_pw_aff_mul (lhs
, rhs
);
654 /* Return an ISL identifier from the name of the ssa_name E. */
657 isl_id_for_ssa_name (scop_p s
, tree e
)
659 const char *name
= get_name (e
);
663 id
= isl_id_alloc (s
->ctx
, name
, e
);
667 snprintf (name1
, sizeof (name1
), "P_%d", SSA_NAME_VERSION (e
));
668 id
= isl_id_alloc (s
->ctx
, name1
, e
);
674 /* Return an ISL identifier for the data reference DR. */
677 isl_id_for_dr (scop_p s
, data_reference_p dr ATTRIBUTE_UNUSED
)
679 /* Data references all get the same isl_id. They need to be comparable
680 and are distinguished through the first dimension, which contains the
682 return isl_id_alloc (s
->ctx
, "", 0);
685 /* Extract an affine expression from the ssa_name E. */
688 extract_affine_name (scop_p s
, tree e
, __isl_take isl_space
*space
)
695 id
= isl_id_for_ssa_name (s
, e
);
696 dimension
= isl_space_find_dim_by_id (space
, isl_dim_param
, id
);
698 dom
= isl_set_universe (isl_space_copy (space
));
699 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
700 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, dimension
, 1);
701 return isl_pw_aff_alloc (dom
, aff
);
704 /* Extract an affine expression from the gmp constant G. */
707 extract_affine_gmp (mpz_t g
, __isl_take isl_space
*space
)
709 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
710 isl_aff
*aff
= isl_aff_zero_on_domain (ls
);
711 isl_set
*dom
= isl_set_universe (space
);
715 ct
= isl_aff_get_ctx (aff
);
716 v
= isl_val_int_from_gmp (ct
, g
);
717 aff
= isl_aff_add_constant_val (aff
, v
);
719 return isl_pw_aff_alloc (dom
, aff
);
722 /* Extract an affine expression from the integer_cst E. */
725 extract_affine_int (tree e
, __isl_take isl_space
*space
)
731 tree_int_to_gmp (e
, g
);
732 res
= extract_affine_gmp (g
, space
);
738 /* Compute pwaff mod 2^width. */
740 extern isl_ctx
*the_isl_ctx
;
743 wrap (isl_pw_aff
*pwaff
, unsigned width
)
747 mod
= isl_val_int_from_ui(the_isl_ctx
, width
);
748 mod
= isl_val_2exp (mod
);
749 pwaff
= isl_pw_aff_mod_val (pwaff
, mod
);
754 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
755 Otherwise returns -1. */
758 parameter_index_in_region_1 (tree name
, sese region
)
763 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
765 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
772 /* When the parameter NAME is in REGION, returns its index in
773 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
774 and returns the index of NAME. */
777 parameter_index_in_region (tree name
, sese region
)
781 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
783 i
= parameter_index_in_region_1 (name
, region
);
787 gcc_assert (SESE_ADD_PARAMS (region
));
789 i
= SESE_PARAMS (region
).length ();
790 SESE_PARAMS (region
).safe_push (name
);
794 /* Extract an affine expression from the tree E in the scop S. */
797 extract_affine (scop_p s
, tree e
, __isl_take isl_space
*space
)
799 isl_pw_aff
*lhs
, *rhs
, *res
;
802 if (e
== chrec_dont_know
) {
803 isl_space_free (space
);
807 switch (TREE_CODE (e
))
809 case POLYNOMIAL_CHREC
:
810 res
= extract_affine_chrec (s
, e
, space
);
814 res
= extract_affine_mul (s
, e
, space
);
818 case POINTER_PLUS_EXPR
:
819 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
820 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
821 res
= isl_pw_aff_add (lhs
, rhs
);
825 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
826 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
827 res
= isl_pw_aff_sub (lhs
, rhs
);
832 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
833 rhs
= extract_affine (s
, integer_minus_one_node
, space
);
834 res
= isl_pw_aff_mul (lhs
, rhs
);
838 gcc_assert (-1 != parameter_index_in_region_1 (e
, SCOP_REGION (s
)));
839 res
= extract_affine_name (s
, e
, space
);
843 res
= extract_affine_int (e
, space
);
844 /* No need to wrap a single integer. */
848 case NON_LVALUE_EXPR
:
849 res
= extract_affine (s
, TREE_OPERAND (e
, 0), space
);
857 type
= TREE_TYPE (e
);
858 if (TYPE_UNSIGNED (type
))
859 res
= wrap (res
, TYPE_PRECISION (type
));
864 /* In the context of sese S, scan the expression E and translate it to
865 a linear expression C. When parsing a symbolic multiplication, K
866 represents the constant multiplier of an expression containing
870 scan_tree_for_params (sese s
, tree e
)
872 if (e
== chrec_dont_know
)
875 switch (TREE_CODE (e
))
877 case POLYNOMIAL_CHREC
:
878 scan_tree_for_params (s
, CHREC_LEFT (e
));
882 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
883 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
885 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
889 case POINTER_PLUS_EXPR
:
891 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
892 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
898 case NON_LVALUE_EXPR
:
899 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
903 parameter_index_in_region (e
, s
);
916 /* Find parameters with respect to REGION in BB. We are looking in memory
917 access functions, conditions and loop bounds. */
920 find_params_in_bb (sese region
, gimple_bb_p gbb
)
926 loop_p loop
= GBB_BB (gbb
)->loop_father
;
928 /* Find parameters in the access functions of data references. */
929 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
930 for (j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
931 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
933 /* Find parameters in conditional statements. */
934 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
936 tree lhs
= scalar_evolution_in_region (region
, loop
,
937 gimple_cond_lhs (stmt
));
938 tree rhs
= scalar_evolution_in_region (region
, loop
,
939 gimple_cond_rhs (stmt
));
941 scan_tree_for_params (region
, lhs
);
942 scan_tree_for_params (region
, rhs
);
946 /* Record the parameters used in the SCOP. A variable is a parameter
947 in a scop if it does not vary during the execution of that scop. */
950 find_scop_parameters (scop_p scop
)
954 sese region
= SCOP_REGION (scop
);
958 /* Find the parameters used in the loop bounds. */
959 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
961 tree nb_iters
= number_of_latch_executions (loop
);
963 if (!chrec_contains_symbols (nb_iters
))
966 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
967 scan_tree_for_params (region
, nb_iters
);
970 /* Find the parameters used in data accesses. */
971 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
972 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
974 nbp
= sese_nb_params (region
);
975 scop_set_nb_params (scop
, nbp
);
976 SESE_ADD_PARAMS (region
) = false;
980 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, nbp
, 0);
982 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, e
)
983 space
= isl_space_set_dim_id (space
, isl_dim_param
, i
,
984 isl_id_for_ssa_name (scop
, e
));
986 scop
->context
= isl_set_universe (space
);
990 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
991 the constraints for the surrounding loops. */
994 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
996 isl_set
*outer
, isl_set
**doms
)
998 tree nb_iters
= number_of_latch_executions (loop
);
999 sese region
= SCOP_REGION (scop
);
1001 isl_set
*inner
= isl_set_copy (outer
);
1004 int pos
= isl_set_dim (outer
, isl_dim_set
);
1010 inner
= isl_set_add_dims (inner
, isl_dim_set
, 1);
1011 space
= isl_set_get_space (inner
);
1014 c
= isl_inequality_alloc
1015 (isl_local_space_from_space (isl_space_copy (space
)));
1016 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, 1);
1017 inner
= isl_set_add_constraint (inner
, c
);
1019 /* loop_i <= cst_nb_iters */
1020 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
1022 c
= isl_inequality_alloc
1023 (isl_local_space_from_space (isl_space_copy (space
)));
1024 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1025 tree_int_to_gmp (nb_iters
, g
);
1026 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1027 c
= isl_constraint_set_constant_val (c
, v
);
1028 inner
= isl_set_add_constraint (inner
, c
);
1031 /* loop_i <= expr_nb_iters */
1032 else if (!chrec_contains_undetermined (nb_iters
))
1037 isl_local_space
*ls
;
1041 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
1043 aff
= extract_affine (scop
, nb_iters
, isl_set_get_space (inner
));
1044 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff
));
1045 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1046 isl_set_dim (valid
, isl_dim_set
));
1047 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1049 ls
= isl_local_space_from_space (isl_space_copy (space
));
1050 al
= isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls
),
1051 isl_dim_in
, pos
, 1);
1052 le
= isl_pw_aff_le_set (isl_pw_aff_from_aff (al
),
1053 isl_pw_aff_copy (aff
));
1054 inner
= isl_set_intersect (inner
, le
);
1056 if (max_stmt_executions (loop
, &nit
))
1058 /* Insert in the context the constraints from the
1059 estimation of the number of iterations NIT and the
1060 symbolic number of iterations (involving parameter
1061 names) NB_ITERS. First, build the affine expression
1062 "NIT - NB_ITERS" and then say that it is positive,
1063 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1070 wi::to_mpz (nit
, g
, SIGNED
);
1071 mpz_sub_ui (g
, g
, 1);
1072 approx
= extract_affine_gmp (g
, isl_set_get_space (inner
));
1073 x
= isl_pw_aff_ge_set (approx
, aff
);
1074 x
= isl_set_project_out (x
, isl_dim_set
, 0,
1075 isl_set_dim (x
, isl_dim_set
));
1076 scop
->context
= isl_set_intersect (scop
->context
, x
);
1078 c
= isl_inequality_alloc
1079 (isl_local_space_from_space (isl_space_copy (space
)));
1080 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1081 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1083 c
= isl_constraint_set_constant_val (c
, v
);
1084 inner
= isl_set_add_constraint (inner
, c
);
1087 isl_pw_aff_free (aff
);
1092 if (loop
->inner
&& loop_in_sese_p (loop
->inner
, region
))
1093 build_loop_iteration_domains (scop
, loop
->inner
, nb
+ 1,
1094 isl_set_copy (inner
), doms
);
1098 && loop_in_sese_p (loop
->next
, region
))
1099 build_loop_iteration_domains (scop
, loop
->next
, nb
,
1100 isl_set_copy (outer
), doms
);
1102 doms
[loop
->num
] = inner
;
1104 isl_set_free (outer
);
1105 isl_space_free (space
);
1109 /* Returns a linear expression for tree T evaluated in PBB. */
1112 create_pw_aff_from_tree (poly_bb_p pbb
, tree t
)
1114 scop_p scop
= PBB_SCOP (pbb
);
1116 t
= scalar_evolution_in_region (SCOP_REGION (scop
), pbb_loop (pbb
), t
);
1117 gcc_assert (!automatically_generated_chrec_p (t
));
1119 return extract_affine (scop
, t
, isl_set_get_space (pbb
->domain
));
1122 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1123 operator. This allows us to invert the condition or to handle
1127 add_condition_to_pbb (poly_bb_p pbb
, gcond
*stmt
, enum tree_code code
)
1129 isl_pw_aff
*lhs
= create_pw_aff_from_tree (pbb
, gimple_cond_lhs (stmt
));
1130 isl_pw_aff
*rhs
= create_pw_aff_from_tree (pbb
, gimple_cond_rhs (stmt
));
1136 cond
= isl_pw_aff_lt_set (lhs
, rhs
);
1140 cond
= isl_pw_aff_gt_set (lhs
, rhs
);
1144 cond
= isl_pw_aff_le_set (lhs
, rhs
);
1148 cond
= isl_pw_aff_ge_set (lhs
, rhs
);
1152 cond
= isl_pw_aff_eq_set (lhs
, rhs
);
1156 cond
= isl_pw_aff_ne_set (lhs
, rhs
);
1160 isl_pw_aff_free (lhs
);
1161 isl_pw_aff_free (rhs
);
1165 cond
= isl_set_coalesce (cond
);
1166 cond
= isl_set_set_tuple_id (cond
, isl_set_get_tuple_id (pbb
->domain
));
1167 pbb
->domain
= isl_set_intersect (pbb
->domain
, cond
);
1170 /* Add conditions to the domain of PBB. */
1173 add_conditions_to_domain (poly_bb_p pbb
)
1177 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1179 if (GBB_CONDITIONS (gbb
).is_empty ())
1182 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1183 switch (gimple_code (stmt
))
1187 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
1188 enum tree_code code
= gimple_cond_code (cond_stmt
);
1190 /* The conditions for ELSE-branches are inverted. */
1191 if (!GBB_CONDITION_CASES (gbb
)[i
])
1192 code
= invert_tree_comparison (code
, false);
1194 add_condition_to_pbb (pbb
, cond_stmt
, code
);
1199 /* Switch statements are not supported right now - fall through. */
1207 /* Traverses all the GBBs of the SCOP and add their constraints to the
1208 iteration domains. */
1211 add_conditions_to_constraints (scop_p scop
)
1216 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1217 add_conditions_to_domain (pbb
);
1220 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1221 edge between BB and its predecessor is not a loop exit edge, and
1222 the last statement of the single predecessor is a COND_EXPR. */
1225 single_pred_cond_non_loop_exit (basic_block bb
)
1227 if (single_pred_p (bb
))
1229 edge e
= single_pred_edge (bb
);
1230 basic_block pred
= e
->src
;
1233 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
1236 stmt
= last_stmt (pred
);
1238 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
1239 return as_a
<gcond
*> (stmt
);
1245 class sese_dom_walker
: public dom_walker
1248 sese_dom_walker (cdi_direction
, sese
);
1250 virtual void before_dom_children (basic_block
);
1251 virtual void after_dom_children (basic_block
);
1254 auto_vec
<gimple
, 3> m_conditions
, m_cases
;
1258 sese_dom_walker::sese_dom_walker (cdi_direction direction
, sese region
)
1259 : dom_walker (direction
), m_region (region
)
1263 /* Call-back for dom_walk executed before visiting the dominated
1267 sese_dom_walker::before_dom_children (basic_block bb
)
1272 if (!bb_in_sese_p (bb
, m_region
))
1275 stmt
= single_pred_cond_non_loop_exit (bb
);
1279 edge e
= single_pred_edge (bb
);
1281 m_conditions
.safe_push (stmt
);
1283 if (e
->flags
& EDGE_TRUE_VALUE
)
1284 m_cases
.safe_push (stmt
);
1286 m_cases
.safe_push (NULL
);
1289 gbb
= gbb_from_bb (bb
);
1293 GBB_CONDITIONS (gbb
) = m_conditions
.copy ();
1294 GBB_CONDITION_CASES (gbb
) = m_cases
.copy ();
1298 /* Call-back for dom_walk executed after visiting the dominated
1302 sese_dom_walker::after_dom_children (basic_block bb
)
1304 if (!bb_in_sese_p (bb
, m_region
))
1307 if (single_pred_cond_non_loop_exit (bb
))
1309 m_conditions
.pop ();
1314 /* Add constraints on the possible values of parameter P from the type
1318 add_param_constraints (scop_p scop
, graphite_dim_t p
)
1320 tree parameter
= SESE_PARAMS (SCOP_REGION (scop
))[p
];
1321 tree type
= TREE_TYPE (parameter
);
1322 tree lb
= NULL_TREE
;
1323 tree ub
= NULL_TREE
;
1325 if (POINTER_TYPE_P (type
) || !TYPE_MIN_VALUE (type
))
1326 lb
= lower_bound_in_type (type
, type
);
1328 lb
= TYPE_MIN_VALUE (type
);
1330 if (POINTER_TYPE_P (type
) || !TYPE_MAX_VALUE (type
))
1331 ub
= upper_bound_in_type (type
, type
);
1333 ub
= TYPE_MAX_VALUE (type
);
1337 isl_space
*space
= isl_set_get_space (scop
->context
);
1342 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1344 tree_int_to_gmp (lb
, g
);
1345 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1346 v
= isl_val_neg (v
);
1348 c
= isl_constraint_set_constant_val (c
, v
);
1349 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, 1);
1351 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1356 isl_space
*space
= isl_set_get_space (scop
->context
);
1361 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1364 tree_int_to_gmp (ub
, g
);
1365 v
= isl_val_int_from_gmp (the_isl_ctx
, g
);
1367 c
= isl_constraint_set_constant_val (c
, v
);
1368 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, -1);
1370 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1374 /* Build the context of the SCOP. The context usually contains extra
1375 constraints that are added to the iteration domains that constrain
1379 build_scop_context (scop_p scop
)
1381 graphite_dim_t p
, n
= scop_nb_params (scop
);
1383 for (p
= 0; p
< n
; p
++)
1384 add_param_constraints (scop
, p
);
1387 /* Build the iteration domains: the loops belonging to the current
1388 SCOP, and that vary for the execution of the current basic block.
1389 Returns false if there is no loop in SCOP. */
1392 build_scop_iteration_domain (scop_p scop
)
1395 sese region
= SCOP_REGION (scop
);
1398 int nb_loops
= number_of_loops (cfun
);
1399 isl_set
**doms
= XCNEWVEC (isl_set
*, nb_loops
);
1401 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1402 if (!loop_in_sese_p (loop_outer (loop
), region
))
1403 build_loop_iteration_domains (scop
, loop
, 0,
1404 isl_set_copy (scop
->context
), doms
);
1406 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1408 loop
= pbb_loop (pbb
);
1410 if (doms
[loop
->num
])
1411 pbb
->domain
= isl_set_copy (doms
[loop
->num
]);
1413 pbb
->domain
= isl_set_copy (scop
->context
);
1415 pbb
->domain
= isl_set_set_tuple_id (pbb
->domain
,
1416 isl_id_for_pbb (scop
, pbb
));
1419 for (i
= 0; i
< nb_loops
; i
++)
1421 isl_set_free (doms
[i
]);
1426 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1427 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1428 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1432 pdr_add_alias_set (isl_map
*acc
, data_reference_p dr
)
1435 int alias_set_num
= 0;
1436 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1438 if (bap
&& bap
->alias_set
)
1439 alias_set_num
= *(bap
->alias_set
);
1441 c
= isl_equality_alloc
1442 (isl_local_space_from_space (isl_map_get_space (acc
)));
1443 c
= isl_constraint_set_constant_si (c
, -alias_set_num
);
1444 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
1446 return isl_map_add_constraint (acc
, c
);
1449 /* Assign the affine expression INDEX to the output dimension POS of
1450 MAP and return the result. */
1453 set_index (isl_map
*map
, int pos
, isl_pw_aff
*index
)
1456 int len
= isl_map_dim (map
, isl_dim_out
);
1459 index_map
= isl_map_from_pw_aff (index
);
1460 index_map
= isl_map_insert_dims (index_map
, isl_dim_out
, 0, pos
);
1461 index_map
= isl_map_add_dims (index_map
, isl_dim_out
, len
- pos
- 1);
1463 id
= isl_map_get_tuple_id (map
, isl_dim_out
);
1464 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_out
, id
);
1465 id
= isl_map_get_tuple_id (map
, isl_dim_in
);
1466 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_in
, id
);
1468 return isl_map_intersect (map
, index_map
);
1471 /* Add to ACCESSES polyhedron equalities defining the access functions
1472 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1473 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1474 PBB is the poly_bb_p that contains the data reference DR. */
1477 pdr_add_memory_accesses (isl_map
*acc
, data_reference_p dr
, poly_bb_p pbb
)
1479 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1480 scop_p scop
= PBB_SCOP (pbb
);
1482 for (i
= 0; i
< nb_subscripts
; i
++)
1485 tree afn
= DR_ACCESS_FN (dr
, nb_subscripts
- 1 - i
);
1487 aff
= extract_affine (scop
, afn
,
1488 isl_space_domain (isl_map_get_space (acc
)));
1489 acc
= set_index (acc
, i
+ 1, aff
);
1495 /* Add constrains representing the size of the accessed data to the
1496 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1497 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1501 pdr_add_data_dimensions (isl_set
*extent
, scop_p scop
, data_reference_p dr
)
1503 tree ref
= DR_REF (dr
);
1504 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1506 for (i
= nb_subscripts
- 1; i
>= 0; i
--, ref
= TREE_OPERAND (ref
, 0))
1510 if (TREE_CODE (ref
) != ARRAY_REF
)
1513 low
= array_ref_low_bound (ref
);
1514 high
= array_ref_up_bound (ref
);
1516 /* XXX The PPL code dealt separately with
1517 subscript - low >= 0 and high - subscript >= 0 in case one of
1518 the two bounds isn't known. Do the same here? */
1520 if (tree_fits_shwi_p (low
)
1522 && tree_fits_shwi_p (high
)
1523 /* 1-element arrays at end of structures may extend over
1524 their declared size. */
1525 && !(array_at_struct_end_p (ref
)
1526 && operand_equal_p (low
, high
, 0)))
1530 isl_set
*univ
, *lbs
, *ubs
;
1534 isl_pw_aff
*lb
= extract_affine_int (low
, isl_set_get_space (extent
));
1535 isl_pw_aff
*ub
= extract_affine_int (high
, isl_set_get_space (extent
));
1538 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub
));
1539 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1540 isl_set_dim (valid
, isl_dim_set
));
1541 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1543 space
= isl_set_get_space (extent
);
1544 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
1545 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_in
, i
+ 1, 1);
1546 univ
= isl_set_universe (isl_space_domain (isl_aff_get_space (aff
)));
1547 index
= isl_pw_aff_alloc (univ
, aff
);
1549 id
= isl_set_get_tuple_id (extent
);
1550 lb
= isl_pw_aff_set_tuple_id (lb
, isl_dim_in
, isl_id_copy (id
));
1551 ub
= isl_pw_aff_set_tuple_id (ub
, isl_dim_in
, id
);
1553 /* low <= sub_i <= high */
1554 lbs
= isl_pw_aff_ge_set (isl_pw_aff_copy (index
), lb
);
1555 ubs
= isl_pw_aff_le_set (index
, ub
);
1556 extent
= isl_set_intersect (extent
, lbs
);
1557 extent
= isl_set_intersect (extent
, ubs
);
1564 /* Build data accesses for DR in PBB. */
1567 build_poly_dr (data_reference_p dr
, poly_bb_p pbb
)
1569 int dr_base_object_set
;
1572 scop_p scop
= PBB_SCOP (pbb
);
1575 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1576 int nb_out
= 1 + DR_NUM_DIMENSIONS (dr
);
1577 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1578 isl_dim_out
, nb_out
);
1580 acc
= isl_map_universe (space
);
1581 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, isl_id_for_dr (scop
, dr
));
1584 acc
= pdr_add_alias_set (acc
, dr
);
1585 acc
= pdr_add_memory_accesses (acc
, dr
, pbb
);
1588 isl_id
*id
= isl_id_for_dr (scop
, dr
);
1589 int nb
= 1 + DR_NUM_DIMENSIONS (dr
);
1590 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, 0, nb
);
1591 int alias_set_num
= 0;
1592 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1594 if (bap
&& bap
->alias_set
)
1595 alias_set_num
= *(bap
->alias_set
);
1597 space
= isl_space_set_tuple_id (space
, isl_dim_set
, id
);
1598 extent
= isl_set_nat_universe (space
);
1599 extent
= isl_set_fix_si (extent
, isl_dim_set
, 0, alias_set_num
);
1600 extent
= pdr_add_data_dimensions (extent
, scop
, dr
);
1603 gcc_assert (dr
->aux
);
1604 dr_base_object_set
= ((base_alias_pair
*)(dr
->aux
))->base_obj_set
;
1606 new_poly_dr (pbb
, dr_base_object_set
,
1607 DR_IS_READ (dr
) ? PDR_READ
: PDR_WRITE
,
1608 dr
, DR_NUM_DIMENSIONS (dr
), acc
, extent
);
1611 /* Write to FILE the alias graph of data references in DIMACS format. */
1614 write_alias_graph_to_ascii_dimacs (FILE *file
, char *comment
,
1615 vec
<data_reference_p
> drs
)
1617 int num_vertex
= drs
.length ();
1619 data_reference_p dr1
, dr2
;
1622 if (num_vertex
== 0)
1625 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1626 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1627 if (dr_may_alias_p (dr1
, dr2
, true))
1630 fprintf (file
, "$\n");
1633 fprintf (file
, "c %s\n", comment
);
1635 fprintf (file
, "p edge %d %d\n", num_vertex
, edge_num
);
1637 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1638 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1639 if (dr_may_alias_p (dr1
, dr2
, true))
1640 fprintf (file
, "e %d %d\n", i
+ 1, j
+ 1);
1645 /* Write to FILE the alias graph of data references in DOT format. */
1648 write_alias_graph_to_ascii_dot (FILE *file
, char *comment
,
1649 vec
<data_reference_p
> drs
)
1651 int num_vertex
= drs
.length ();
1652 data_reference_p dr1
, dr2
;
1655 if (num_vertex
== 0)
1658 fprintf (file
, "$\n");
1661 fprintf (file
, "c %s\n", comment
);
1663 /* First print all the vertices. */
1664 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1665 fprintf (file
, "n%d;\n", i
);
1667 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1668 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1669 if (dr_may_alias_p (dr1
, dr2
, true))
1670 fprintf (file
, "n%d n%d\n", i
, j
);
1675 /* Write to FILE the alias graph of data references in ECC format. */
1678 write_alias_graph_to_ascii_ecc (FILE *file
, char *comment
,
1679 vec
<data_reference_p
> drs
)
1681 int num_vertex
= drs
.length ();
1682 data_reference_p dr1
, dr2
;
1685 if (num_vertex
== 0)
1688 fprintf (file
, "$\n");
1691 fprintf (file
, "c %s\n", comment
);
1693 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1694 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1695 if (dr_may_alias_p (dr1
, dr2
, true))
1696 fprintf (file
, "%d %d\n", i
, j
);
1701 /* Check if DR1 and DR2 are in the same object set. */
1704 dr_same_base_object_p (const struct data_reference
*dr1
,
1705 const struct data_reference
*dr2
)
1707 return operand_equal_p (DR_BASE_OBJECT (dr1
), DR_BASE_OBJECT (dr2
), 0);
1710 /* Uses DFS component number as representative of alias-sets. Also tests for
1711 optimality by verifying if every connected component is a clique. Returns
1712 true (1) if the above test is true, and false (0) otherwise. */
1715 build_alias_set_optimal_p (vec
<data_reference_p
> drs
)
1717 int num_vertices
= drs
.length ();
1718 struct graph
*g
= new_graph (num_vertices
);
1719 data_reference_p dr1
, dr2
;
1721 int num_connected_components
;
1722 int v_indx1
, v_indx2
, num_vertices_in_component
;
1725 struct graph_edge
*e
;
1726 int this_component_is_clique
;
1727 int all_components_are_cliques
= 1;
1729 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1730 for (j
= i
+1; drs
.iterate (j
, &dr2
); j
++)
1731 if (dr_may_alias_p (dr1
, dr2
, true))
1737 all_vertices
= XNEWVEC (int, num_vertices
);
1738 vertices
= XNEWVEC (int, num_vertices
);
1739 for (i
= 0; i
< num_vertices
; i
++)
1740 all_vertices
[i
] = i
;
1742 num_connected_components
= graphds_dfs (g
, all_vertices
, num_vertices
,
1744 for (i
= 0; i
< g
->n_vertices
; i
++)
1746 data_reference_p dr
= drs
[i
];
1747 base_alias_pair
*bap
;
1749 gcc_assert (dr
->aux
);
1750 bap
= (base_alias_pair
*)(dr
->aux
);
1752 bap
->alias_set
= XNEW (int);
1753 *(bap
->alias_set
) = g
->vertices
[i
].component
+ 1;
1756 /* Verify if the DFS numbering results in optimal solution. */
1757 for (i
= 0; i
< num_connected_components
; i
++)
1759 num_vertices_in_component
= 0;
1760 /* Get all vertices whose DFS component number is the same as i. */
1761 for (j
= 0; j
< num_vertices
; j
++)
1762 if (g
->vertices
[j
].component
== i
)
1763 vertices
[num_vertices_in_component
++] = j
;
1765 /* Now test if the vertices in 'vertices' form a clique, by testing
1766 for edges among each pair. */
1767 this_component_is_clique
= 1;
1768 for (v_indx1
= 0; v_indx1
< num_vertices_in_component
; v_indx1
++)
1770 for (v_indx2
= v_indx1
+1; v_indx2
< num_vertices_in_component
; v_indx2
++)
1772 /* Check if the two vertices are connected by iterating
1773 through all the edges which have one of these are source. */
1774 e
= g
->vertices
[vertices
[v_indx2
]].pred
;
1777 if (e
->src
== vertices
[v_indx1
])
1783 this_component_is_clique
= 0;
1787 if (!this_component_is_clique
)
1788 all_components_are_cliques
= 0;
1792 free (all_vertices
);
1795 return all_components_are_cliques
;
1798 /* Group each data reference in DRS with its base object set num. */
1801 build_base_obj_set_for_drs (vec
<data_reference_p
> drs
)
1803 int num_vertex
= drs
.length ();
1804 struct graph
*g
= new_graph (num_vertex
);
1805 data_reference_p dr1
, dr2
;
1809 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1810 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1811 if (dr_same_base_object_p (dr1
, dr2
))
1817 queue
= XNEWVEC (int, num_vertex
);
1818 for (i
= 0; i
< num_vertex
; i
++)
1821 graphds_dfs (g
, queue
, num_vertex
, NULL
, true, NULL
);
1823 for (i
= 0; i
< g
->n_vertices
; i
++)
1825 data_reference_p dr
= drs
[i
];
1826 base_alias_pair
*bap
;
1828 gcc_assert (dr
->aux
);
1829 bap
= (base_alias_pair
*)(dr
->aux
);
1831 bap
->base_obj_set
= g
->vertices
[i
].component
+ 1;
1838 /* Build the data references for PBB. */
1841 build_pbb_drs (poly_bb_p pbb
)
1844 data_reference_p dr
;
1845 vec
<data_reference_p
> gbb_drs
= GBB_DATA_REFS (PBB_BLACK_BOX (pbb
));
1847 FOR_EACH_VEC_ELT (gbb_drs
, j
, dr
)
1848 build_poly_dr (dr
, pbb
);
1851 /* Dump to file the alias graphs for the data references in DRS. */
1854 dump_alias_graphs (vec
<data_reference_p
> drs
)
1857 FILE *file_dimacs
, *file_ecc
, *file_dot
;
1859 file_dimacs
= fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1862 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1863 current_function_name ());
1864 write_alias_graph_to_ascii_dimacs (file_dimacs
, comment
, drs
);
1865 fclose (file_dimacs
);
1868 file_ecc
= fopen ("/tmp/dr_alias_graph_ecc", "ab");
1871 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1872 current_function_name ());
1873 write_alias_graph_to_ascii_ecc (file_ecc
, comment
, drs
);
1877 file_dot
= fopen ("/tmp/dr_alias_graph_dot", "ab");
1880 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1881 current_function_name ());
1882 write_alias_graph_to_ascii_dot (file_dot
, comment
, drs
);
1887 /* Build data references in SCOP. */
1890 build_scop_drs (scop_p scop
)
1894 data_reference_p dr
;
1895 auto_vec
<data_reference_p
, 3> drs
;
1897 /* Remove all the PBBs that do not have data references: these basic
1898 blocks are not handled in the polyhedral representation. */
1899 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1900 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).is_empty ())
1902 free_gimple_bb (PBB_BLACK_BOX (pbb
));
1904 SCOP_BBS (scop
).ordered_remove (i
);
1908 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1909 for (j
= 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).iterate (j
, &dr
); j
++)
1912 FOR_EACH_VEC_ELT (drs
, i
, dr
)
1913 dr
->aux
= XNEW (base_alias_pair
);
1915 if (!build_alias_set_optimal_p (drs
))
1917 /* TODO: Add support when building alias set is not optimal. */
1921 build_base_obj_set_for_drs (drs
);
1923 /* When debugging, enable the following code. This cannot be used
1924 in production compilers. */
1926 dump_alias_graphs (drs
);
1930 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1931 build_pbb_drs (pbb
);
1934 /* Return a gsi at the position of the phi node STMT. */
1936 static gphi_iterator
1937 gsi_for_phi_node (gphi
*stmt
)
1940 basic_block bb
= gimple_bb (stmt
);
1942 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
1943 if (stmt
== psi
.phi ())
1950 /* Analyze all the data references of STMTS and add them to the
1951 GBB_DATA_REFS vector of BB. */
1954 analyze_drs_in_stmts (scop_p scop
, basic_block bb
, vec
<gimple
> stmts
)
1960 sese region
= SCOP_REGION (scop
);
1962 if (!bb_in_sese_p (bb
, region
))
1965 nest
= outermost_loop_in_sese_1 (region
, bb
);
1966 gbb
= gbb_from_bb (bb
);
1968 FOR_EACH_VEC_ELT (stmts
, i
, stmt
)
1972 if (is_gimple_debug (stmt
))
1975 loop
= loop_containing_stmt (stmt
);
1976 if (!loop_in_sese_p (loop
, region
))
1979 graphite_find_data_references_in_stmt (nest
, loop
, stmt
,
1980 &GBB_DATA_REFS (gbb
));
1984 /* Insert STMT at the end of the STMTS sequence and then insert the
1985 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1989 insert_stmts (scop_p scop
, gimple stmt
, gimple_seq stmts
,
1990 gimple_stmt_iterator insert_gsi
)
1992 gimple_stmt_iterator gsi
;
1993 auto_vec
<gimple
, 3> x
;
1995 gimple_seq_add_stmt (&stmts
, stmt
);
1996 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1997 x
.safe_push (gsi_stmt (gsi
));
1999 gsi_insert_seq_before (&insert_gsi
, stmts
, GSI_SAME_STMT
);
2000 analyze_drs_in_stmts (scop
, gsi_bb (insert_gsi
), x
);
2003 /* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
2006 insert_out_of_ssa_copy (scop_p scop
, tree res
, tree expr
, gimple after_stmt
)
2009 gimple_stmt_iterator gsi
;
2010 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2011 gassign
*stmt
= gimple_build_assign (unshare_expr (res
), var
);
2012 auto_vec
<gimple
, 3> x
;
2014 gimple_seq_add_stmt (&stmts
, stmt
);
2015 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2016 x
.safe_push (gsi_stmt (gsi
));
2018 if (gimple_code (after_stmt
) == GIMPLE_PHI
)
2020 gsi
= gsi_after_labels (gimple_bb (after_stmt
));
2021 gsi_insert_seq_before (&gsi
, stmts
, GSI_NEW_STMT
);
2025 gsi
= gsi_for_stmt (after_stmt
);
2026 gsi_insert_seq_after (&gsi
, stmts
, GSI_NEW_STMT
);
2029 analyze_drs_in_stmts (scop
, gimple_bb (after_stmt
), x
);
2032 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2035 new_pbb_from_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
)
2037 vec
<data_reference_p
> drs
;
2039 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
2040 gimple_bb_p gbb1
= new_gimple_bb (bb
, drs
);
2041 poly_bb_p pbb1
= new_poly_bb (scop
, gbb1
);
2042 int index
, n
= SCOP_BBS (scop
).length ();
2044 /* The INDEX of PBB in SCOP_BBS. */
2045 for (index
= 0; index
< n
; index
++)
2046 if (SCOP_BBS (scop
)[index
] == pbb
)
2049 pbb1
->domain
= isl_set_copy (pbb
->domain
);
2050 pbb1
->domain
= isl_set_set_tuple_id (pbb1
->domain
,
2051 isl_id_for_pbb (scop
, pbb1
));
2053 GBB_PBB (gbb1
) = pbb1
;
2054 GBB_CONDITIONS (gbb1
) = GBB_CONDITIONS (gbb
).copy ();
2055 GBB_CONDITION_CASES (gbb1
) = GBB_CONDITION_CASES (gbb
).copy ();
2056 SCOP_BBS (scop
).safe_insert (index
+ 1, pbb1
);
2059 /* Insert on edge E the assignment "RES := EXPR". */
2062 insert_out_of_ssa_copy_on_edge (scop_p scop
, edge e
, tree res
, tree expr
)
2064 gimple_stmt_iterator gsi
;
2065 gimple_seq stmts
= NULL
;
2066 tree var
= force_gimple_operand (expr
, &stmts
, true, NULL_TREE
);
2067 gimple stmt
= gimple_build_assign (unshare_expr (res
), var
);
2069 auto_vec
<gimple
, 3> x
;
2071 gimple_seq_add_stmt (&stmts
, stmt
);
2072 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2073 x
.safe_push (gsi_stmt (gsi
));
2075 gsi_insert_seq_on_edge (e
, stmts
);
2076 gsi_commit_edge_inserts ();
2077 bb
= gimple_bb (stmt
);
2079 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
2082 if (!gbb_from_bb (bb
))
2083 new_pbb_from_pbb (scop
, pbb_from_bb (e
->src
), bb
);
2085 analyze_drs_in_stmts (scop
, bb
, x
);
2088 /* Creates a zero dimension array of the same type as VAR. */
2091 create_zero_dim_array (tree var
, const char *base_name
)
2093 tree index_type
= build_index_type (integer_zero_node
);
2094 tree elt_type
= TREE_TYPE (var
);
2095 tree array_type
= build_array_type (elt_type
, index_type
);
2096 tree base
= create_tmp_var (array_type
, base_name
);
2098 return build4 (ARRAY_REF
, elt_type
, base
, integer_zero_node
, NULL_TREE
,
2102 /* Returns true when PHI is a loop close phi node. */
2105 scalar_close_phi_node_p (gimple phi
)
2107 if (gimple_code (phi
) != GIMPLE_PHI
2108 || virtual_operand_p (gimple_phi_result (phi
)))
2111 /* Note that loop close phi nodes should have a single argument
2112 because we translated the representation into a canonical form
2113 before Graphite: see canonicalize_loop_closed_ssa_form. */
2114 return (gimple_phi_num_args (phi
) == 1);
2117 /* For a definition DEF in REGION, propagates the expression EXPR in
2118 all the uses of DEF outside REGION. */
2121 propagate_expr_outside_region (tree def
, tree expr
, sese region
)
2123 imm_use_iterator imm_iter
;
2126 bool replaced_once
= false;
2128 gcc_assert (TREE_CODE (def
) == SSA_NAME
);
2130 expr
= force_gimple_operand (unshare_expr (expr
), &stmts
, true,
2133 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2134 if (!is_gimple_debug (use_stmt
)
2135 && !bb_in_sese_p (gimple_bb (use_stmt
), region
))
2138 use_operand_p use_p
;
2140 FOR_EACH_PHI_OR_STMT_USE (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2141 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0)
2142 && (replaced_once
= true))
2143 replace_exp (use_p
, expr
);
2145 update_stmt (use_stmt
);
2150 gsi_insert_seq_on_edge (SESE_ENTRY (region
), stmts
);
2151 gsi_commit_edge_inserts ();
2155 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2156 dimension array for it. */
2159 rewrite_close_phi_out_of_ssa (scop_p scop
, gimple_stmt_iterator
*psi
)
2161 sese region
= SCOP_REGION (scop
);
2162 gimple phi
= gsi_stmt (*psi
);
2163 tree res
= gimple_phi_result (phi
);
2164 basic_block bb
= gimple_bb (phi
);
2165 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
2166 tree arg
= gimple_phi_arg_def (phi
, 0);
2169 /* Note that loop close phi nodes should have a single argument
2170 because we translated the representation into a canonical form
2171 before Graphite: see canonicalize_loop_closed_ssa_form. */
2172 gcc_assert (gimple_phi_num_args (phi
) == 1);
2174 /* The phi node can be a non close phi node, when its argument is
2175 invariant, or a default definition. */
2176 if (is_gimple_min_invariant (arg
)
2177 || SSA_NAME_IS_DEFAULT_DEF (arg
))
2179 propagate_expr_outside_region (res
, arg
, region
);
2184 else if (gimple_bb (SSA_NAME_DEF_STMT (arg
))->loop_father
== bb
->loop_father
)
2186 propagate_expr_outside_region (res
, arg
, region
);
2187 stmt
= gimple_build_assign (res
, arg
);
2188 remove_phi_node (psi
, false);
2189 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2193 /* If res is scev analyzable and is not a scalar value, it is safe
2194 to ignore the close phi node: it will be code generated in the
2195 out of Graphite pass. */
2196 else if (scev_analyzable_p (res
, region
))
2198 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (res
));
2201 if (!loop_in_sese_p (loop
, region
))
2203 loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2204 scev
= scalar_evolution_in_region (region
, loop
, arg
);
2205 scev
= compute_overall_effect_of_inner_loop (loop
, scev
);
2208 scev
= scalar_evolution_in_region (region
, loop
, res
);
2210 if (tree_does_not_contain_chrecs (scev
))
2211 propagate_expr_outside_region (res
, scev
, region
);
2218 tree zero_dim_array
= create_zero_dim_array (res
, "Close_Phi");
2220 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2222 if (TREE_CODE (arg
) == SSA_NAME
)
2223 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2224 SSA_NAME_DEF_STMT (arg
));
2226 insert_out_of_ssa_copy_on_edge (scop
, single_pred_edge (bb
),
2227 zero_dim_array
, arg
);
2230 remove_phi_node (psi
, false);
2231 SSA_NAME_DEF_STMT (res
) = stmt
;
2233 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2236 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2237 dimension array for it. */
2240 rewrite_phi_out_of_ssa (scop_p scop
, gphi_iterator
*psi
)
2243 gphi
*phi
= psi
->phi ();
2244 basic_block bb
= gimple_bb (phi
);
2245 tree res
= gimple_phi_result (phi
);
2246 tree zero_dim_array
= create_zero_dim_array (res
, "phi_out_of_ssa");
2249 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2251 tree arg
= gimple_phi_arg_def (phi
, i
);
2252 edge e
= gimple_phi_arg_edge (phi
, i
);
2254 /* Avoid the insertion of code in the loop latch to please the
2255 pattern matching of the vectorizer. */
2256 if (TREE_CODE (arg
) == SSA_NAME
2257 && !SSA_NAME_IS_DEFAULT_DEF (arg
)
2258 && e
->src
== bb
->loop_father
->latch
)
2259 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2260 SSA_NAME_DEF_STMT (arg
));
2262 insert_out_of_ssa_copy_on_edge (scop
, e
, zero_dim_array
, arg
);
2265 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2266 remove_phi_node (psi
, false);
2267 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2270 /* Rewrite the degenerate phi node at position PSI from the degenerate
2271 form "x = phi (y, y, ..., y)" to "x = y". */
2274 rewrite_degenerate_phi (gphi_iterator
*psi
)
2278 gimple_stmt_iterator gsi
;
2279 gphi
*phi
= psi
->phi ();
2280 tree res
= gimple_phi_result (phi
);
2283 bb
= gimple_bb (phi
);
2284 rhs
= degenerate_phi_result (phi
);
2287 stmt
= gimple_build_assign (res
, rhs
);
2288 remove_phi_node (psi
, false);
2290 gsi
= gsi_after_labels (bb
);
2291 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2294 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2297 rewrite_reductions_out_of_ssa (scop_p scop
)
2301 sese region
= SCOP_REGION (scop
);
2303 FOR_EACH_BB_FN (bb
, cfun
)
2304 if (bb_in_sese_p (bb
, region
))
2305 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);)
2307 gphi
*phi
= psi
.phi ();
2309 if (virtual_operand_p (gimple_phi_result (phi
)))
2315 if (gimple_phi_num_args (phi
) > 1
2316 && degenerate_phi_result (phi
))
2317 rewrite_degenerate_phi (&psi
);
2319 else if (scalar_close_phi_node_p (phi
))
2320 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2322 else if (reduction_phi_p (region
, &psi
))
2323 rewrite_phi_out_of_ssa (scop
, &psi
);
2326 update_ssa (TODO_update_ssa
);
2327 #ifdef ENABLE_CHECKING
2328 verify_loop_closed_ssa (true);
2332 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2333 read from ZERO_DIM_ARRAY. */
2336 rewrite_cross_bb_scalar_dependence (scop_p scop
, tree zero_dim_array
,
2337 tree def
, gimple use_stmt
)
2342 use_operand_p use_p
;
2344 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
2346 name
= copy_ssa_name (def
);
2347 name_stmt
= gimple_build_assign (name
, zero_dim_array
);
2349 gimple_assign_set_lhs (name_stmt
, name
);
2350 insert_stmts (scop
, name_stmt
, NULL
, gsi_for_stmt (use_stmt
));
2352 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2353 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0))
2354 replace_exp (use_p
, name
);
2356 update_stmt (use_stmt
);
2359 /* For every definition DEF in the SCOP that is used outside the scop,
2360 insert a closing-scop definition in the basic block just after this
2364 handle_scalar_deps_crossing_scop_limits (scop_p scop
, tree def
, gimple stmt
)
2366 tree var
= create_tmp_reg (TREE_TYPE (def
));
2367 tree new_name
= make_ssa_name (var
, stmt
);
2368 bool needs_copy
= false;
2369 use_operand_p use_p
;
2370 imm_use_iterator imm_iter
;
2372 sese region
= SCOP_REGION (scop
);
2374 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2376 if (!bb_in_sese_p (gimple_bb (use_stmt
), region
))
2378 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
2380 SET_USE (use_p
, new_name
);
2382 update_stmt (use_stmt
);
2387 /* Insert in the empty BB just after the scop a use of DEF such
2388 that the rewrite of cross_bb_scalar_dependences won't insert
2389 arrays everywhere else. */
2392 gimple assign
= gimple_build_assign (new_name
, def
);
2393 gimple_stmt_iterator psi
= gsi_after_labels (SESE_EXIT (region
)->dest
);
2395 update_stmt (assign
);
2396 gsi_insert_before (&psi
, assign
, GSI_SAME_STMT
);
2400 /* Rewrite the scalar dependences crossing the boundary of the BB
2401 containing STMT with an array. Return true when something has been
2405 rewrite_cross_bb_scalar_deps (scop_p scop
, gimple_stmt_iterator
*gsi
)
2407 sese region
= SCOP_REGION (scop
);
2408 gimple stmt
= gsi_stmt (*gsi
);
2409 imm_use_iterator imm_iter
;
2412 tree zero_dim_array
= NULL_TREE
;
2416 switch (gimple_code (stmt
))
2419 def
= gimple_assign_lhs (stmt
);
2423 def
= gimple_call_lhs (stmt
);
2431 || !is_gimple_reg (def
))
2434 if (scev_analyzable_p (def
, region
))
2436 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (def
));
2437 tree scev
= scalar_evolution_in_region (region
, loop
, def
);
2439 if (tree_contains_chrecs (scev
, NULL
))
2442 propagate_expr_outside_region (def
, scev
, region
);
2446 def_bb
= gimple_bb (stmt
);
2448 handle_scalar_deps_crossing_scop_limits (scop
, def
, stmt
);
2450 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2451 if (gimple_code (use_stmt
) == GIMPLE_PHI
2454 gphi_iterator psi
= gsi_start_phis (gimple_bb (use_stmt
));
2456 if (scalar_close_phi_node_p (gsi_stmt (psi
)))
2457 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2459 rewrite_phi_out_of_ssa (scop
, &psi
);
2462 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2463 if (gimple_code (use_stmt
) != GIMPLE_PHI
2464 && def_bb
!= gimple_bb (use_stmt
)
2465 && !is_gimple_debug (use_stmt
)
2468 if (!zero_dim_array
)
2470 zero_dim_array
= create_zero_dim_array
2471 (def
, "Cross_BB_scalar_dependence");
2472 insert_out_of_ssa_copy (scop
, zero_dim_array
, def
,
2473 SSA_NAME_DEF_STMT (def
));
2477 rewrite_cross_bb_scalar_dependence (scop
, unshare_expr (zero_dim_array
),
2484 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2487 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop
)
2490 gimple_stmt_iterator psi
;
2491 sese region
= SCOP_REGION (scop
);
2492 bool changed
= false;
2494 /* Create an extra empty BB after the scop. */
2495 split_edge (SESE_EXIT (region
));
2497 FOR_EACH_BB_FN (bb
, cfun
)
2498 if (bb_in_sese_p (bb
, region
))
2499 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
2500 changed
|= rewrite_cross_bb_scalar_deps (scop
, &psi
);
2505 update_ssa (TODO_update_ssa
);
2506 #ifdef ENABLE_CHECKING
2507 verify_loop_closed_ssa (true);
2512 /* Returns the number of pbbs that are in loops contained in SCOP. */
2515 nb_pbbs_in_loops (scop_p scop
)
2521 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
2522 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), SCOP_REGION (scop
)))
2528 /* Return the number of data references in BB that write in
2532 nb_data_writes_in_bb (basic_block bb
)
2535 gimple_stmt_iterator gsi
;
2537 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2538 if (gimple_vdef (gsi_stmt (gsi
)))
2544 /* Splits at STMT the basic block BB represented as PBB in the
2548 split_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
, gimple stmt
)
2550 edge e1
= split_block (bb
, stmt
);
2551 new_pbb_from_pbb (scop
, pbb
, e1
->dest
);
2555 /* Splits STMT out of its current BB. This is done for reduction
2556 statements for which we want to ignore data dependences. */
2559 split_reduction_stmt (scop_p scop
, gimple stmt
)
2561 basic_block bb
= gimple_bb (stmt
);
2562 poly_bb_p pbb
= pbb_from_bb (bb
);
2563 gimple_bb_p gbb
= gbb_from_bb (bb
);
2566 data_reference_p dr
;
2568 /* Do not split basic blocks with no writes to memory: the reduction
2569 will be the only write to memory. */
2570 if (nb_data_writes_in_bb (bb
) == 0
2571 /* Or if we have already marked BB as a reduction. */
2572 || PBB_IS_REDUCTION (pbb_from_bb (bb
)))
2575 e1
= split_pbb (scop
, pbb
, bb
, stmt
);
2577 /* Split once more only when the reduction stmt is not the only one
2578 left in the original BB. */
2579 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb
)))
2581 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
2583 e1
= split_pbb (scop
, pbb
, bb
, gsi_stmt (gsi
));
2586 /* A part of the data references will end in a different basic block
2587 after the split: move the DRs from the original GBB to the newly
2589 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
2591 basic_block bb1
= gimple_bb (DR_STMT (dr
));
2595 gimple_bb_p gbb1
= gbb_from_bb (bb1
);
2596 GBB_DATA_REFS (gbb1
).safe_push (dr
);
2597 GBB_DATA_REFS (gbb
).ordered_remove (i
);
2605 /* Return true when stmt is a reduction operation. */
2608 is_reduction_operation_p (gimple stmt
)
2610 enum tree_code code
;
2612 gcc_assert (is_gimple_assign (stmt
));
2613 code
= gimple_assign_rhs_code (stmt
);
2615 return flag_associative_math
2616 && commutative_tree_code (code
)
2617 && associative_tree_code (code
);
2620 /* Returns true when PHI contains an argument ARG. */
2623 phi_contains_arg (gphi
*phi
, tree arg
)
2627 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2628 if (operand_equal_p (arg
, gimple_phi_arg_def (phi
, i
), 0))
2634 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2637 follow_ssa_with_commutative_ops (tree arg
, tree lhs
)
2641 if (TREE_CODE (arg
) != SSA_NAME
)
2644 stmt
= SSA_NAME_DEF_STMT (arg
);
2646 if (gimple_code (stmt
) == GIMPLE_NOP
2647 || gimple_code (stmt
) == GIMPLE_CALL
)
2650 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2652 if (phi_contains_arg (phi
, lhs
))
2657 if (!is_gimple_assign (stmt
))
2660 if (gimple_num_ops (stmt
) == 2)
2661 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2663 if (is_reduction_operation_p (stmt
))
2666 = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2669 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt
), lhs
);
2675 /* Detect commutative and associative scalar reductions starting at
2676 the STMT. Return the phi node of the reduction cycle, or NULL. */
2679 detect_commutative_reduction_arg (tree lhs
, gimple stmt
, tree arg
,
2683 gphi
*phi
= follow_ssa_with_commutative_ops (arg
, lhs
);
2688 in
->safe_push (stmt
);
2689 out
->safe_push (stmt
);
2693 /* Detect commutative and associative scalar reductions starting at
2694 STMT. Return the phi node of the reduction cycle, or NULL. */
2697 detect_commutative_reduction_assign (gimple stmt
, vec
<gimple
> *in
,
2700 tree lhs
= gimple_assign_lhs (stmt
);
2702 if (gimple_num_ops (stmt
) == 2)
2703 return detect_commutative_reduction_arg (lhs
, stmt
,
2704 gimple_assign_rhs1 (stmt
),
2707 if (is_reduction_operation_p (stmt
))
2709 gphi
*res
= detect_commutative_reduction_arg (lhs
, stmt
,
2710 gimple_assign_rhs1 (stmt
),
2713 : detect_commutative_reduction_arg (lhs
, stmt
,
2714 gimple_assign_rhs2 (stmt
),
2721 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2724 follow_inital_value_to_phi (tree arg
, tree lhs
)
2728 if (!arg
|| TREE_CODE (arg
) != SSA_NAME
)
2731 stmt
= SSA_NAME_DEF_STMT (arg
);
2733 if (gphi
*phi
= dyn_cast
<gphi
*> (stmt
))
2734 if (phi_contains_arg (phi
, lhs
))
2741 /* Return the argument of the loop PHI that is the initial value coming
2742 from outside the loop. */
2745 edge_initial_value_for_loop_phi (gphi
*phi
)
2749 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2751 edge e
= gimple_phi_arg_edge (phi
, i
);
2753 if (loop_depth (e
->src
->loop_father
)
2754 < loop_depth (e
->dest
->loop_father
))
2761 /* Return the argument of the loop PHI that is the initial value coming
2762 from outside the loop. */
2765 initial_value_for_loop_phi (gphi
*phi
)
2769 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2771 edge e
= gimple_phi_arg_edge (phi
, i
);
2773 if (loop_depth (e
->src
->loop_father
)
2774 < loop_depth (e
->dest
->loop_father
))
2775 return gimple_phi_arg_def (phi
, i
);
2781 /* Returns true when DEF is used outside the reduction cycle of
2785 used_outside_reduction (tree def
, gimple loop_phi
)
2787 use_operand_p use_p
;
2788 imm_use_iterator imm_iter
;
2789 loop_p loop
= loop_containing_stmt (loop_phi
);
2791 /* In LOOP, DEF should be used only in LOOP_PHI. */
2792 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2794 gimple stmt
= USE_STMT (use_p
);
2796 if (stmt
!= loop_phi
2797 && !is_gimple_debug (stmt
)
2798 && flow_bb_inside_loop_p (loop
, gimple_bb (stmt
)))
2805 /* Detect commutative and associative scalar reductions belonging to
2806 the SCOP starting at the loop closed phi node STMT. Return the phi
2807 node of the reduction cycle, or NULL. */
2810 detect_commutative_reduction (scop_p scop
, gimple stmt
, vec
<gimple
> *in
,
2813 if (scalar_close_phi_node_p (stmt
))
2816 gphi
*loop_phi
, *phi
, *close_phi
= as_a
<gphi
*> (stmt
);
2817 tree init
, lhs
, arg
= gimple_phi_arg_def (close_phi
, 0);
2819 if (TREE_CODE (arg
) != SSA_NAME
)
2822 /* Note that loop close phi nodes should have a single argument
2823 because we translated the representation into a canonical form
2824 before Graphite: see canonicalize_loop_closed_ssa_form. */
2825 gcc_assert (gimple_phi_num_args (close_phi
) == 1);
2827 def
= SSA_NAME_DEF_STMT (arg
);
2828 if (!stmt_in_sese_p (def
, SCOP_REGION (scop
))
2829 || !(loop_phi
= detect_commutative_reduction (scop
, def
, in
, out
)))
2832 lhs
= gimple_phi_result (close_phi
);
2833 init
= initial_value_for_loop_phi (loop_phi
);
2834 phi
= follow_inital_value_to_phi (init
, lhs
);
2836 if (phi
&& (used_outside_reduction (lhs
, phi
)
2837 || !has_single_use (gimple_phi_result (phi
))))
2840 in
->safe_push (loop_phi
);
2841 out
->safe_push (close_phi
);
2845 if (gimple_code (stmt
) == GIMPLE_ASSIGN
)
2846 return detect_commutative_reduction_assign (stmt
, in
, out
);
2851 /* Translate the scalar reduction statement STMT to an array RED
2852 knowing that its recursive phi node is LOOP_PHI. */
2855 translate_scalar_reduction_to_array_for_stmt (scop_p scop
, tree red
,
2856 gimple stmt
, gphi
*loop_phi
)
2858 tree res
= gimple_phi_result (loop_phi
);
2859 gassign
*assign
= gimple_build_assign (res
, unshare_expr (red
));
2860 gimple_stmt_iterator gsi
;
2862 insert_stmts (scop
, assign
, NULL
, gsi_after_labels (gimple_bb (loop_phi
)));
2864 assign
= gimple_build_assign (unshare_expr (red
), gimple_assign_lhs (stmt
));
2865 gsi
= gsi_for_stmt (stmt
);
2867 insert_stmts (scop
, assign
, NULL
, gsi
);
2870 /* Removes the PHI node and resets all the debug stmts that are using
2874 remove_phi (gphi
*phi
)
2876 imm_use_iterator imm_iter
;
2878 use_operand_p use_p
;
2879 gimple_stmt_iterator gsi
;
2880 auto_vec
<gimple
, 3> update
;
2884 def
= PHI_RESULT (phi
);
2885 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2887 stmt
= USE_STMT (use_p
);
2889 if (is_gimple_debug (stmt
))
2891 gimple_debug_bind_reset_value (stmt
);
2892 update
.safe_push (stmt
);
2896 FOR_EACH_VEC_ELT (update
, i
, stmt
)
2899 gsi
= gsi_for_phi_node (phi
);
2900 remove_phi_node (&gsi
, false);
2903 /* Helper function for for_each_index. For each INDEX of the data
2904 reference REF, returns true when its indices are valid in the loop
2905 nest LOOP passed in as DATA. */
2908 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED
, tree
*index
, void *data
)
2911 basic_block header
, def_bb
;
2914 if (TREE_CODE (*index
) != SSA_NAME
)
2917 loop
= *((loop_p
*) data
);
2918 header
= loop
->header
;
2919 stmt
= SSA_NAME_DEF_STMT (*index
);
2924 def_bb
= gimple_bb (stmt
);
2929 return dominated_by_p (CDI_DOMINATORS
, header
, def_bb
);
2932 /* When the result of a CLOSE_PHI is written to a memory location,
2933 return a pointer to that memory reference, otherwise return
2937 close_phi_written_to_memory (gphi
*close_phi
)
2939 imm_use_iterator imm_iter
;
2940 use_operand_p use_p
;
2942 tree res
, def
= gimple_phi_result (close_phi
);
2944 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2945 if ((stmt
= USE_STMT (use_p
))
2946 && gimple_code (stmt
) == GIMPLE_ASSIGN
2947 && (res
= gimple_assign_lhs (stmt
)))
2949 switch (TREE_CODE (res
))
2959 tree arg
= gimple_phi_arg_def (close_phi
, 0);
2960 loop_p nest
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2962 /* FIXME: this restriction is for id-{24,25}.f and
2963 could be handled by duplicating the computation of
2964 array indices before the loop of the close_phi. */
2965 if (for_each_index (&res
, dr_indices_valid_in_loop
, &nest
))
2977 /* Rewrite out of SSA the reduction described by the loop phi nodes
2978 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2981 IN: stmt, loop_n, ..., loop_0
2982 OUT: stmt, close_n, ..., close_0
2984 the first element is the reduction statement, and the next elements
2985 are the loop and close phi nodes of each of the outer loops. */
2988 translate_scalar_reduction_to_array (scop_p scop
,
2993 unsigned int i
= out
.length () - 1;
2994 tree red
= close_phi_written_to_memory (as_a
<gphi
*> (out
[i
]));
2996 FOR_EACH_VEC_ELT (in
, i
, loop_stmt
)
2998 gimple close_stmt
= out
[i
];
3002 basic_block bb
= split_reduction_stmt (scop
, loop_stmt
);
3003 poly_bb_p pbb
= pbb_from_bb (bb
);
3004 PBB_IS_REDUCTION (pbb
) = true;
3005 gcc_assert (close_stmt
== loop_stmt
);
3008 red
= create_zero_dim_array
3009 (gimple_assign_lhs (loop_stmt
), "Commutative_Associative_Reduction");
3011 translate_scalar_reduction_to_array_for_stmt (scop
, red
, loop_stmt
,
3012 as_a
<gphi
*> (in
[1]));
3016 gphi
*loop_phi
= as_a
<gphi
*> (loop_stmt
);
3017 gphi
*close_phi
= as_a
<gphi
*> (close_stmt
);
3019 if (i
== in
.length () - 1)
3021 insert_out_of_ssa_copy (scop
, gimple_phi_result (close_phi
),
3022 unshare_expr (red
), close_phi
);
3023 insert_out_of_ssa_copy_on_edge
3024 (scop
, edge_initial_value_for_loop_phi (loop_phi
),
3025 unshare_expr (red
), initial_value_for_loop_phi (loop_phi
));
3028 remove_phi (loop_phi
);
3029 remove_phi (close_phi
);
3033 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3034 true when something has been changed. */
3037 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop
,
3041 auto_vec
<gimple
, 10> in
;
3042 auto_vec
<gimple
, 10> out
;
3044 detect_commutative_reduction (scop
, close_phi
, &in
, &out
);
3045 res
= in
.length () > 1;
3047 translate_scalar_reduction_to_array (scop
, in
, out
);
3052 /* Rewrites all the commutative reductions from LOOP out of SSA.
3053 Returns true when something has been changed. */
3056 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop
,
3060 edge exit
= single_exit (loop
);
3062 bool changed
= false;
3067 for (gsi
= gsi_start_phis (exit
->dest
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3068 if ((res
= gimple_phi_result (gsi
.phi ()))
3069 && !virtual_operand_p (res
)
3070 && !scev_analyzable_p (res
, SCOP_REGION (scop
)))
3071 changed
|= rewrite_commutative_reductions_out_of_ssa_close_phi
3077 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3080 rewrite_commutative_reductions_out_of_ssa (scop_p scop
)
3083 bool changed
= false;
3084 sese region
= SCOP_REGION (scop
);
3086 FOR_EACH_LOOP (loop
, 0)
3087 if (loop_in_sese_p (loop
, region
))
3088 changed
|= rewrite_commutative_reductions_out_of_ssa_loop (scop
, loop
);
3093 gsi_commit_edge_inserts ();
3094 update_ssa (TODO_update_ssa
);
3095 #ifdef ENABLE_CHECKING
3096 verify_loop_closed_ssa (true);
3101 /* Can all ivs be represented by a signed integer?
3102 As CLooG might generate negative values in its expressions, signed loop ivs
3103 are required in the backend. */
3106 scop_ivs_can_be_represented (scop_p scop
)
3112 FOR_EACH_LOOP (loop
, 0)
3114 if (!loop_in_sese_p (loop
, SCOP_REGION (scop
)))
3117 for (psi
= gsi_start_phis (loop
->header
);
3118 !gsi_end_p (psi
); gsi_next (&psi
))
3120 gphi
*phi
= psi
.phi ();
3121 tree res
= PHI_RESULT (phi
);
3122 tree type
= TREE_TYPE (res
);
3124 if (TYPE_UNSIGNED (type
)
3125 && TYPE_PRECISION (type
) >= TYPE_PRECISION (long_long_integer_type_node
))
3138 /* Builds the polyhedral representation for a SESE region. */
3141 build_poly_scop (scop_p scop
)
3143 sese region
= SCOP_REGION (scop
);
3144 graphite_dim_t max_dim
;
3146 build_scop_bbs (scop
);
3148 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3149 Once CLooG is fixed, remove this guard. Anyways, it makes no
3150 sense to optimize a scop containing only PBBs that do not belong
3152 if (nb_pbbs_in_loops (scop
) == 0)
3155 if (!scop_ivs_can_be_represented (scop
))
3158 if (flag_associative_math
)
3159 rewrite_commutative_reductions_out_of_ssa (scop
);
3161 build_sese_loop_nests (region
);
3162 /* Record all conditions in REGION. */
3163 sese_dom_walker (CDI_DOMINATORS
, region
).walk (cfun
->cfg
->x_entry_block_ptr
);
3164 find_scop_parameters (scop
);
3166 max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
3167 if (scop_nb_params (scop
) > max_dim
)
3170 build_scop_iteration_domain (scop
);
3171 build_scop_context (scop
);
3172 add_conditions_to_constraints (scop
);
3174 /* Rewrite out of SSA only after having translated the
3175 representation to the polyhedral representation to avoid scev
3176 analysis failures. That means that these functions will insert
3177 new data references that they create in the right place. */
3178 rewrite_reductions_out_of_ssa (scop
);
3179 rewrite_cross_bb_scalar_deps_out_of_ssa (scop
);
3181 build_scop_drs (scop
);
3183 build_scop_scattering (scop
);
3185 /* This SCoP has been translated to the polyhedral
3187 POLY_SCOP_P (scop
) = true;