1 /* Conversion of SESE regions to Polyhedra.
2 Copyright (C) 2009-2013 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>
29 #include <cloog/cloog.h>
30 #include <cloog/cloog.h>
31 #include <cloog/isl/domain.h>
35 #include "coretypes.h"
36 #include "tree-flow.h"
37 #include "tree-pass.h"
39 #include "tree-chrec.h"
40 #include "tree-data-ref.h"
41 #include "tree-scalar-evolution.h"
46 #include "graphite-poly.h"
47 #include "graphite-sese-to-poly.h"
50 /* Assigns to RES the value of the INTEGER_CST T. */
53 tree_int_to_gmp (tree t
, mpz_t res
)
55 double_int di
= tree_to_double_int (t
);
56 mpz_set_double_int (res
, di
, TYPE_UNSIGNED (TREE_TYPE (t
)));
59 /* Returns the index of the PHI argument defined in the outermost
63 phi_arg_in_outermost_loop (gimple phi
)
65 loop_p loop
= gimple_bb (phi
)->loop_father
;
68 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
69 if (!flow_bb_inside_loop_p (loop
, gimple_phi_arg_edge (phi
, i
)->src
))
71 loop
= gimple_phi_arg_edge (phi
, i
)->src
->loop_father
;
78 /* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
79 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
82 remove_simple_copy_phi (gimple_stmt_iterator
*psi
)
84 gimple phi
= gsi_stmt (*psi
);
85 tree res
= gimple_phi_result (phi
);
86 size_t entry
= phi_arg_in_outermost_loop (phi
);
87 tree init
= gimple_phi_arg_def (phi
, entry
);
88 gimple stmt
= gimple_build_assign (res
, init
);
89 edge e
= gimple_phi_arg_edge (phi
, entry
);
91 remove_phi_node (psi
, false);
92 gsi_insert_on_edge_immediate (e
, stmt
);
93 SSA_NAME_DEF_STMT (res
) = stmt
;
96 /* Removes an invariant phi node at position PSI by inserting on the
97 loop ENTRY edge the assignment RES = INIT. */
100 remove_invariant_phi (sese region
, gimple_stmt_iterator
*psi
)
102 gimple phi
= gsi_stmt (*psi
);
103 loop_p loop
= loop_containing_stmt (phi
);
104 tree res
= gimple_phi_result (phi
);
105 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
106 size_t entry
= phi_arg_in_outermost_loop (phi
);
107 edge e
= gimple_phi_arg_edge (phi
, entry
);
110 gimple_seq stmts
= NULL
;
112 if (tree_contains_chrecs (scev
, NULL
))
113 scev
= gimple_phi_arg_def (phi
, entry
);
115 var
= force_gimple_operand (scev
, &stmts
, true, NULL_TREE
);
116 stmt
= gimple_build_assign (res
, var
);
117 remove_phi_node (psi
, false);
119 gimple_seq_add_stmt (&stmts
, stmt
);
120 gsi_insert_seq_on_edge (e
, stmts
);
121 gsi_commit_edge_inserts ();
122 SSA_NAME_DEF_STMT (res
) = stmt
;
125 /* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
128 simple_copy_phi_p (gimple phi
)
132 if (gimple_phi_num_args (phi
) != 2)
135 res
= gimple_phi_result (phi
);
136 return (res
== gimple_phi_arg_def (phi
, 0)
137 || res
== gimple_phi_arg_def (phi
, 1));
140 /* Returns true when the phi node at position PSI is a reduction phi
141 node in REGION. Otherwise moves the pointer PSI to the next phi to
145 reduction_phi_p (sese region
, gimple_stmt_iterator
*psi
)
148 gimple phi
= gsi_stmt (*psi
);
149 tree res
= gimple_phi_result (phi
);
151 loop
= loop_containing_stmt (phi
);
153 if (simple_copy_phi_p (phi
))
155 /* PRE introduces phi nodes like these, for an example,
156 see id-5.f in the fortran graphite testsuite:
158 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
160 remove_simple_copy_phi (psi
);
164 if (scev_analyzable_p (res
, region
))
166 tree scev
= scalar_evolution_in_region (region
, loop
, res
);
168 if (evolution_function_is_invariant_p (scev
, loop
->num
))
169 remove_invariant_phi (region
, psi
);
176 /* All the other cases are considered reductions. */
180 /* Store the GRAPHITE representation of BB. */
183 new_gimple_bb (basic_block bb
, vec
<data_reference_p
> drs
)
185 struct gimple_bb
*gbb
;
187 gbb
= XNEW (struct gimple_bb
);
190 GBB_DATA_REFS (gbb
) = drs
;
191 GBB_CONDITIONS (gbb
).create (0);
192 GBB_CONDITION_CASES (gbb
).create (0);
198 free_data_refs_aux (vec
<data_reference_p
> datarefs
)
201 struct data_reference
*dr
;
203 FOR_EACH_VEC_ELT (datarefs
, i
, dr
)
206 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
208 free (bap
->alias_set
);
217 free_gimple_bb (struct gimple_bb
*gbb
)
219 free_data_refs_aux (GBB_DATA_REFS (gbb
));
220 free_data_refs (GBB_DATA_REFS (gbb
));
222 GBB_CONDITIONS (gbb
).release ();
223 GBB_CONDITION_CASES (gbb
).release ();
224 GBB_BB (gbb
)->aux
= 0;
228 /* Deletes all gimple bbs in SCOP. */
231 remove_gbbs_in_scop (scop_p scop
)
236 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
237 free_gimple_bb (PBB_BLACK_BOX (pbb
));
240 /* Deletes all scops in SCOPS. */
243 free_scops (vec
<scop_p
> scops
)
248 FOR_EACH_VEC_ELT (scops
, i
, scop
)
250 remove_gbbs_in_scop (scop
);
251 free_sese (SCOP_REGION (scop
));
258 /* Same as outermost_loop_in_sese, returns the outermost loop
259 containing BB in REGION, but makes sure that the returned loop
260 belongs to the REGION, and so this returns the first loop in the
261 REGION when the loop containing BB does not belong to REGION. */
264 outermost_loop_in_sese_1 (sese region
, basic_block bb
)
266 loop_p nest
= outermost_loop_in_sese (region
, bb
);
268 if (loop_in_sese_p (nest
, region
))
271 /* When the basic block BB does not belong to a loop in the region,
272 return the first loop in the region. */
275 if (loop_in_sese_p (nest
, region
))
284 /* Generates a polyhedral black box only if the bb contains interesting
288 try_generate_gimple_bb (scop_p scop
, basic_block bb
)
290 vec
<data_reference_p
> drs
;
292 sese region
= SCOP_REGION (scop
);
293 loop_p nest
= outermost_loop_in_sese_1 (region
, bb
);
294 gimple_stmt_iterator gsi
;
296 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
298 gimple stmt
= gsi_stmt (gsi
);
301 if (is_gimple_debug (stmt
))
304 loop
= loop_containing_stmt (stmt
);
305 if (!loop_in_sese_p (loop
, region
))
308 graphite_find_data_references_in_stmt (nest
, loop
, stmt
, &drs
);
311 return new_gimple_bb (bb
, drs
);
314 /* Returns true if all predecessors of BB, that are not dominated by BB, are
315 marked in MAP. The predecessors dominated by BB are loop latches and will
316 be handled after BB. */
319 all_non_dominated_preds_marked_p (basic_block bb
, sbitmap map
)
324 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
325 if (!bitmap_bit_p (map
, e
->src
->index
)
326 && !dominated_by_p (CDI_DOMINATORS
, e
->src
, bb
))
332 /* Compare the depth of two basic_block's P1 and P2. */
335 compare_bb_depths (const void *p1
, const void *p2
)
337 const_basic_block
const bb1
= *(const_basic_block
const*)p1
;
338 const_basic_block
const bb2
= *(const_basic_block
const*)p2
;
339 int d1
= loop_depth (bb1
->loop_father
);
340 int d2
= loop_depth (bb2
->loop_father
);
351 /* Sort the basic blocks from DOM such that the first are the ones at
352 a deepest loop level. */
355 graphite_sort_dominated_info (vec
<basic_block
> dom
)
357 dom
.qsort (compare_bb_depths
);
360 /* Recursive helper function for build_scops_bbs. */
363 build_scop_bbs_1 (scop_p scop
, sbitmap visited
, basic_block bb
)
365 sese region
= SCOP_REGION (scop
);
366 vec
<basic_block
> dom
;
369 if (bitmap_bit_p (visited
, bb
->index
)
370 || !bb_in_sese_p (bb
, region
))
373 pbb
= new_poly_bb (scop
, try_generate_gimple_bb (scop
, bb
));
374 SCOP_BBS (scop
).safe_push (pbb
);
375 bitmap_set_bit (visited
, bb
->index
);
377 dom
= get_dominated_by (CDI_DOMINATORS
, bb
);
382 graphite_sort_dominated_info (dom
);
384 while (!dom
.is_empty ())
389 FOR_EACH_VEC_ELT (dom
, i
, dom_bb
)
390 if (all_non_dominated_preds_marked_p (dom_bb
, visited
))
392 build_scop_bbs_1 (scop
, visited
, dom_bb
);
393 dom
.unordered_remove (i
);
401 /* Gather the basic blocks belonging to the SCOP. */
404 build_scop_bbs (scop_p scop
)
406 sbitmap visited
= sbitmap_alloc (last_basic_block
);
407 sese region
= SCOP_REGION (scop
);
409 bitmap_clear (visited
);
410 build_scop_bbs_1 (scop
, visited
, SESE_ENTRY_BB (region
));
411 sbitmap_free (visited
);
414 /* Return an ISL identifier for the polyhedral basic block PBB. */
417 isl_id_for_pbb (scop_p s
, poly_bb_p pbb
)
420 snprintf (name
, sizeof (name
), "S_%d", pbb_index (pbb
));
421 return isl_id_alloc (s
->ctx
, name
, pbb
);
424 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
425 We generate SCATTERING_DIMENSIONS scattering dimensions.
427 CLooG 0.15.0 and previous versions require, that all
428 scattering functions of one CloogProgram have the same number of
429 scattering dimensions, therefore we allow to specify it. This
430 should be removed in future versions of CLooG.
432 The scattering polyhedron consists of these dimensions: scattering,
433 loop_iterators, parameters.
437 | scattering_dimensions = 5
438 | used_scattering_dimensions = 3
446 | Scattering polyhedron:
448 | scattering: {s1, s2, s3, s4, s5}
449 | loop_iterators: {i}
450 | parameters: {p1, p2}
452 | s1 s2 s3 s4 s5 i p1 p2 1
453 | 1 0 0 0 0 0 0 0 -4 = 0
454 | 0 1 0 0 0 -1 0 0 0 = 0
455 | 0 0 1 0 0 0 0 0 -5 = 0 */
458 build_pbb_scattering_polyhedrons (isl_aff
*static_sched
,
459 poly_bb_p pbb
, int scattering_dimensions
)
462 int nb_iterators
= pbb_dim_iter_domain (pbb
);
463 int used_scattering_dimensions
= nb_iterators
* 2 + 1;
467 gcc_assert (scattering_dimensions
>= used_scattering_dimensions
);
471 dc
= isl_set_get_space (pbb
->domain
);
472 dm
= isl_space_add_dims (isl_space_from_domain (dc
),
473 isl_dim_out
, scattering_dimensions
);
474 pbb
->schedule
= isl_map_universe (dm
);
476 for (i
= 0; i
< scattering_dimensions
; i
++)
478 /* Textual order inside this loop. */
481 isl_constraint
*c
= isl_equality_alloc
482 (isl_local_space_from_space (isl_map_get_space (pbb
->schedule
)));
484 if (0 != isl_aff_get_coefficient (static_sched
, isl_dim_in
,
488 isl_int_neg (val
, val
);
489 c
= isl_constraint_set_constant (c
, val
);
490 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
491 pbb
->schedule
= isl_map_add_constraint (pbb
->schedule
, c
);
494 /* Iterations of this loop. */
495 else /* if ((i % 2) == 1) */
497 int loop
= (i
- 1) / 2;
498 pbb
->schedule
= isl_map_equate (pbb
->schedule
, isl_dim_in
, loop
,
505 pbb
->transformed
= isl_map_copy (pbb
->schedule
);
508 /* Build for BB the static schedule.
510 The static schedule is a Dewey numbering of the abstract syntax
511 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
513 The following example informally defines the static schedule:
532 Static schedules for A to F:
545 build_scop_scattering (scop_p scop
)
549 gimple_bb_p previous_gbb
= NULL
;
550 isl_space
*dc
= isl_set_get_space (scop
->context
);
551 isl_aff
*static_sched
;
553 dc
= isl_space_add_dims (dc
, isl_dim_set
, number_of_loops());
554 static_sched
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
556 /* We have to start schedules at 0 on the first component and
557 because we cannot compare_prefix_loops against a previous loop,
558 prefix will be equal to zero, and that index will be
559 incremented before copying. */
560 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
, 0, -1);
562 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
564 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
566 int nb_scat_dims
= pbb_dim_iter_domain (pbb
) * 2 + 1;
569 prefix
= nb_common_loops (SCOP_REGION (scop
), previous_gbb
, gbb
);
575 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
,
577 build_pbb_scattering_polyhedrons (static_sched
, pbb
, nb_scat_dims
);
580 isl_aff_free (static_sched
);
583 static isl_pw_aff
*extract_affine (scop_p
, tree
, __isl_take isl_space
*space
);
585 /* Extract an affine expression from the chain of recurrence E. */
588 extract_affine_chrec (scop_p s
, tree e
, __isl_take isl_space
*space
)
590 isl_pw_aff
*lhs
= extract_affine (s
, CHREC_LEFT (e
), isl_space_copy (space
));
591 isl_pw_aff
*rhs
= extract_affine (s
, CHREC_RIGHT (e
), isl_space_copy (space
));
592 isl_local_space
*ls
= isl_local_space_from_space (space
);
593 unsigned pos
= sese_loop_depth ((sese
) s
->region
,
594 get_loop (CHREC_VARIABLE (e
))) - 1;
595 isl_aff
*loop
= isl_aff_set_coefficient_si
596 (isl_aff_zero_on_domain (ls
), isl_dim_in
, pos
, 1);
597 isl_pw_aff
*l
= isl_pw_aff_from_aff (loop
);
599 /* Before multiplying, make sure that the result is affine. */
600 gcc_assert (isl_pw_aff_is_cst (rhs
)
601 || isl_pw_aff_is_cst (l
));
603 return isl_pw_aff_add (lhs
, isl_pw_aff_mul (rhs
, l
));
606 /* Extract an affine expression from the mult_expr E. */
609 extract_affine_mul (scop_p s
, tree e
, __isl_take isl_space
*space
)
611 isl_pw_aff
*lhs
= extract_affine (s
, TREE_OPERAND (e
, 0),
612 isl_space_copy (space
));
613 isl_pw_aff
*rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
615 if (!isl_pw_aff_is_cst (lhs
)
616 && !isl_pw_aff_is_cst (rhs
))
618 isl_pw_aff_free (lhs
);
619 isl_pw_aff_free (rhs
);
623 return isl_pw_aff_mul (lhs
, rhs
);
626 /* Return an ISL identifier from the name of the ssa_name E. */
629 isl_id_for_ssa_name (scop_p s
, tree e
)
631 const char *name
= get_name (e
);
635 id
= isl_id_alloc (s
->ctx
, name
, e
);
639 snprintf (name1
, sizeof (name1
), "P_%d", SSA_NAME_VERSION (e
));
640 id
= isl_id_alloc (s
->ctx
, name1
, e
);
646 /* Return an ISL identifier for the data reference DR. */
649 isl_id_for_dr (scop_p s
, data_reference_p dr ATTRIBUTE_UNUSED
)
651 /* Data references all get the same isl_id. They need to be comparable
652 and are distinguished through the first dimension, which contains the
654 return isl_id_alloc (s
->ctx
, "", 0);
657 /* Extract an affine expression from the ssa_name E. */
660 extract_affine_name (scop_p s
, tree e
, __isl_take isl_space
*space
)
667 id
= isl_id_for_ssa_name (s
, e
);
668 dimension
= isl_space_find_dim_by_id (space
, isl_dim_param
, id
);
670 dom
= isl_set_universe (isl_space_copy (space
));
671 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
672 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, dimension
, 1);
673 return isl_pw_aff_alloc (dom
, aff
);
676 /* Extract an affine expression from the gmp constant G. */
679 extract_affine_gmp (mpz_t g
, __isl_take isl_space
*space
)
681 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
682 isl_aff
*aff
= isl_aff_zero_on_domain (ls
);
683 isl_set
*dom
= isl_set_universe (space
);
687 isl_int_set_gmp (v
, g
);
688 aff
= isl_aff_add_constant (aff
, v
);
691 return isl_pw_aff_alloc (dom
, aff
);
694 /* Extract an affine expression from the integer_cst E. */
697 extract_affine_int (tree e
, __isl_take isl_space
*space
)
703 tree_int_to_gmp (e
, g
);
704 res
= extract_affine_gmp (g
, space
);
710 /* Compute pwaff mod 2^width. */
713 wrap (isl_pw_aff
*pwaff
, unsigned width
)
718 isl_int_set_si (mod
, 1);
719 isl_int_mul_2exp (mod
, mod
, width
);
721 pwaff
= isl_pw_aff_mod (pwaff
, mod
);
728 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
729 Otherwise returns -1. */
732 parameter_index_in_region_1 (tree name
, sese region
)
737 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
739 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, p
)
746 /* When the parameter NAME is in REGION, returns its index in
747 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
748 and returns the index of NAME. */
751 parameter_index_in_region (tree name
, sese region
)
755 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
757 i
= parameter_index_in_region_1 (name
, region
);
761 gcc_assert (SESE_ADD_PARAMS (region
));
763 i
= SESE_PARAMS (region
).length ();
764 SESE_PARAMS (region
).safe_push (name
);
768 /* Extract an affine expression from the tree E in the scop S. */
771 extract_affine (scop_p s
, tree e
, __isl_take isl_space
*space
)
773 isl_pw_aff
*lhs
, *rhs
, *res
;
776 if (e
== chrec_dont_know
) {
777 isl_space_free (space
);
781 switch (TREE_CODE (e
))
783 case POLYNOMIAL_CHREC
:
784 res
= extract_affine_chrec (s
, e
, space
);
788 res
= extract_affine_mul (s
, e
, space
);
792 case POINTER_PLUS_EXPR
:
793 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
794 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
795 res
= isl_pw_aff_add (lhs
, rhs
);
799 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
800 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
801 res
= isl_pw_aff_sub (lhs
, rhs
);
806 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
807 rhs
= extract_affine (s
, integer_minus_one_node
, space
);
808 res
= isl_pw_aff_mul (lhs
, rhs
);
812 gcc_assert (-1 != parameter_index_in_region_1 (e
, SCOP_REGION (s
)));
813 res
= extract_affine_name (s
, e
, space
);
817 res
= extract_affine_int (e
, space
);
818 /* No need to wrap a single integer. */
822 case NON_LVALUE_EXPR
:
823 res
= extract_affine (s
, TREE_OPERAND (e
, 0), space
);
831 type
= TREE_TYPE (e
);
832 if (TYPE_UNSIGNED (type
))
833 res
= wrap (res
, TYPE_PRECISION (type
));
838 /* In the context of sese S, scan the expression E and translate it to
839 a linear expression C. When parsing a symbolic multiplication, K
840 represents the constant multiplier of an expression containing
844 scan_tree_for_params (sese s
, tree e
)
846 if (e
== chrec_dont_know
)
849 switch (TREE_CODE (e
))
851 case POLYNOMIAL_CHREC
:
852 scan_tree_for_params (s
, CHREC_LEFT (e
));
856 if (chrec_contains_symbols (TREE_OPERAND (e
, 0)))
857 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
859 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
863 case POINTER_PLUS_EXPR
:
865 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
866 scan_tree_for_params (s
, TREE_OPERAND (e
, 1));
872 case NON_LVALUE_EXPR
:
873 scan_tree_for_params (s
, TREE_OPERAND (e
, 0));
877 parameter_index_in_region (e
, s
);
890 /* Find parameters with respect to REGION in BB. We are looking in memory
891 access functions, conditions and loop bounds. */
894 find_params_in_bb (sese region
, gimple_bb_p gbb
)
900 loop_p loop
= GBB_BB (gbb
)->loop_father
;
902 /* Find parameters in the access functions of data references. */
903 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
904 for (j
= 0; j
< DR_NUM_DIMENSIONS (dr
); j
++)
905 scan_tree_for_params (region
, DR_ACCESS_FN (dr
, j
));
907 /* Find parameters in conditional statements. */
908 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
910 tree lhs
= scalar_evolution_in_region (region
, loop
,
911 gimple_cond_lhs (stmt
));
912 tree rhs
= scalar_evolution_in_region (region
, loop
,
913 gimple_cond_rhs (stmt
));
915 scan_tree_for_params (region
, lhs
);
916 scan_tree_for_params (region
, rhs
);
920 /* Record the parameters used in the SCOP. A variable is a parameter
921 in a scop if it does not vary during the execution of that scop. */
924 find_scop_parameters (scop_p scop
)
928 sese region
= SCOP_REGION (scop
);
932 /* Find the parameters used in the loop bounds. */
933 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
935 tree nb_iters
= number_of_latch_executions (loop
);
937 if (!chrec_contains_symbols (nb_iters
))
940 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
941 scan_tree_for_params (region
, nb_iters
);
944 /* Find the parameters used in data accesses. */
945 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
946 find_params_in_bb (region
, PBB_BLACK_BOX (pbb
));
948 nbp
= sese_nb_params (region
);
949 scop_set_nb_params (scop
, nbp
);
950 SESE_ADD_PARAMS (region
) = false;
954 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, nbp
, 0);
956 FOR_EACH_VEC_ELT (SESE_PARAMS (region
), i
, e
)
957 space
= isl_space_set_dim_id (space
, isl_dim_param
, i
,
958 isl_id_for_ssa_name (scop
, e
));
960 scop
->context
= isl_set_universe (space
);
964 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
965 the constraints for the surrounding loops. */
968 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
970 isl_set
*outer
, isl_set
**doms
)
972 tree nb_iters
= number_of_latch_executions (loop
);
973 sese region
= SCOP_REGION (scop
);
975 isl_set
*inner
= isl_set_copy (outer
);
978 int pos
= isl_set_dim (outer
, isl_dim_set
);
985 inner
= isl_set_add_dims (inner
, isl_dim_set
, 1);
986 space
= isl_set_get_space (inner
);
989 c
= isl_inequality_alloc
990 (isl_local_space_from_space (isl_space_copy (space
)));
991 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, 1);
992 inner
= isl_set_add_constraint (inner
, c
);
994 /* loop_i <= cst_nb_iters */
995 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
997 c
= isl_inequality_alloc
998 (isl_local_space_from_space(isl_space_copy (space
)));
999 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1000 tree_int_to_gmp (nb_iters
, g
);
1001 isl_int_set_gmp (v
, g
);
1002 c
= isl_constraint_set_constant (c
, v
);
1003 inner
= isl_set_add_constraint (inner
, c
);
1006 /* loop_i <= expr_nb_iters */
1007 else if (!chrec_contains_undetermined (nb_iters
))
1012 isl_local_space
*ls
;
1016 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
1018 aff
= extract_affine (scop
, nb_iters
, isl_set_get_space (inner
));
1019 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff
));
1020 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1021 isl_set_dim (valid
, isl_dim_set
));
1022 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1024 ls
= isl_local_space_from_space (isl_space_copy (space
));
1025 al
= isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls
),
1026 isl_dim_in
, pos
, 1);
1027 le
= isl_pw_aff_le_set (isl_pw_aff_from_aff (al
),
1028 isl_pw_aff_copy (aff
));
1029 inner
= isl_set_intersect (inner
, le
);
1031 if (max_stmt_executions (loop
, &nit
))
1033 /* Insert in the context the constraints from the
1034 estimation of the number of iterations NIT and the
1035 symbolic number of iterations (involving parameter
1036 names) NB_ITERS. First, build the affine expression
1037 "NIT - NB_ITERS" and then say that it is positive,
1038 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1045 mpz_set_double_int (g
, nit
, false);
1046 mpz_sub_ui (g
, g
, 1);
1047 approx
= extract_affine_gmp (g
, isl_set_get_space (inner
));
1048 x
= isl_pw_aff_ge_set (approx
, aff
);
1049 x
= isl_set_project_out (x
, isl_dim_set
, 0,
1050 isl_set_dim (x
, isl_dim_set
));
1051 scop
->context
= isl_set_intersect (scop
->context
, x
);
1053 c
= isl_inequality_alloc
1054 (isl_local_space_from_space (isl_space_copy (space
)));
1055 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
1056 isl_int_set_gmp (v
, g
);
1058 c
= isl_constraint_set_constant (c
, v
);
1059 inner
= isl_set_add_constraint (inner
, c
);
1062 isl_pw_aff_free (aff
);
1067 if (loop
->inner
&& loop_in_sese_p (loop
->inner
, region
))
1068 build_loop_iteration_domains (scop
, loop
->inner
, nb
+ 1,
1069 isl_set_copy (inner
), doms
);
1073 && loop_in_sese_p (loop
->next
, region
))
1074 build_loop_iteration_domains (scop
, loop
->next
, nb
,
1075 isl_set_copy (outer
), doms
);
1077 doms
[loop
->num
] = inner
;
1079 isl_set_free (outer
);
1080 isl_space_free (space
);
1085 /* Returns a linear expression for tree T evaluated in PBB. */
1088 create_pw_aff_from_tree (poly_bb_p pbb
, tree t
)
1090 scop_p scop
= PBB_SCOP (pbb
);
1092 t
= scalar_evolution_in_region (SCOP_REGION (scop
), pbb_loop (pbb
), t
);
1093 gcc_assert (!automatically_generated_chrec_p (t
));
1095 return extract_affine (scop
, t
, isl_set_get_space (pbb
->domain
));
1098 /* Add conditional statement STMT to pbb. CODE is used as the comparison
1099 operator. This allows us to invert the condition or to handle
1103 add_condition_to_pbb (poly_bb_p pbb
, gimple stmt
, enum tree_code code
)
1105 isl_pw_aff
*lhs
= create_pw_aff_from_tree (pbb
, gimple_cond_lhs (stmt
));
1106 isl_pw_aff
*rhs
= create_pw_aff_from_tree (pbb
, gimple_cond_rhs (stmt
));
1112 cond
= isl_pw_aff_lt_set (lhs
, rhs
);
1116 cond
= isl_pw_aff_gt_set (lhs
, rhs
);
1120 cond
= isl_pw_aff_le_set (lhs
, rhs
);
1124 cond
= isl_pw_aff_ge_set (lhs
, rhs
);
1128 cond
= isl_pw_aff_eq_set (lhs
, rhs
);
1132 cond
= isl_pw_aff_ne_set (lhs
, rhs
);
1136 isl_pw_aff_free(lhs
);
1137 isl_pw_aff_free(rhs
);
1141 cond
= isl_set_coalesce (cond
);
1142 cond
= isl_set_set_tuple_id (cond
, isl_set_get_tuple_id (pbb
->domain
));
1143 pbb
->domain
= isl_set_intersect (pbb
->domain
, cond
);
1146 /* Add conditions to the domain of PBB. */
1149 add_conditions_to_domain (poly_bb_p pbb
)
1153 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1155 if (GBB_CONDITIONS (gbb
).is_empty ())
1158 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
1159 switch (gimple_code (stmt
))
1163 enum tree_code code
= gimple_cond_code (stmt
);
1165 /* The conditions for ELSE-branches are inverted. */
1166 if (!GBB_CONDITION_CASES (gbb
)[i
])
1167 code
= invert_tree_comparison (code
, false);
1169 add_condition_to_pbb (pbb
, stmt
, code
);
1174 /* Switch statements are not supported right now - fall through. */
1182 /* Traverses all the GBBs of the SCOP and add their constraints to the
1183 iteration domains. */
1186 add_conditions_to_constraints (scop_p scop
)
1191 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1192 add_conditions_to_domain (pbb
);
1195 /* Structure used to pass data to dom_walk. */
1199 vec
<gimple
> *conditions
, *cases
;
1203 /* Returns a COND_EXPR statement when BB has a single predecessor, the
1204 edge between BB and its predecessor is not a loop exit edge, and
1205 the last statement of the single predecessor is a COND_EXPR. */
1208 single_pred_cond_non_loop_exit (basic_block bb
)
1210 if (single_pred_p (bb
))
1212 edge e
= single_pred_edge (bb
);
1213 basic_block pred
= e
->src
;
1216 if (loop_depth (pred
->loop_father
) > loop_depth (bb
->loop_father
))
1219 stmt
= last_stmt (pred
);
1221 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
1228 /* Call-back for dom_walk executed before visiting the dominated
1232 build_sese_conditions_before (struct dom_walk_data
*dw_data
,
1235 struct bsc
*data
= (struct bsc
*) dw_data
->global_data
;
1236 vec
<gimple
> *conditions
= data
->conditions
;
1237 vec
<gimple
> *cases
= data
->cases
;
1241 if (!bb_in_sese_p (bb
, data
->region
))
1244 stmt
= single_pred_cond_non_loop_exit (bb
);
1248 edge e
= single_pred_edge (bb
);
1250 conditions
->safe_push (stmt
);
1252 if (e
->flags
& EDGE_TRUE_VALUE
)
1253 cases
->safe_push (stmt
);
1255 cases
->safe_push (NULL
);
1258 gbb
= gbb_from_bb (bb
);
1262 GBB_CONDITIONS (gbb
) = conditions
->copy ();
1263 GBB_CONDITION_CASES (gbb
) = cases
->copy ();
1267 /* Call-back for dom_walk executed after visiting the dominated
1271 build_sese_conditions_after (struct dom_walk_data
*dw_data
,
1274 struct bsc
*data
= (struct bsc
*) dw_data
->global_data
;
1275 vec
<gimple
> *conditions
= data
->conditions
;
1276 vec
<gimple
> *cases
= data
->cases
;
1278 if (!bb_in_sese_p (bb
, data
->region
))
1281 if (single_pred_cond_non_loop_exit (bb
))
1288 /* Record all conditions in REGION. */
1291 build_sese_conditions (sese region
)
1293 struct dom_walk_data walk_data
;
1294 vec
<gimple
> conditions
;
1295 conditions
.create (3);
1300 data
.conditions
= &conditions
;
1301 data
.cases
= &cases
;
1302 data
.region
= region
;
1304 walk_data
.dom_direction
= CDI_DOMINATORS
;
1305 walk_data
.initialize_block_local_data
= NULL
;
1306 walk_data
.before_dom_children
= build_sese_conditions_before
;
1307 walk_data
.after_dom_children
= build_sese_conditions_after
;
1308 walk_data
.global_data
= &data
;
1309 walk_data
.block_local_data_size
= 0;
1311 init_walk_dominator_tree (&walk_data
);
1312 walk_dominator_tree (&walk_data
, SESE_ENTRY_BB (region
));
1313 fini_walk_dominator_tree (&walk_data
);
1315 conditions
.release ();
1319 /* Add constraints on the possible values of parameter P from the type
1323 add_param_constraints (scop_p scop
, graphite_dim_t p
)
1325 tree parameter
= SESE_PARAMS (SCOP_REGION (scop
))[p
];
1326 tree type
= TREE_TYPE (parameter
);
1327 tree lb
= NULL_TREE
;
1328 tree ub
= NULL_TREE
;
1330 if (POINTER_TYPE_P (type
) || !TYPE_MIN_VALUE (type
))
1331 lb
= lower_bound_in_type (type
, type
);
1333 lb
= TYPE_MIN_VALUE (type
);
1335 if (POINTER_TYPE_P (type
) || !TYPE_MAX_VALUE (type
))
1336 ub
= upper_bound_in_type (type
, type
);
1338 ub
= TYPE_MAX_VALUE (type
);
1342 isl_space
*space
= isl_set_get_space (scop
->context
);
1347 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1350 tree_int_to_gmp (lb
, g
);
1351 isl_int_set_gmp (v
, g
);
1354 c
= isl_constraint_set_constant (c
, v
);
1356 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, 1);
1358 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1363 isl_space
*space
= isl_set_get_space (scop
->context
);
1368 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
1372 tree_int_to_gmp (ub
, g
);
1373 isl_int_set_gmp (v
, g
);
1375 c
= isl_constraint_set_constant (c
, v
);
1377 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, -1);
1379 scop
->context
= isl_set_add_constraint (scop
->context
, c
);
1383 /* Build the context of the SCOP. The context usually contains extra
1384 constraints that are added to the iteration domains that constrain
1388 build_scop_context (scop_p scop
)
1390 graphite_dim_t p
, n
= scop_nb_params (scop
);
1392 for (p
= 0; p
< n
; p
++)
1393 add_param_constraints (scop
, p
);
1396 /* Build the iteration domains: the loops belonging to the current
1397 SCOP, and that vary for the execution of the current basic block.
1398 Returns false if there is no loop in SCOP. */
1401 build_scop_iteration_domain (scop_p scop
)
1404 sese region
= SCOP_REGION (scop
);
1407 int nb_loops
= number_of_loops ();
1408 isl_set
**doms
= XCNEWVEC (isl_set
*, nb_loops
);
1410 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region
), i
, loop
)
1411 if (!loop_in_sese_p (loop_outer (loop
), region
))
1412 build_loop_iteration_domains (scop
, loop
, 0,
1413 isl_set_copy (scop
->context
), doms
);
1415 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1417 loop
= pbb_loop (pbb
);
1419 if (doms
[loop
->num
])
1420 pbb
->domain
= isl_set_copy (doms
[loop
->num
]);
1422 pbb
->domain
= isl_set_copy (scop
->context
);
1424 pbb
->domain
= isl_set_set_tuple_id (pbb
->domain
,
1425 isl_id_for_pbb (scop
, pbb
));
1428 for (i
= 0; i
< nb_loops
; i
++)
1430 isl_set_free (doms
[i
]);
1435 /* Add a constrain to the ACCESSES polyhedron for the alias set of
1436 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1437 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1441 pdr_add_alias_set (isl_map
*acc
, data_reference_p dr
)
1444 int alias_set_num
= 0;
1445 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1447 if (bap
&& bap
->alias_set
)
1448 alias_set_num
= *(bap
->alias_set
);
1450 c
= isl_equality_alloc
1451 (isl_local_space_from_space (isl_map_get_space (acc
)));
1452 c
= isl_constraint_set_constant_si (c
, -alias_set_num
);
1453 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
1455 return isl_map_add_constraint (acc
, c
);
1458 /* Assign the affine expression INDEX to the output dimension POS of
1459 MAP and return the result. */
1462 set_index (isl_map
*map
, int pos
, isl_pw_aff
*index
)
1465 int len
= isl_map_dim (map
, isl_dim_out
);
1468 index_map
= isl_map_from_pw_aff (index
);
1469 index_map
= isl_map_insert_dims (index_map
, isl_dim_out
, 0, pos
);
1470 index_map
= isl_map_add_dims (index_map
, isl_dim_out
, len
- pos
- 1);
1472 id
= isl_map_get_tuple_id (map
, isl_dim_out
);
1473 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_out
, id
);
1474 id
= isl_map_get_tuple_id (map
, isl_dim_in
);
1475 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_in
, id
);
1477 return isl_map_intersect (map
, index_map
);
1480 /* Add to ACCESSES polyhedron equalities defining the access functions
1481 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1482 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1483 PBB is the poly_bb_p that contains the data reference DR. */
1486 pdr_add_memory_accesses (isl_map
*acc
, data_reference_p dr
, poly_bb_p pbb
)
1488 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1489 scop_p scop
= PBB_SCOP (pbb
);
1491 for (i
= 0; i
< nb_subscripts
; i
++)
1494 tree afn
= DR_ACCESS_FN (dr
, nb_subscripts
- 1 - i
);
1496 aff
= extract_affine (scop
, afn
,
1497 isl_space_domain (isl_map_get_space (acc
)));
1498 acc
= set_index (acc
, i
+ 1, aff
);
1504 /* Add constrains representing the size of the accessed data to the
1505 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1506 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1510 pdr_add_data_dimensions (isl_set
*extent
, scop_p scop
, data_reference_p dr
)
1512 tree ref
= DR_REF (dr
);
1513 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
1515 for (i
= nb_subscripts
- 1; i
>= 0; i
--, ref
= TREE_OPERAND (ref
, 0))
1519 if (TREE_CODE (ref
) != ARRAY_REF
)
1522 low
= array_ref_low_bound (ref
);
1523 high
= array_ref_up_bound (ref
);
1525 /* XXX The PPL code dealt separately with
1526 subscript - low >= 0 and high - subscript >= 0 in case one of
1527 the two bounds isn't known. Do the same here? */
1529 if (host_integerp (low
, 0)
1531 && host_integerp (high
, 0)
1532 /* 1-element arrays at end of structures may extend over
1533 their declared size. */
1534 && !(array_at_struct_end_p (ref
)
1535 && operand_equal_p (low
, high
, 0)))
1539 isl_set
*univ
, *lbs
, *ubs
;
1543 isl_pw_aff
*lb
= extract_affine_int (low
, isl_set_get_space (extent
));
1544 isl_pw_aff
*ub
= extract_affine_int (high
, isl_set_get_space (extent
));
1547 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub
));
1548 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
1549 isl_set_dim (valid
, isl_dim_set
));
1550 scop
->context
= isl_set_intersect (scop
->context
, valid
);
1552 space
= isl_set_get_space (extent
);
1553 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
1554 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_in
, i
+ 1, 1);
1555 univ
= isl_set_universe (isl_space_domain (isl_aff_get_space (aff
)));
1556 index
= isl_pw_aff_alloc (univ
, aff
);
1558 id
= isl_set_get_tuple_id (extent
);
1559 lb
= isl_pw_aff_set_tuple_id (lb
, isl_dim_in
, isl_id_copy (id
));
1560 ub
= isl_pw_aff_set_tuple_id (ub
, isl_dim_in
, id
);
1562 /* low <= sub_i <= high */
1563 lbs
= isl_pw_aff_ge_set (isl_pw_aff_copy (index
), lb
);
1564 ubs
= isl_pw_aff_le_set (index
, ub
);
1565 extent
= isl_set_intersect (extent
, lbs
);
1566 extent
= isl_set_intersect (extent
, ubs
);
1573 /* Build data accesses for DR in PBB. */
1576 build_poly_dr (data_reference_p dr
, poly_bb_p pbb
)
1578 int dr_base_object_set
;
1581 scop_p scop
= PBB_SCOP (pbb
);
1584 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1585 int nb_out
= 1 + DR_NUM_DIMENSIONS (dr
);
1586 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1587 isl_dim_out
, nb_out
);
1589 acc
= isl_map_universe (space
);
1590 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, isl_id_for_dr (scop
, dr
));
1593 acc
= pdr_add_alias_set (acc
, dr
);
1594 acc
= pdr_add_memory_accesses (acc
, dr
, pbb
);
1597 isl_id
*id
= isl_id_for_dr (scop
, dr
);
1598 int nb
= 1 + DR_NUM_DIMENSIONS (dr
);
1599 isl_space
*space
= isl_space_set_alloc (scop
->ctx
, 0, nb
);
1600 int alias_set_num
= 0;
1601 base_alias_pair
*bap
= (base_alias_pair
*)(dr
->aux
);
1603 if (bap
&& bap
->alias_set
)
1604 alias_set_num
= *(bap
->alias_set
);
1606 space
= isl_space_set_tuple_id (space
, isl_dim_set
, id
);
1607 extent
= isl_set_nat_universe (space
);
1608 extent
= isl_set_fix_si (extent
, isl_dim_set
, 0, alias_set_num
);
1609 extent
= pdr_add_data_dimensions (extent
, scop
, dr
);
1612 gcc_assert (dr
->aux
);
1613 dr_base_object_set
= ((base_alias_pair
*)(dr
->aux
))->base_obj_set
;
1615 new_poly_dr (pbb
, dr_base_object_set
,
1616 DR_IS_READ (dr
) ? PDR_READ
: PDR_WRITE
,
1617 dr
, DR_NUM_DIMENSIONS (dr
), acc
, extent
);
1620 /* Write to FILE the alias graph of data references in DIMACS format. */
1623 write_alias_graph_to_ascii_dimacs (FILE *file
, char *comment
,
1624 vec
<data_reference_p
> drs
)
1626 int num_vertex
= drs
.length ();
1628 data_reference_p dr1
, dr2
;
1631 if (num_vertex
== 0)
1634 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1635 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1636 if (dr_may_alias_p (dr1
, dr2
, true))
1639 fprintf (file
, "$\n");
1642 fprintf (file
, "c %s\n", comment
);
1644 fprintf (file
, "p edge %d %d\n", num_vertex
, edge_num
);
1646 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1647 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1648 if (dr_may_alias_p (dr1
, dr2
, true))
1649 fprintf (file
, "e %d %d\n", i
+ 1, j
+ 1);
1654 /* Write to FILE the alias graph of data references in DOT format. */
1657 write_alias_graph_to_ascii_dot (FILE *file
, char *comment
,
1658 vec
<data_reference_p
> drs
)
1660 int num_vertex
= drs
.length ();
1661 data_reference_p dr1
, dr2
;
1664 if (num_vertex
== 0)
1667 fprintf (file
, "$\n");
1670 fprintf (file
, "c %s\n", comment
);
1672 /* First print all the vertices. */
1673 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1674 fprintf (file
, "n%d;\n", i
);
1676 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1677 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1678 if (dr_may_alias_p (dr1
, dr2
, true))
1679 fprintf (file
, "n%d n%d\n", i
, j
);
1684 /* Write to FILE the alias graph of data references in ECC format. */
1687 write_alias_graph_to_ascii_ecc (FILE *file
, char *comment
,
1688 vec
<data_reference_p
> drs
)
1690 int num_vertex
= drs
.length ();
1691 data_reference_p dr1
, dr2
;
1694 if (num_vertex
== 0)
1697 fprintf (file
, "$\n");
1700 fprintf (file
, "c %s\n", comment
);
1702 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1703 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1704 if (dr_may_alias_p (dr1
, dr2
, true))
1705 fprintf (file
, "%d %d\n", i
, j
);
1710 /* Check if DR1 and DR2 are in the same object set. */
1713 dr_same_base_object_p (const struct data_reference
*dr1
,
1714 const struct data_reference
*dr2
)
1716 return operand_equal_p (DR_BASE_OBJECT (dr1
), DR_BASE_OBJECT (dr2
), 0);
1719 /* Uses DFS component number as representative of alias-sets. Also tests for
1720 optimality by verifying if every connected component is a clique. Returns
1721 true (1) if the above test is true, and false (0) otherwise. */
1724 build_alias_set_optimal_p (vec
<data_reference_p
> drs
)
1726 int num_vertices
= drs
.length ();
1727 struct graph
*g
= new_graph (num_vertices
);
1728 data_reference_p dr1
, dr2
;
1730 int num_connected_components
;
1731 int v_indx1
, v_indx2
, num_vertices_in_component
;
1734 struct graph_edge
*e
;
1735 int this_component_is_clique
;
1736 int all_components_are_cliques
= 1;
1738 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1739 for (j
= i
+1; drs
.iterate (j
, &dr2
); j
++)
1740 if (dr_may_alias_p (dr1
, dr2
, true))
1746 all_vertices
= XNEWVEC (int, num_vertices
);
1747 vertices
= XNEWVEC (int, num_vertices
);
1748 for (i
= 0; i
< num_vertices
; i
++)
1749 all_vertices
[i
] = i
;
1751 num_connected_components
= graphds_dfs (g
, all_vertices
, num_vertices
,
1753 for (i
= 0; i
< g
->n_vertices
; i
++)
1755 data_reference_p dr
= drs
[i
];
1756 base_alias_pair
*bap
;
1758 gcc_assert (dr
->aux
);
1759 bap
= (base_alias_pair
*)(dr
->aux
);
1761 bap
->alias_set
= XNEW (int);
1762 *(bap
->alias_set
) = g
->vertices
[i
].component
+ 1;
1765 /* Verify if the DFS numbering results in optimal solution. */
1766 for (i
= 0; i
< num_connected_components
; i
++)
1768 num_vertices_in_component
= 0;
1769 /* Get all vertices whose DFS component number is the same as i. */
1770 for (j
= 0; j
< num_vertices
; j
++)
1771 if (g
->vertices
[j
].component
== i
)
1772 vertices
[num_vertices_in_component
++] = j
;
1774 /* Now test if the vertices in 'vertices' form a clique, by testing
1775 for edges among each pair. */
1776 this_component_is_clique
= 1;
1777 for (v_indx1
= 0; v_indx1
< num_vertices_in_component
; v_indx1
++)
1779 for (v_indx2
= v_indx1
+1; v_indx2
< num_vertices_in_component
; v_indx2
++)
1781 /* Check if the two vertices are connected by iterating
1782 through all the edges which have one of these are source. */
1783 e
= g
->vertices
[vertices
[v_indx2
]].pred
;
1786 if (e
->src
== vertices
[v_indx1
])
1792 this_component_is_clique
= 0;
1796 if (!this_component_is_clique
)
1797 all_components_are_cliques
= 0;
1801 free (all_vertices
);
1804 return all_components_are_cliques
;
1807 /* Group each data reference in DRS with its base object set num. */
1810 build_base_obj_set_for_drs (vec
<data_reference_p
> drs
)
1812 int num_vertex
= drs
.length ();
1813 struct graph
*g
= new_graph (num_vertex
);
1814 data_reference_p dr1
, dr2
;
1818 FOR_EACH_VEC_ELT (drs
, i
, dr1
)
1819 for (j
= i
+ 1; drs
.iterate (j
, &dr2
); j
++)
1820 if (dr_same_base_object_p (dr1
, dr2
))
1826 queue
= XNEWVEC (int, num_vertex
);
1827 for (i
= 0; i
< num_vertex
; i
++)
1830 graphds_dfs (g
, queue
, num_vertex
, NULL
, true, NULL
);
1832 for (i
= 0; i
< g
->n_vertices
; i
++)
1834 data_reference_p dr
= drs
[i
];
1835 base_alias_pair
*bap
;
1837 gcc_assert (dr
->aux
);
1838 bap
= (base_alias_pair
*)(dr
->aux
);
1840 bap
->base_obj_set
= g
->vertices
[i
].component
+ 1;
1847 /* Build the data references for PBB. */
1850 build_pbb_drs (poly_bb_p pbb
)
1853 data_reference_p dr
;
1854 vec
<data_reference_p
> gbb_drs
= GBB_DATA_REFS (PBB_BLACK_BOX (pbb
));
1856 FOR_EACH_VEC_ELT (gbb_drs
, j
, dr
)
1857 build_poly_dr (dr
, pbb
);
1860 /* Dump to file the alias graphs for the data references in DRS. */
1863 dump_alias_graphs (vec
<data_reference_p
> drs
)
1866 FILE *file_dimacs
, *file_ecc
, *file_dot
;
1868 file_dimacs
= fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1871 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1872 current_function_name ());
1873 write_alias_graph_to_ascii_dimacs (file_dimacs
, comment
, drs
);
1874 fclose (file_dimacs
);
1877 file_ecc
= fopen ("/tmp/dr_alias_graph_ecc", "ab");
1880 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1881 current_function_name ());
1882 write_alias_graph_to_ascii_ecc (file_ecc
, comment
, drs
);
1886 file_dot
= fopen ("/tmp/dr_alias_graph_dot", "ab");
1889 snprintf (comment
, sizeof (comment
), "%s %s", main_input_filename
,
1890 current_function_name ());
1891 write_alias_graph_to_ascii_dot (file_dot
, comment
, drs
);
1896 /* Build data references in SCOP. */
1899 build_scop_drs (scop_p scop
)
1903 data_reference_p dr
;
1904 vec
<data_reference_p
> drs
;
1907 /* Remove all the PBBs that do not have data references: these basic
1908 blocks are not handled in the polyhedral representation. */
1909 for (i
= 0; SCOP_BBS (scop
).iterate (i
, &pbb
); i
++)
1910 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).is_empty ())
1912 free_gimple_bb (PBB_BLACK_BOX (pbb
));
1914 SCOP_BBS (scop
).ordered_remove (i
);
1918 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1919 for (j
= 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb
)).iterate (j
, &dr
); j
++)
1922 FOR_EACH_VEC_ELT (drs
, i
, dr
)
1923 dr
->aux
= XNEW (base_alias_pair
);
1925 if (!build_alias_set_optimal_p (drs
))
1927 /* TODO: Add support when building alias set is not optimal. */
1931 build_base_obj_set_for_drs (drs
);
1933 /* When debugging, enable the following code. This cannot be used
1934 in production compilers. */
1936 dump_alias_graphs (drs
);
1940 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1941 build_pbb_drs (pbb
);
1944 /* Return a gsi at the position of the phi node STMT. */
1946 static gimple_stmt_iterator
1947 gsi_for_phi_node (gimple stmt
)
1949 gimple_stmt_iterator psi
;
1950 basic_block bb
= gimple_bb (stmt
);
1952 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
1953 if (stmt
== gsi_stmt (psi
))
1960 /* Analyze all the data references of STMTS and add them to the
1961 GBB_DATA_REFS vector of BB. */
1964 analyze_drs_in_stmts (scop_p scop
, basic_block bb
, vec
<gimple
> stmts
)
1970 sese region
= SCOP_REGION (scop
);
1972 if (!bb_in_sese_p (bb
, region
))
1975 nest
= outermost_loop_in_sese_1 (region
, bb
);
1976 gbb
= gbb_from_bb (bb
);
1978 FOR_EACH_VEC_ELT (stmts
, i
, stmt
)
1982 if (is_gimple_debug (stmt
))
1985 loop
= loop_containing_stmt (stmt
);
1986 if (!loop_in_sese_p (loop
, region
))
1989 graphite_find_data_references_in_stmt (nest
, loop
, stmt
,
1990 &GBB_DATA_REFS (gbb
));
1994 /* Insert STMT at the end of the STMTS sequence and then insert the
1995 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1999 insert_stmts (scop_p scop
, gimple stmt
, gimple_seq stmts
,
2000 gimple_stmt_iterator insert_gsi
)
2002 gimple_stmt_iterator gsi
;
2006 gimple_seq_add_stmt (&stmts
, stmt
);
2007 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2008 x
.safe_push (gsi_stmt (gsi
));
2010 gsi_insert_seq_before (&insert_gsi
, stmts
, GSI_SAME_STMT
);
2011 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 gimple stmt
= gimple_build_assign (unshare_expr (res
), var
);
2027 gimple_seq_add_stmt (&stmts
, stmt
);
2028 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2029 x
.safe_push (gsi_stmt (gsi
));
2031 if (gimple_code (after_stmt
) == GIMPLE_PHI
)
2033 gsi
= gsi_after_labels (gimple_bb (after_stmt
));
2034 gsi_insert_seq_before (&gsi
, stmts
, GSI_NEW_STMT
);
2038 gsi
= gsi_for_stmt (after_stmt
);
2039 gsi_insert_seq_after (&gsi
, stmts
, GSI_NEW_STMT
);
2042 analyze_drs_in_stmts (scop
, gimple_bb (after_stmt
), x
);
2046 /* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2049 new_pbb_from_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
)
2051 vec
<data_reference_p
> drs
;
2053 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
2054 gimple_bb_p gbb1
= new_gimple_bb (bb
, drs
);
2055 poly_bb_p pbb1
= new_poly_bb (scop
, gbb1
);
2056 int index
, n
= SCOP_BBS (scop
).length ();
2058 /* The INDEX of PBB in SCOP_BBS. */
2059 for (index
= 0; index
< n
; index
++)
2060 if (SCOP_BBS (scop
)[index
] == pbb
)
2063 pbb1
->domain
= isl_set_copy (pbb
->domain
);
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
);
2084 gimple_seq_add_stmt (&stmts
, stmt
);
2085 for (gsi
= gsi_start (stmts
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2086 x
.safe_push (gsi_stmt (gsi
));
2088 gsi_insert_seq_on_edge (e
, stmts
);
2089 gsi_commit_edge_inserts ();
2090 bb
= gimple_bb (stmt
);
2092 if (!bb_in_sese_p (bb
, SCOP_REGION (scop
)))
2095 if (!gbb_from_bb (bb
))
2096 new_pbb_from_pbb (scop
, pbb_from_bb (e
->src
), bb
);
2098 analyze_drs_in_stmts (scop
, bb
, x
);
2102 /* Creates a zero dimension array of the same type as VAR. */
2105 create_zero_dim_array (tree var
, const char *base_name
)
2107 tree index_type
= build_index_type (integer_zero_node
);
2108 tree elt_type
= TREE_TYPE (var
);
2109 tree array_type
= build_array_type (elt_type
, index_type
);
2110 tree base
= create_tmp_var (array_type
, base_name
);
2112 return build4 (ARRAY_REF
, elt_type
, base
, integer_zero_node
, NULL_TREE
,
2116 /* Returns true when PHI is a loop close phi node. */
2119 scalar_close_phi_node_p (gimple phi
)
2121 if (gimple_code (phi
) != GIMPLE_PHI
2122 || virtual_operand_p (gimple_phi_result (phi
)))
2125 /* Note that loop close phi nodes should have a single argument
2126 because we translated the representation into a canonical form
2127 before Graphite: see canonicalize_loop_closed_ssa_form. */
2128 return (gimple_phi_num_args (phi
) == 1);
2131 /* For a definition DEF in REGION, propagates the expression EXPR in
2132 all the uses of DEF outside REGION. */
2135 propagate_expr_outside_region (tree def
, tree expr
, sese region
)
2137 imm_use_iterator imm_iter
;
2140 bool replaced_once
= false;
2142 gcc_assert (TREE_CODE (def
) == SSA_NAME
);
2144 expr
= force_gimple_operand (unshare_expr (expr
), &stmts
, true,
2147 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2148 if (!is_gimple_debug (use_stmt
)
2149 && !bb_in_sese_p (gimple_bb (use_stmt
), region
))
2152 use_operand_p use_p
;
2154 FOR_EACH_PHI_OR_STMT_USE (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2155 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0)
2156 && (replaced_once
= true))
2157 replace_exp (use_p
, expr
);
2159 update_stmt (use_stmt
);
2164 gsi_insert_seq_on_edge (SESE_ENTRY (region
), stmts
);
2165 gsi_commit_edge_inserts ();
2169 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2170 dimension array for it. */
2173 rewrite_close_phi_out_of_ssa (scop_p scop
, gimple_stmt_iterator
*psi
)
2175 sese region
= SCOP_REGION (scop
);
2176 gimple phi
= gsi_stmt (*psi
);
2177 tree res
= gimple_phi_result (phi
);
2178 basic_block bb
= gimple_bb (phi
);
2179 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
2180 tree arg
= gimple_phi_arg_def (phi
, 0);
2183 /* Note that loop close phi nodes should have a single argument
2184 because we translated the representation into a canonical form
2185 before Graphite: see canonicalize_loop_closed_ssa_form. */
2186 gcc_assert (gimple_phi_num_args (phi
) == 1);
2188 /* The phi node can be a non close phi node, when its argument is
2189 invariant, or a default definition. */
2190 if (is_gimple_min_invariant (arg
)
2191 || SSA_NAME_IS_DEFAULT_DEF (arg
))
2193 propagate_expr_outside_region (res
, arg
, region
);
2198 else if (gimple_bb (SSA_NAME_DEF_STMT (arg
))->loop_father
== bb
->loop_father
)
2200 propagate_expr_outside_region (res
, arg
, region
);
2201 stmt
= gimple_build_assign (res
, arg
);
2202 remove_phi_node (psi
, false);
2203 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2204 SSA_NAME_DEF_STMT (res
) = stmt
;
2208 /* If res is scev analyzable and is not a scalar value, it is safe
2209 to ignore the close phi node: it will be code generated in the
2210 out of Graphite pass. */
2211 else if (scev_analyzable_p (res
, region
))
2213 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (res
));
2216 if (!loop_in_sese_p (loop
, region
))
2218 loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2219 scev
= scalar_evolution_in_region (region
, loop
, arg
);
2220 scev
= compute_overall_effect_of_inner_loop (loop
, scev
);
2223 scev
= scalar_evolution_in_region (region
, loop
, res
);
2225 if (tree_does_not_contain_chrecs (scev
))
2226 propagate_expr_outside_region (res
, scev
, region
);
2233 tree zero_dim_array
= create_zero_dim_array (res
, "Close_Phi");
2235 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2237 if (TREE_CODE (arg
) == SSA_NAME
)
2238 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2239 SSA_NAME_DEF_STMT (arg
));
2241 insert_out_of_ssa_copy_on_edge (scop
, single_pred_edge (bb
),
2242 zero_dim_array
, arg
);
2245 remove_phi_node (psi
, false);
2246 SSA_NAME_DEF_STMT (res
) = stmt
;
2248 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2251 /* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2252 dimension array for it. */
2255 rewrite_phi_out_of_ssa (scop_p scop
, gimple_stmt_iterator
*psi
)
2258 gimple phi
= gsi_stmt (*psi
);
2259 basic_block bb
= gimple_bb (phi
);
2260 tree res
= gimple_phi_result (phi
);
2261 tree zero_dim_array
= create_zero_dim_array (res
, "phi_out_of_ssa");
2264 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2266 tree arg
= gimple_phi_arg_def (phi
, i
);
2267 edge e
= gimple_phi_arg_edge (phi
, i
);
2269 /* Avoid the insertion of code in the loop latch to please the
2270 pattern matching of the vectorizer. */
2271 if (TREE_CODE (arg
) == SSA_NAME
2272 && e
->src
== bb
->loop_father
->latch
)
2273 insert_out_of_ssa_copy (scop
, zero_dim_array
, arg
,
2274 SSA_NAME_DEF_STMT (arg
));
2276 insert_out_of_ssa_copy_on_edge (scop
, e
, zero_dim_array
, arg
);
2279 stmt
= gimple_build_assign (res
, unshare_expr (zero_dim_array
));
2280 remove_phi_node (psi
, false);
2281 SSA_NAME_DEF_STMT (res
) = stmt
;
2282 insert_stmts (scop
, stmt
, NULL
, gsi_after_labels (bb
));
2285 /* Rewrite the degenerate phi node at position PSI from the degenerate
2286 form "x = phi (y, y, ..., y)" to "x = y". */
2289 rewrite_degenerate_phi (gimple_stmt_iterator
*psi
)
2293 gimple_stmt_iterator gsi
;
2294 gimple phi
= gsi_stmt (*psi
);
2295 tree res
= gimple_phi_result (phi
);
2298 bb
= gimple_bb (phi
);
2299 rhs
= degenerate_phi_result (phi
);
2302 stmt
= gimple_build_assign (res
, rhs
);
2303 remove_phi_node (psi
, false);
2304 SSA_NAME_DEF_STMT (res
) = stmt
;
2306 gsi
= gsi_after_labels (bb
);
2307 gsi_insert_before (&gsi
, stmt
, GSI_NEW_STMT
);
2310 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2313 rewrite_reductions_out_of_ssa (scop_p scop
)
2316 gimple_stmt_iterator psi
;
2317 sese region
= SCOP_REGION (scop
);
2320 if (bb_in_sese_p (bb
, region
))
2321 for (psi
= gsi_start_phis (bb
); !gsi_end_p (psi
);)
2323 gimple phi
= gsi_stmt (psi
);
2325 if (virtual_operand_p (gimple_phi_result (phi
)))
2331 if (gimple_phi_num_args (phi
) > 1
2332 && degenerate_phi_result (phi
))
2333 rewrite_degenerate_phi (&psi
);
2335 else if (scalar_close_phi_node_p (phi
))
2336 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2338 else if (reduction_phi_p (region
, &psi
))
2339 rewrite_phi_out_of_ssa (scop
, &psi
);
2342 update_ssa (TODO_update_ssa
);
2343 #ifdef ENABLE_CHECKING
2344 verify_loop_closed_ssa (true);
2348 /* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2349 read from ZERO_DIM_ARRAY. */
2352 rewrite_cross_bb_scalar_dependence (scop_p scop
, tree zero_dim_array
,
2353 tree def
, gimple use_stmt
)
2358 use_operand_p use_p
;
2360 gcc_assert (gimple_code (use_stmt
) != GIMPLE_PHI
);
2362 name
= copy_ssa_name (def
, NULL
);
2363 name_stmt
= gimple_build_assign (name
, zero_dim_array
);
2365 gimple_assign_set_lhs (name_stmt
, name
);
2366 insert_stmts (scop
, name_stmt
, NULL
, gsi_for_stmt (use_stmt
));
2368 FOR_EACH_SSA_USE_OPERAND (use_p
, use_stmt
, iter
, SSA_OP_ALL_USES
)
2369 if (operand_equal_p (def
, USE_FROM_PTR (use_p
), 0))
2370 replace_exp (use_p
, name
);
2372 update_stmt (use_stmt
);
2375 /* For every definition DEF in the SCOP that is used outside the scop,
2376 insert a closing-scop definition in the basic block just after this
2380 handle_scalar_deps_crossing_scop_limits (scop_p scop
, tree def
, gimple stmt
)
2382 tree var
= create_tmp_reg (TREE_TYPE (def
), NULL
);
2383 tree new_name
= make_ssa_name (var
, stmt
);
2384 bool needs_copy
= false;
2385 use_operand_p use_p
;
2386 imm_use_iterator imm_iter
;
2388 sese region
= SCOP_REGION (scop
);
2390 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2392 if (!bb_in_sese_p (gimple_bb (use_stmt
), region
))
2394 FOR_EACH_IMM_USE_ON_STMT (use_p
, imm_iter
)
2396 SET_USE (use_p
, new_name
);
2398 update_stmt (use_stmt
);
2403 /* Insert in the empty BB just after the scop a use of DEF such
2404 that the rewrite of cross_bb_scalar_dependences won't insert
2405 arrays everywhere else. */
2408 gimple assign
= gimple_build_assign (new_name
, def
);
2409 gimple_stmt_iterator psi
= gsi_after_labels (SESE_EXIT (region
)->dest
);
2411 SSA_NAME_DEF_STMT (new_name
) = assign
;
2412 update_stmt (assign
);
2413 gsi_insert_before (&psi
, assign
, GSI_SAME_STMT
);
2417 /* Rewrite the scalar dependences crossing the boundary of the BB
2418 containing STMT with an array. Return true when something has been
2422 rewrite_cross_bb_scalar_deps (scop_p scop
, gimple_stmt_iterator
*gsi
)
2424 sese region
= SCOP_REGION (scop
);
2425 gimple stmt
= gsi_stmt (*gsi
);
2426 imm_use_iterator imm_iter
;
2429 tree zero_dim_array
= NULL_TREE
;
2433 switch (gimple_code (stmt
))
2436 def
= gimple_assign_lhs (stmt
);
2440 def
= gimple_call_lhs (stmt
);
2448 || !is_gimple_reg (def
))
2451 if (scev_analyzable_p (def
, region
))
2453 loop_p loop
= loop_containing_stmt (SSA_NAME_DEF_STMT (def
));
2454 tree scev
= scalar_evolution_in_region (region
, loop
, def
);
2456 if (tree_contains_chrecs (scev
, NULL
))
2459 propagate_expr_outside_region (def
, scev
, region
);
2463 def_bb
= gimple_bb (stmt
);
2465 handle_scalar_deps_crossing_scop_limits (scop
, def
, stmt
);
2467 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2468 if (gimple_code (use_stmt
) == GIMPLE_PHI
2471 gimple_stmt_iterator psi
= gsi_for_stmt (use_stmt
);
2473 if (scalar_close_phi_node_p (gsi_stmt (psi
)))
2474 rewrite_close_phi_out_of_ssa (scop
, &psi
);
2476 rewrite_phi_out_of_ssa (scop
, &psi
);
2479 FOR_EACH_IMM_USE_STMT (use_stmt
, imm_iter
, def
)
2480 if (gimple_code (use_stmt
) != GIMPLE_PHI
2481 && def_bb
!= gimple_bb (use_stmt
)
2482 && !is_gimple_debug (use_stmt
)
2485 if (!zero_dim_array
)
2487 zero_dim_array
= create_zero_dim_array
2488 (def
, "Cross_BB_scalar_dependence");
2489 insert_out_of_ssa_copy (scop
, zero_dim_array
, def
,
2490 SSA_NAME_DEF_STMT (def
));
2494 rewrite_cross_bb_scalar_dependence (scop
, zero_dim_array
,
2501 /* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2504 rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop
)
2507 gimple_stmt_iterator psi
;
2508 sese region
= SCOP_REGION (scop
);
2509 bool changed
= false;
2511 /* Create an extra empty BB after the scop. */
2512 split_edge (SESE_EXIT (region
));
2515 if (bb_in_sese_p (bb
, region
))
2516 for (psi
= gsi_start_bb (bb
); !gsi_end_p (psi
); gsi_next (&psi
))
2517 changed
|= rewrite_cross_bb_scalar_deps (scop
, &psi
);
2522 update_ssa (TODO_update_ssa
);
2523 #ifdef ENABLE_CHECKING
2524 verify_loop_closed_ssa (true);
2529 /* Returns the number of pbbs that are in loops contained in SCOP. */
2532 nb_pbbs_in_loops (scop_p scop
)
2538 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
2539 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb
)), SCOP_REGION (scop
)))
2545 /* Return the number of data references in BB that write in
2549 nb_data_writes_in_bb (basic_block bb
)
2552 gimple_stmt_iterator gsi
;
2554 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2555 if (gimple_vdef (gsi_stmt (gsi
)))
2561 /* Splits at STMT the basic block BB represented as PBB in the
2565 split_pbb (scop_p scop
, poly_bb_p pbb
, basic_block bb
, gimple stmt
)
2567 edge e1
= split_block (bb
, stmt
);
2568 new_pbb_from_pbb (scop
, pbb
, e1
->dest
);
2572 /* Splits STMT out of its current BB. This is done for reduction
2573 statements for which we want to ignore data dependences. */
2576 split_reduction_stmt (scop_p scop
, gimple stmt
)
2578 basic_block bb
= gimple_bb (stmt
);
2579 poly_bb_p pbb
= pbb_from_bb (bb
);
2580 gimple_bb_p gbb
= gbb_from_bb (bb
);
2583 data_reference_p dr
;
2585 /* Do not split basic blocks with no writes to memory: the reduction
2586 will be the only write to memory. */
2587 if (nb_data_writes_in_bb (bb
) == 0
2588 /* Or if we have already marked BB as a reduction. */
2589 || PBB_IS_REDUCTION (pbb_from_bb (bb
)))
2592 e1
= split_pbb (scop
, pbb
, bb
, stmt
);
2594 /* Split once more only when the reduction stmt is not the only one
2595 left in the original BB. */
2596 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb
)))
2598 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
2600 e1
= split_pbb (scop
, pbb
, bb
, gsi_stmt (gsi
));
2603 /* A part of the data references will end in a different basic block
2604 after the split: move the DRs from the original GBB to the newly
2606 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb
), i
, dr
)
2608 basic_block bb1
= gimple_bb (DR_STMT (dr
));
2612 gimple_bb_p gbb1
= gbb_from_bb (bb1
);
2613 GBB_DATA_REFS (gbb1
).safe_push (dr
);
2614 GBB_DATA_REFS (gbb
).ordered_remove (i
);
2622 /* Return true when stmt is a reduction operation. */
2625 is_reduction_operation_p (gimple stmt
)
2627 enum tree_code code
;
2629 gcc_assert (is_gimple_assign (stmt
));
2630 code
= gimple_assign_rhs_code (stmt
);
2632 return flag_associative_math
2633 && commutative_tree_code (code
)
2634 && associative_tree_code (code
);
2637 /* Returns true when PHI contains an argument ARG. */
2640 phi_contains_arg (gimple phi
, tree arg
)
2644 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2645 if (operand_equal_p (arg
, gimple_phi_arg_def (phi
, i
), 0))
2651 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2654 follow_ssa_with_commutative_ops (tree arg
, tree lhs
)
2658 if (TREE_CODE (arg
) != SSA_NAME
)
2661 stmt
= SSA_NAME_DEF_STMT (arg
);
2663 if (gimple_code (stmt
) == GIMPLE_NOP
2664 || gimple_code (stmt
) == GIMPLE_CALL
)
2667 if (gimple_code (stmt
) == GIMPLE_PHI
)
2669 if (phi_contains_arg (stmt
, lhs
))
2674 if (!is_gimple_assign (stmt
))
2677 if (gimple_num_ops (stmt
) == 2)
2678 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2680 if (is_reduction_operation_p (stmt
))
2682 gimple res
= follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt
), lhs
);
2685 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt
), lhs
);
2691 /* Detect commutative and associative scalar reductions starting at
2692 the STMT. Return the phi node of the reduction cycle, or NULL. */
2695 detect_commutative_reduction_arg (tree lhs
, gimple stmt
, tree arg
,
2699 gimple phi
= follow_ssa_with_commutative_ops (arg
, lhs
);
2704 in
->safe_push (stmt
);
2705 out
->safe_push (stmt
);
2709 /* Detect commutative and associative scalar reductions starting at
2710 STMT. Return the phi node of the reduction cycle, or NULL. */
2713 detect_commutative_reduction_assign (gimple stmt
, vec
<gimple
> *in
,
2716 tree lhs
= gimple_assign_lhs (stmt
);
2718 if (gimple_num_ops (stmt
) == 2)
2719 return detect_commutative_reduction_arg (lhs
, stmt
,
2720 gimple_assign_rhs1 (stmt
),
2723 if (is_reduction_operation_p (stmt
))
2725 gimple res
= detect_commutative_reduction_arg (lhs
, stmt
,
2726 gimple_assign_rhs1 (stmt
),
2729 : detect_commutative_reduction_arg (lhs
, stmt
,
2730 gimple_assign_rhs2 (stmt
),
2737 /* Return a loop phi node that corresponds to a reduction containing LHS. */
2740 follow_inital_value_to_phi (tree arg
, tree lhs
)
2744 if (!arg
|| TREE_CODE (arg
) != SSA_NAME
)
2747 stmt
= SSA_NAME_DEF_STMT (arg
);
2749 if (gimple_code (stmt
) == GIMPLE_PHI
2750 && phi_contains_arg (stmt
, lhs
))
2757 /* Return the argument of the loop PHI that is the initial value coming
2758 from outside the loop. */
2761 edge_initial_value_for_loop_phi (gimple phi
)
2765 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2767 edge e
= gimple_phi_arg_edge (phi
, i
);
2769 if (loop_depth (e
->src
->loop_father
)
2770 < loop_depth (e
->dest
->loop_father
))
2777 /* Return the argument of the loop PHI that is the initial value coming
2778 from outside the loop. */
2781 initial_value_for_loop_phi (gimple phi
)
2785 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2787 edge e
= gimple_phi_arg_edge (phi
, i
);
2789 if (loop_depth (e
->src
->loop_father
)
2790 < loop_depth (e
->dest
->loop_father
))
2791 return gimple_phi_arg_def (phi
, i
);
2797 /* Returns true when DEF is used outside the reduction cycle of
2801 used_outside_reduction (tree def
, gimple loop_phi
)
2803 use_operand_p use_p
;
2804 imm_use_iterator imm_iter
;
2805 loop_p loop
= loop_containing_stmt (loop_phi
);
2807 /* In LOOP, DEF should be used only in LOOP_PHI. */
2808 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2810 gimple stmt
= USE_STMT (use_p
);
2812 if (stmt
!= loop_phi
2813 && !is_gimple_debug (stmt
)
2814 && flow_bb_inside_loop_p (loop
, gimple_bb (stmt
)))
2821 /* Detect commutative and associative scalar reductions belonging to
2822 the SCOP starting at the loop closed phi node STMT. Return the phi
2823 node of the reduction cycle, or NULL. */
2826 detect_commutative_reduction (scop_p scop
, gimple stmt
, vec
<gimple
> *in
,
2829 if (scalar_close_phi_node_p (stmt
))
2831 gimple def
, loop_phi
, phi
, close_phi
= stmt
;
2832 tree init
, lhs
, arg
= gimple_phi_arg_def (close_phi
, 0);
2834 if (TREE_CODE (arg
) != SSA_NAME
)
2837 /* Note that loop close phi nodes should have a single argument
2838 because we translated the representation into a canonical form
2839 before Graphite: see canonicalize_loop_closed_ssa_form. */
2840 gcc_assert (gimple_phi_num_args (close_phi
) == 1);
2842 def
= SSA_NAME_DEF_STMT (arg
);
2843 if (!stmt_in_sese_p (def
, SCOP_REGION (scop
))
2844 || !(loop_phi
= detect_commutative_reduction (scop
, def
, in
, out
)))
2847 lhs
= gimple_phi_result (close_phi
);
2848 init
= initial_value_for_loop_phi (loop_phi
);
2849 phi
= follow_inital_value_to_phi (init
, lhs
);
2851 if (phi
&& (used_outside_reduction (lhs
, phi
)
2852 || !has_single_use (gimple_phi_result (phi
))))
2855 in
->safe_push (loop_phi
);
2856 out
->safe_push (close_phi
);
2860 if (gimple_code (stmt
) == GIMPLE_ASSIGN
)
2861 return detect_commutative_reduction_assign (stmt
, in
, out
);
2866 /* Translate the scalar reduction statement STMT to an array RED
2867 knowing that its recursive phi node is LOOP_PHI. */
2870 translate_scalar_reduction_to_array_for_stmt (scop_p scop
, tree red
,
2871 gimple stmt
, gimple loop_phi
)
2873 tree res
= gimple_phi_result (loop_phi
);
2874 gimple assign
= gimple_build_assign (res
, unshare_expr (red
));
2875 gimple_stmt_iterator gsi
;
2877 insert_stmts (scop
, assign
, NULL
, gsi_after_labels (gimple_bb (loop_phi
)));
2879 assign
= gimple_build_assign (unshare_expr (red
), gimple_assign_lhs (stmt
));
2880 gsi
= gsi_for_stmt (stmt
);
2882 insert_stmts (scop
, assign
, NULL
, gsi
);
2885 /* Removes the PHI node and resets all the debug stmts that are using
2889 remove_phi (gimple phi
)
2891 imm_use_iterator imm_iter
;
2893 use_operand_p use_p
;
2894 gimple_stmt_iterator gsi
;
2900 def
= PHI_RESULT (phi
);
2901 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2903 stmt
= USE_STMT (use_p
);
2905 if (is_gimple_debug (stmt
))
2907 gimple_debug_bind_reset_value (stmt
);
2908 update
.safe_push (stmt
);
2912 FOR_EACH_VEC_ELT (update
, i
, stmt
)
2917 gsi
= gsi_for_phi_node (phi
);
2918 remove_phi_node (&gsi
, false);
2921 /* Helper function for for_each_index. For each INDEX of the data
2922 reference REF, returns true when its indices are valid in the loop
2923 nest LOOP passed in as DATA. */
2926 dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED
, tree
*index
, void *data
)
2929 basic_block header
, def_bb
;
2932 if (TREE_CODE (*index
) != SSA_NAME
)
2935 loop
= *((loop_p
*) data
);
2936 header
= loop
->header
;
2937 stmt
= SSA_NAME_DEF_STMT (*index
);
2942 def_bb
= gimple_bb (stmt
);
2947 return dominated_by_p (CDI_DOMINATORS
, header
, def_bb
);
2950 /* When the result of a CLOSE_PHI is written to a memory location,
2951 return a pointer to that memory reference, otherwise return
2955 close_phi_written_to_memory (gimple close_phi
)
2957 imm_use_iterator imm_iter
;
2958 use_operand_p use_p
;
2960 tree res
, def
= gimple_phi_result (close_phi
);
2962 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, def
)
2963 if ((stmt
= USE_STMT (use_p
))
2964 && gimple_code (stmt
) == GIMPLE_ASSIGN
2965 && (res
= gimple_assign_lhs (stmt
)))
2967 switch (TREE_CODE (res
))
2977 tree arg
= gimple_phi_arg_def (close_phi
, 0);
2978 loop_p nest
= loop_containing_stmt (SSA_NAME_DEF_STMT (arg
));
2980 /* FIXME: this restriction is for id-{24,25}.f and
2981 could be handled by duplicating the computation of
2982 array indices before the loop of the close_phi. */
2983 if (for_each_index (&res
, dr_indices_valid_in_loop
, &nest
))
2995 /* Rewrite out of SSA the reduction described by the loop phi nodes
2996 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2999 IN: stmt, loop_n, ..., loop_0
3000 OUT: stmt, close_n, ..., close_0
3002 the first element is the reduction statement, and the next elements
3003 are the loop and close phi nodes of each of the outer loops. */
3006 translate_scalar_reduction_to_array (scop_p scop
,
3011 unsigned int i
= out
.length () - 1;
3012 tree red
= close_phi_written_to_memory (out
[i
]);
3014 FOR_EACH_VEC_ELT (in
, i
, loop_phi
)
3016 gimple close_phi
= out
[i
];
3020 gimple stmt
= loop_phi
;
3021 basic_block bb
= split_reduction_stmt (scop
, stmt
);
3022 poly_bb_p pbb
= pbb_from_bb (bb
);
3023 PBB_IS_REDUCTION (pbb
) = true;
3024 gcc_assert (close_phi
== loop_phi
);
3027 red
= create_zero_dim_array
3028 (gimple_assign_lhs (stmt
), "Commutative_Associative_Reduction");
3030 translate_scalar_reduction_to_array_for_stmt (scop
, red
, stmt
, in
[1]);
3034 if (i
== in
.length () - 1)
3036 insert_out_of_ssa_copy (scop
, gimple_phi_result (close_phi
),
3037 unshare_expr (red
), close_phi
);
3038 insert_out_of_ssa_copy_on_edge
3039 (scop
, edge_initial_value_for_loop_phi (loop_phi
),
3040 unshare_expr (red
), initial_value_for_loop_phi (loop_phi
));
3043 remove_phi (loop_phi
);
3044 remove_phi (close_phi
);
3048 /* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3049 true when something has been changed. */
3052 rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop
,
3061 detect_commutative_reduction (scop
, close_phi
, &in
, &out
);
3062 res
= in
.length () > 1;
3064 translate_scalar_reduction_to_array (scop
, in
, out
);
3071 /* Rewrites all the commutative reductions from LOOP out of SSA.
3072 Returns true when something has been changed. */
3075 rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop
,
3078 gimple_stmt_iterator gsi
;
3079 edge exit
= single_exit (loop
);
3081 bool changed
= false;
3086 for (gsi
= gsi_start_phis (exit
->dest
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3087 if ((res
= gimple_phi_result (gsi_stmt (gsi
)))
3088 && !virtual_operand_p (res
)
3089 && !scev_analyzable_p (res
, SCOP_REGION (scop
)))
3090 changed
|= rewrite_commutative_reductions_out_of_ssa_close_phi
3091 (scop
, gsi_stmt (gsi
));
3096 /* Rewrites all the commutative reductions from SCOP out of SSA. */
3099 rewrite_commutative_reductions_out_of_ssa (scop_p scop
)
3103 bool changed
= false;
3104 sese region
= SCOP_REGION (scop
);
3106 FOR_EACH_LOOP (li
, loop
, 0)
3107 if (loop_in_sese_p (loop
, region
))
3108 changed
|= rewrite_commutative_reductions_out_of_ssa_loop (scop
, loop
);
3113 gsi_commit_edge_inserts ();
3114 update_ssa (TODO_update_ssa
);
3115 #ifdef ENABLE_CHECKING
3116 verify_loop_closed_ssa (true);
3121 /* Can all ivs be represented by a signed integer?
3122 As CLooG might generate negative values in its expressions, signed loop ivs
3123 are required in the backend. */
3126 scop_ivs_can_be_represented (scop_p scop
)
3130 gimple_stmt_iterator psi
;
3133 FOR_EACH_LOOP (li
, loop
, 0)
3135 if (!loop_in_sese_p (loop
, SCOP_REGION (scop
)))
3138 for (psi
= gsi_start_phis (loop
->header
);
3139 !gsi_end_p (psi
); gsi_next (&psi
))
3141 gimple phi
= gsi_stmt (psi
);
3142 tree res
= PHI_RESULT (phi
);
3143 tree type
= TREE_TYPE (res
);
3145 if (TYPE_UNSIGNED (type
)
3146 && TYPE_PRECISION (type
) >= TYPE_PRECISION (long_long_integer_type_node
))
3153 FOR_EACH_LOOP_BREAK (li
);
3159 /* Builds the polyhedral representation for a SESE region. */
3162 build_poly_scop (scop_p scop
)
3164 sese region
= SCOP_REGION (scop
);
3165 graphite_dim_t max_dim
;
3167 build_scop_bbs (scop
);
3169 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3170 Once CLooG is fixed, remove this guard. Anyways, it makes no
3171 sense to optimize a scop containing only PBBs that do not belong
3173 if (nb_pbbs_in_loops (scop
) == 0)
3176 if (!scop_ivs_can_be_represented (scop
))
3179 if (flag_associative_math
)
3180 rewrite_commutative_reductions_out_of_ssa (scop
);
3182 build_sese_loop_nests (region
);
3183 build_sese_conditions (region
);
3184 find_scop_parameters (scop
);
3186 max_dim
= PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS
);
3187 if (scop_nb_params (scop
) > max_dim
)
3190 build_scop_iteration_domain (scop
);
3191 build_scop_context (scop
);
3192 add_conditions_to_constraints (scop
);
3194 /* Rewrite out of SSA only after having translated the
3195 representation to the polyhedral representation to avoid scev
3196 analysis failures. That means that these functions will insert
3197 new data references that they create in the right place. */
3198 rewrite_reductions_out_of_ssa (scop
);
3199 rewrite_cross_bb_scalar_deps_out_of_ssa (scop
);
3201 build_scop_drs (scop
);
3203 build_scop_scattering (scop
);
3205 /* This SCoP has been translated to the polyhedral
3207 POLY_SCOP_P (scop
) = true;