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/>. */
28 #include "coretypes.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
38 #include "gimplify-me.h"
40 #include "tree-ssa-loop-manip.h"
41 #include "tree-ssa-loop-niter.h"
42 #include "tree-ssa-loop.h"
43 #include "tree-into-ssa.h"
44 #include "tree-pass.h"
46 #include "tree-data-ref.h"
47 #include "tree-scalar-evolution.h"
49 #include "tree-ssa-propagate.h"
51 #include <isl/constraint.h>
54 #include <isl/union_map.h>
55 #include <isl/constraint.h>
59 /* Since ISL-0.13, the extern is in val_gmp.h. */
60 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
63 #include <isl/val_gmp.h>
64 #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
70 /* Assigns to RES the value of the INTEGER_CST T. */
73 tree_int_to_gmp (tree t
, mpz_t res
)
75 wi::to_mpz (t
, res
, TYPE_SIGN (TREE_TYPE (t
)));
78 /* Return an ISL identifier for the polyhedral basic block PBB. */
81 isl_id_for_pbb (scop_p s
, poly_bb_p pbb
)
84 snprintf (name
, sizeof (name
), "S_%d", pbb_index (pbb
));
85 return isl_id_alloc (s
->isl_context
, name
, pbb
);
88 /* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
89 We generate SCATTERING_DIMENSIONS scattering dimensions.
91 The scattering polyhedron consists of these dimensions: scattering,
92 loop_iterators, parameters.
96 | scattering_dimensions = 5
104 | Scattering polyhedron:
106 | scattering: {s1, s2, s3, s4, s5}
107 | loop_iterators: {i}
108 | parameters: {p1, p2}
110 | s1 s2 s3 s4 s5 i p1 p2 1
111 | 1 0 0 0 0 0 0 0 -4 = 0
112 | 0 1 0 0 0 -1 0 0 0 = 0
113 | 0 0 1 0 0 0 0 0 -5 = 0 */
116 build_pbb_scattering_polyhedrons (isl_aff
*static_sched
,
121 int scattering_dimensions
= isl_set_dim (pbb
->domain
, isl_dim_set
) * 2 + 1;
123 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
124 isl_space
*dm
= isl_space_add_dims (isl_space_from_domain (dc
),
125 isl_dim_out
, scattering_dimensions
);
126 pbb
->schedule
= isl_map_universe (dm
);
128 for (int i
= 0; i
< scattering_dimensions
; i
++)
130 /* Textual order inside this loop. */
133 isl_constraint
*c
= isl_equality_alloc
134 (isl_local_space_from_space (isl_map_get_space (pbb
->schedule
)));
136 val
= isl_aff_get_coefficient_val (static_sched
, isl_dim_in
, i
/ 2);
137 gcc_assert (val
&& isl_val_is_int (val
));
139 val
= isl_val_neg (val
);
140 c
= isl_constraint_set_constant_val (c
, val
);
141 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
142 pbb
->schedule
= isl_map_add_constraint (pbb
->schedule
, c
);
145 /* Iterations of this loop. */
146 else /* if ((i % 2) == 1) */
148 int loop
= (i
- 1) / 2;
149 pbb
->schedule
= isl_map_equate (pbb
->schedule
, isl_dim_in
, loop
,
154 pbb
->transformed
= isl_map_copy (pbb
->schedule
);
157 /* Build for BB the static schedule.
159 The static schedule is a Dewey numbering of the abstract syntax
160 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
162 The following example informally defines the static schedule:
181 Static schedules for A to F:
194 build_scop_scattering (scop_p scop
)
196 gimple_poly_bb_p previous_gbb
= NULL
;
197 isl_space
*dc
= isl_set_get_space (scop
->param_context
);
198 isl_aff
*static_sched
;
200 dc
= isl_space_add_dims (dc
, isl_dim_set
, number_of_loops (cfun
));
201 static_sched
= isl_aff_zero_on_domain (isl_local_space_from_space (dc
));
203 /* We have to start schedules at 0 on the first component and
204 because we cannot compare_prefix_loops against a previous loop,
205 prefix will be equal to zero, and that index will be
206 incremented before copying. */
207 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
, 0, -1);
211 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
213 gimple_poly_bb_p gbb
= PBB_BLACK_BOX (pbb
);
217 prefix
= nb_common_loops (scop
->scop_info
->region
, previous_gbb
, gbb
);
221 static_sched
= isl_aff_add_coefficient_si (static_sched
, isl_dim_in
,
223 build_pbb_scattering_polyhedrons (static_sched
, pbb
);
226 isl_aff_free (static_sched
);
229 static isl_pw_aff
*extract_affine (scop_p
, tree
, __isl_take isl_space
*space
);
231 /* Extract an affine expression from the chain of recurrence E. */
234 extract_affine_chrec (scop_p s
, tree e
, __isl_take isl_space
*space
)
236 isl_pw_aff
*lhs
= extract_affine (s
, CHREC_LEFT (e
), isl_space_copy (space
));
237 isl_pw_aff
*rhs
= extract_affine (s
, CHREC_RIGHT (e
), isl_space_copy (space
));
238 isl_local_space
*ls
= isl_local_space_from_space (space
);
239 unsigned pos
= sese_loop_depth (s
->scop_info
->region
, get_chrec_loop (e
)) - 1;
240 isl_aff
*loop
= isl_aff_set_coefficient_si
241 (isl_aff_zero_on_domain (ls
), isl_dim_in
, pos
, 1);
242 isl_pw_aff
*l
= isl_pw_aff_from_aff (loop
);
244 /* Before multiplying, make sure that the result is affine. */
245 gcc_assert (isl_pw_aff_is_cst (rhs
)
246 || isl_pw_aff_is_cst (l
));
248 return isl_pw_aff_add (lhs
, isl_pw_aff_mul (rhs
, l
));
251 /* Extract an affine expression from the mult_expr E. */
254 extract_affine_mul (scop_p s
, tree e
, __isl_take isl_space
*space
)
256 isl_pw_aff
*lhs
= extract_affine (s
, TREE_OPERAND (e
, 0),
257 isl_space_copy (space
));
258 isl_pw_aff
*rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
260 if (!isl_pw_aff_is_cst (lhs
)
261 && !isl_pw_aff_is_cst (rhs
))
263 isl_pw_aff_free (lhs
);
264 isl_pw_aff_free (rhs
);
268 return isl_pw_aff_mul (lhs
, rhs
);
271 /* Return an ISL identifier from the name of the ssa_name E. */
274 isl_id_for_ssa_name (scop_p s
, tree e
)
276 const char *name
= get_name (e
);
280 id
= isl_id_alloc (s
->isl_context
, name
, e
);
284 snprintf (name1
, sizeof (name1
), "P_%d", SSA_NAME_VERSION (e
));
285 id
= isl_id_alloc (s
->isl_context
, name1
, e
);
291 /* Return an ISL identifier for the data reference DR. Data references and
292 scalar references get the same isl_id. They need to be comparable and are
293 distinguished through the first dimension, which contains the alias set or
294 SSA_NAME_VERSION number. */
297 isl_id_for_dr (scop_p s
)
299 return isl_id_alloc (s
->isl_context
, "", 0);
302 /* Extract an affine expression from the ssa_name E. */
305 extract_affine_name (scop_p s
, tree e
, __isl_take isl_space
*space
)
307 isl_id
*id
= isl_id_for_ssa_name (s
, e
);
308 int dimension
= isl_space_find_dim_by_id (space
, isl_dim_param
, id
);
310 isl_set
*dom
= isl_set_universe (isl_space_copy (space
));
311 isl_aff
*aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
312 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, dimension
, 1);
313 return isl_pw_aff_alloc (dom
, aff
);
316 /* Extract an affine expression from the gmp constant G. */
319 extract_affine_gmp (mpz_t g
, __isl_take isl_space
*space
)
321 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
322 isl_aff
*aff
= isl_aff_zero_on_domain (ls
);
323 isl_set
*dom
= isl_set_universe (space
);
324 isl_ctx
*ct
= isl_aff_get_ctx (aff
);
325 isl_val
*v
= isl_val_int_from_gmp (ct
, g
);
326 aff
= isl_aff_add_constant_val (aff
, v
);
328 return isl_pw_aff_alloc (dom
, aff
);
331 /* Extract an affine expression from the integer_cst E. */
334 extract_affine_int (tree e
, __isl_take isl_space
*space
)
339 tree_int_to_gmp (e
, g
);
340 isl_pw_aff
*res
= extract_affine_gmp (g
, space
);
346 /* Compute pwaff mod 2^width. */
349 wrap (isl_pw_aff
*pwaff
, unsigned width
)
353 mod
= isl_val_int_from_ui (isl_pw_aff_get_ctx (pwaff
), width
);
354 mod
= isl_val_2exp (mod
);
355 pwaff
= isl_pw_aff_mod_val (pwaff
, mod
);
360 /* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
361 Otherwise returns -1. */
364 parameter_index_in_region_1 (tree name
, sese_info_p region
)
369 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
371 FOR_EACH_VEC_ELT (region
->params
, i
, p
)
378 /* Extract an affine expression from the tree E in the scop S. */
381 extract_affine (scop_p s
, tree e
, __isl_take isl_space
*space
)
383 isl_pw_aff
*lhs
, *rhs
, *res
;
385 if (e
== chrec_dont_know
) {
386 isl_space_free (space
);
390 switch (TREE_CODE (e
))
392 case POLYNOMIAL_CHREC
:
393 res
= extract_affine_chrec (s
, e
, space
);
397 res
= extract_affine_mul (s
, e
, space
);
401 case POINTER_PLUS_EXPR
:
402 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
403 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
404 res
= isl_pw_aff_add (lhs
, rhs
);
408 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
409 rhs
= extract_affine (s
, TREE_OPERAND (e
, 1), space
);
410 res
= isl_pw_aff_sub (lhs
, rhs
);
415 lhs
= extract_affine (s
, TREE_OPERAND (e
, 0), isl_space_copy (space
));
416 rhs
= extract_affine (s
, integer_minus_one_node
, space
);
417 res
= isl_pw_aff_mul (lhs
, rhs
);
421 gcc_assert (-1 != parameter_index_in_region_1 (e
, s
->scop_info
)
422 || !invariant_in_sese_p_rec (e
, s
->scop_info
->region
, NULL
));
423 res
= extract_affine_name (s
, e
, space
);
427 res
= extract_affine_int (e
, space
);
428 /* No need to wrap a single integer. */
432 case NON_LVALUE_EXPR
:
433 res
= extract_affine (s
, TREE_OPERAND (e
, 0), space
);
441 tree type
= TREE_TYPE (e
);
442 if (TYPE_UNSIGNED (type
))
443 res
= wrap (res
, TYPE_PRECISION (type
));
448 /* Assign dimension for each parameter in SCOP. */
451 set_scop_parameter_dim (scop_p scop
)
453 sese_info_p region
= scop
->scop_info
;
454 unsigned nbp
= sese_nb_params (region
);
455 isl_space
*space
= isl_space_set_alloc (scop
->isl_context
, nbp
, 0);
459 FOR_EACH_VEC_ELT (region
->params
, i
, e
)
460 space
= isl_space_set_dim_id (space
, isl_dim_param
, i
,
461 isl_id_for_ssa_name (scop
, e
));
463 scop
->param_context
= isl_set_universe (space
);
467 cleanup_loop_iter_dom (isl_set
*inner
, isl_set
*outer
, isl_space
*space
, mpz_t g
)
469 isl_set_free (inner
);
470 isl_set_free (outer
);
471 isl_space_free (space
);
476 /* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
477 the constraints for the surrounding loops. */
480 build_loop_iteration_domains (scop_p scop
, struct loop
*loop
,
482 isl_set
*outer
, isl_set
**doms
)
485 tree nb_iters
= number_of_latch_executions (loop
);
486 sese_l region
= scop
->scop_info
->region
;
487 gcc_assert (loop_in_sese_p (loop
, region
));
489 isl_set
*inner
= isl_set_copy (outer
);
490 int pos
= isl_set_dim (outer
, isl_dim_set
);
496 inner
= isl_set_add_dims (inner
, isl_dim_set
, 1);
497 isl_space
*space
= isl_set_get_space (inner
);
500 isl_constraint
*c
= isl_inequality_alloc
501 (isl_local_space_from_space (isl_space_copy (space
)));
502 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, 1);
503 inner
= isl_set_add_constraint (inner
, c
);
505 /* loop_i <= cst_nb_iters */
506 if (TREE_CODE (nb_iters
) == INTEGER_CST
)
508 c
= isl_inequality_alloc
509 (isl_local_space_from_space (isl_space_copy (space
)));
510 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
511 tree_int_to_gmp (nb_iters
, g
);
512 v
= isl_val_int_from_gmp (scop
->isl_context
, g
);
513 c
= isl_constraint_set_constant_val (c
, v
);
514 inner
= isl_set_add_constraint (inner
, c
);
517 /* loop_i <= expr_nb_iters */
518 else if (!chrec_contains_undetermined (nb_iters
))
522 nb_iters
= scalar_evolution_in_region (region
, loop
, nb_iters
);
524 /* Bail out as we do not know the scev. */
525 if (chrec_contains_undetermined (nb_iters
))
526 return cleanup_loop_iter_dom (inner
, outer
, space
, g
);
528 aff
= extract_affine (scop
, nb_iters
, isl_set_get_space (inner
));
529 isl_set
*valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff
));
530 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
531 isl_set_dim (valid
, isl_dim_set
));
534 scop
->param_context
= isl_set_intersect (scop
->param_context
, valid
);
536 isl_local_space
*ls
= isl_local_space_from_space (isl_space_copy (space
));
537 isl_aff
*al
= isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls
),
539 isl_set
*le
= isl_pw_aff_le_set (isl_pw_aff_from_aff (al
),
540 isl_pw_aff_copy (aff
));
541 inner
= isl_set_intersect (inner
, le
);
544 if (max_stmt_executions (loop
, &nit
))
546 /* Insert in the context the constraints from the
547 estimation of the number of iterations NIT and the
548 symbolic number of iterations (involving parameter
549 names) NB_ITERS. First, build the affine expression
550 "NIT - NB_ITERS" and then say that it is positive,
551 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
554 wi::to_mpz (nit
, g
, SIGNED
);
555 mpz_sub_ui (g
, g
, 1);
558 = extract_affine_gmp (g
, isl_set_get_space (inner
));
559 isl_set
*x
= isl_pw_aff_ge_set (approx
, aff
);
560 x
= isl_set_project_out (x
, isl_dim_set
, 0,
561 isl_set_dim (x
, isl_dim_set
));
562 scop
->param_context
= isl_set_intersect (scop
->param_context
, x
);
564 isl_constraint
*c
= isl_inequality_alloc
565 (isl_local_space_from_space (isl_space_copy (space
)));
566 c
= isl_constraint_set_coefficient_si (c
, isl_dim_set
, pos
, -1);
567 v
= isl_val_int_from_gmp (scop
->isl_context
, g
);
569 c
= isl_constraint_set_constant_val (c
, v
);
570 inner
= isl_set_add_constraint (inner
, c
);
573 isl_pw_aff_free (aff
);
579 && !build_loop_iteration_domains (scop
, loop
->inner
, nb
+ 1,
580 isl_set_copy (inner
), doms
))
581 return cleanup_loop_iter_dom (inner
, outer
, space
, g
);
585 && loop_in_sese_p (loop
->next
, region
)
586 && !build_loop_iteration_domains (scop
, loop
->next
, nb
,
587 isl_set_copy (outer
), doms
))
588 return cleanup_loop_iter_dom (inner
, outer
, space
, g
);
590 doms
[loop
->num
] = inner
;
592 isl_set_free (outer
);
593 isl_space_free (space
);
598 /* Returns a linear expression for tree T evaluated in PBB. */
601 create_pw_aff_from_tree (poly_bb_p pbb
, tree t
)
603 scop_p scop
= PBB_SCOP (pbb
);
605 t
= scalar_evolution_in_region (scop
->scop_info
->region
, pbb_loop (pbb
), t
);
607 /* Bail out as we do not know the scev. */
608 if (chrec_contains_undetermined (t
))
611 gcc_assert (!automatically_generated_chrec_p (t
));
613 return extract_affine (scop
, t
, isl_set_get_space (pbb
->domain
));
616 /* Add conditional statement STMT to pbb. CODE is used as the comparison
617 operator. This allows us to invert the condition or to handle
621 add_condition_to_pbb (poly_bb_p pbb
, gcond
*stmt
, enum tree_code code
)
623 isl_pw_aff
*lhs
= create_pw_aff_from_tree (pbb
, gimple_cond_lhs (stmt
));
627 isl_pw_aff
*rhs
= create_pw_aff_from_tree (pbb
, gimple_cond_rhs (stmt
));
630 isl_pw_aff_free (lhs
);
638 cond
= isl_pw_aff_lt_set (lhs
, rhs
);
642 cond
= isl_pw_aff_gt_set (lhs
, rhs
);
646 cond
= isl_pw_aff_le_set (lhs
, rhs
);
650 cond
= isl_pw_aff_ge_set (lhs
, rhs
);
654 cond
= isl_pw_aff_eq_set (lhs
, rhs
);
658 cond
= isl_pw_aff_ne_set (lhs
, rhs
);
662 isl_pw_aff_free (lhs
);
663 isl_pw_aff_free (rhs
);
667 cond
= isl_set_coalesce (cond
);
668 cond
= isl_set_set_tuple_id (cond
, isl_set_get_tuple_id (pbb
->domain
));
669 pbb
->domain
= isl_set_intersect (pbb
->domain
, cond
);
673 /* Add conditions to the domain of PBB. */
676 add_conditions_to_domain (poly_bb_p pbb
)
680 gimple_poly_bb_p gbb
= PBB_BLACK_BOX (pbb
);
682 if (GBB_CONDITIONS (gbb
).is_empty ())
685 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb
), i
, stmt
)
686 switch (gimple_code (stmt
))
690 /* Don't constrain on anything else than INTEGER_TYPE. */
691 if (TREE_CODE (TREE_TYPE (gimple_cond_lhs (stmt
))) != INTEGER_TYPE
)
694 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
695 enum tree_code code
= gimple_cond_code (cond_stmt
);
697 /* The conditions for ELSE-branches are inverted. */
698 if (!GBB_CONDITION_CASES (gbb
)[i
])
699 code
= invert_tree_comparison (code
, false);
701 if (!add_condition_to_pbb (pbb
, cond_stmt
, code
))
707 /* Switch statements are not supported right now - fall through. */
717 /* Traverses all the GBBs of the SCOP and add their constraints to the
718 iteration domains. */
721 add_conditions_to_constraints (scop_p scop
)
726 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
727 if (!add_conditions_to_domain (pbb
))
733 /* Add constraints on the possible values of parameter P from the type
737 add_param_constraints (scop_p scop
, graphite_dim_t p
)
739 tree parameter
= scop
->scop_info
->params
[p
];
740 tree type
= TREE_TYPE (parameter
);
744 if (POINTER_TYPE_P (type
) || !TYPE_MIN_VALUE (type
))
745 lb
= lower_bound_in_type (type
, type
);
747 lb
= TYPE_MIN_VALUE (type
);
749 if (POINTER_TYPE_P (type
) || !TYPE_MAX_VALUE (type
))
750 ub
= upper_bound_in_type (type
, type
);
752 ub
= TYPE_MAX_VALUE (type
);
756 isl_space
*space
= isl_set_get_space (scop
->param_context
);
761 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
763 tree_int_to_gmp (lb
, g
);
764 v
= isl_val_int_from_gmp (scop
->isl_context
, g
);
767 c
= isl_constraint_set_constant_val (c
, v
);
768 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, 1);
770 scop
->param_context
= isl_set_add_constraint (scop
->param_context
, c
);
775 isl_space
*space
= isl_set_get_space (scop
->param_context
);
780 c
= isl_inequality_alloc (isl_local_space_from_space (space
));
783 tree_int_to_gmp (ub
, g
);
784 v
= isl_val_int_from_gmp (scop
->isl_context
, g
);
786 c
= isl_constraint_set_constant_val (c
, v
);
787 c
= isl_constraint_set_coefficient_si (c
, isl_dim_param
, p
, -1);
789 scop
->param_context
= isl_set_add_constraint (scop
->param_context
, c
);
793 /* Build the context of the SCOP. The context usually contains extra
794 constraints that are added to the iteration domains that constrain
798 build_scop_context (scop_p scop
)
800 graphite_dim_t p
, n
= scop_nb_params (scop
);
802 for (p
= 0; p
< n
; p
++)
803 add_param_constraints (scop
, p
);
806 /* Build the iteration domains: the loops belonging to the current
807 SCOP, and that vary for the execution of the current basic block.
808 Returns false if there is no loop in SCOP. */
811 build_scop_iteration_domain (scop_p scop
)
813 sese_info_p region
= scop
->scop_info
;
814 int nb_loops
= number_of_loops (cfun
);
815 isl_set
**doms
= XCNEWVEC (isl_set
*, nb_loops
);
819 FOR_EACH_VEC_ELT (region
->loop_nest
, i
, loop
)
820 if (!loop_in_sese_p (loop_outer (loop
), region
->region
)
821 && !build_loop_iteration_domains (scop
, loop
, 0,
822 isl_set_copy (scop
->param_context
), doms
))
829 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
831 loop
= pbb_loop (pbb
);
834 pbb
->domain
= isl_set_copy (doms
[loop
->num
]);
836 pbb
->domain
= isl_set_copy (scop
->param_context
);
838 pbb
->domain
= isl_set_set_tuple_id (pbb
->domain
,
839 isl_id_for_pbb (scop
, pbb
));
843 for (int i
= 0; i
< nb_loops
; i
++)
845 isl_set_free (doms
[i
]);
851 /* Add a constrain to the ACCESSES polyhedron for the alias set of
852 data reference DR. ACCESSP_NB_DIMS is the dimension of the
853 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
857 pdr_add_alias_set (isl_map
*acc
, dr_info
&dri
)
859 isl_constraint
*c
= isl_equality_alloc
860 (isl_local_space_from_space (isl_map_get_space (acc
)));
861 /* Positive numbers for all alias sets. */
862 c
= isl_constraint_set_constant_si (c
, -dri
.alias_set
);
863 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
865 return isl_map_add_constraint (acc
, c
);
868 /* Add a constrain to the ACCESSES polyhedron for the alias set of
869 data reference DR. ACCESSP_NB_DIMS is the dimension of the
870 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
874 add_scalar_version_numbers (isl_map
*acc
, tree var
)
876 isl_constraint
*c
= isl_equality_alloc
877 (isl_local_space_from_space (isl_map_get_space (acc
)));
878 int max_arrays
= PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP
);
879 /* Each scalar variables has a unique alias set number starting from
881 c
= isl_constraint_set_constant_si (c
, -max_arrays
- SSA_NAME_VERSION (var
));
882 c
= isl_constraint_set_coefficient_si (c
, isl_dim_out
, 0, 1);
884 return isl_map_add_constraint (acc
, c
);
887 /* Assign the affine expression INDEX to the output dimension POS of
888 MAP and return the result. */
891 set_index (isl_map
*map
, int pos
, isl_pw_aff
*index
)
894 int len
= isl_map_dim (map
, isl_dim_out
);
897 index_map
= isl_map_from_pw_aff (index
);
898 index_map
= isl_map_insert_dims (index_map
, isl_dim_out
, 0, pos
);
899 index_map
= isl_map_add_dims (index_map
, isl_dim_out
, len
- pos
- 1);
901 id
= isl_map_get_tuple_id (map
, isl_dim_out
);
902 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_out
, id
);
903 id
= isl_map_get_tuple_id (map
, isl_dim_in
);
904 index_map
= isl_map_set_tuple_id (index_map
, isl_dim_in
, id
);
906 return isl_map_intersect (map
, index_map
);
909 /* Add to ACCESSES polyhedron equalities defining the access functions
910 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
911 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
912 PBB is the poly_bb_p that contains the data reference DR. */
915 pdr_add_memory_accesses (isl_map
*acc
, dr_info
&dri
)
917 data_reference_p dr
= dri
.dr
;
918 poly_bb_p pbb
= dri
.pbb
;
919 int i
, nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
920 scop_p scop
= PBB_SCOP (pbb
);
922 for (i
= 0; i
< nb_subscripts
; i
++)
925 tree afn
= DR_ACCESS_FN (dr
, nb_subscripts
- 1 - i
);
927 aff
= extract_affine (scop
, afn
,
928 isl_space_domain (isl_map_get_space (acc
)));
929 acc
= set_index (acc
, i
+ 1, aff
);
935 /* Add constrains representing the size of the accessed data to the
936 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
937 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
941 pdr_add_data_dimensions (isl_set
*subscript_sizes
, scop_p scop
,
944 tree ref
= DR_REF (dr
);
946 int nb_subscripts
= DR_NUM_DIMENSIONS (dr
);
947 for (int i
= nb_subscripts
- 1; i
>= 0; i
--, ref
= TREE_OPERAND (ref
, 0))
949 if (TREE_CODE (ref
) != ARRAY_REF
)
950 return subscript_sizes
;
952 tree low
= array_ref_low_bound (ref
);
953 tree high
= array_ref_up_bound (ref
);
955 /* XXX The PPL code dealt separately with
956 subscript - low >= 0 and high - subscript >= 0 in case one of
957 the two bounds isn't known. Do the same here? */
959 if (tree_fits_shwi_p (low
)
961 && tree_fits_shwi_p (high
)
962 /* 1-element arrays at end of structures may extend over
963 their declared size. */
964 && !(array_at_struct_end_p (ref
)
965 && operand_equal_p (low
, high
, 0)))
969 isl_set
*univ
, *lbs
, *ubs
;
972 isl_space
*space
= isl_set_get_space (subscript_sizes
);
973 isl_pw_aff
*lb
= extract_affine_int (low
, isl_space_copy (space
));
974 isl_pw_aff
*ub
= extract_affine_int (high
, isl_space_copy (space
));
977 valid
= isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub
));
978 valid
= isl_set_project_out (valid
, isl_dim_set
, 0,
979 isl_set_dim (valid
, isl_dim_set
));
980 scop
->param_context
= isl_set_intersect (scop
->param_context
, valid
);
982 aff
= isl_aff_zero_on_domain (isl_local_space_from_space (space
));
983 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_in
, i
+ 1, 1);
984 univ
= isl_set_universe (isl_space_domain (isl_aff_get_space (aff
)));
985 index
= isl_pw_aff_alloc (univ
, aff
);
987 id
= isl_set_get_tuple_id (subscript_sizes
);
988 lb
= isl_pw_aff_set_tuple_id (lb
, isl_dim_in
, isl_id_copy (id
));
989 ub
= isl_pw_aff_set_tuple_id (ub
, isl_dim_in
, id
);
991 /* low <= sub_i <= high */
992 lbs
= isl_pw_aff_ge_set (isl_pw_aff_copy (index
), lb
);
993 ubs
= isl_pw_aff_le_set (index
, ub
);
994 subscript_sizes
= isl_set_intersect (subscript_sizes
, lbs
);
995 subscript_sizes
= isl_set_intersect (subscript_sizes
, ubs
);
999 return subscript_sizes
;
1002 /* Build data accesses for DRI. */
1005 build_poly_dr (dr_info
&dri
)
1008 isl_set
*subscript_sizes
;
1009 poly_bb_p pbb
= dri
.pbb
;
1010 data_reference_p dr
= dri
.dr
;
1011 scop_p scop
= PBB_SCOP (pbb
);
1012 isl_id
*id
= isl_id_for_dr (scop
);
1015 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1016 int nb_out
= 1 + DR_NUM_DIMENSIONS (dr
);
1017 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1018 isl_dim_out
, nb_out
);
1020 acc
= isl_map_universe (space
);
1021 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, isl_id_copy (id
));
1024 acc
= pdr_add_alias_set (acc
, dri
);
1025 acc
= pdr_add_memory_accesses (acc
, dri
);
1028 int nb
= 1 + DR_NUM_DIMENSIONS (dr
);
1029 isl_space
*space
= isl_space_set_alloc (scop
->isl_context
, 0, nb
);
1031 space
= isl_space_set_tuple_id (space
, isl_dim_set
, id
);
1032 subscript_sizes
= isl_set_nat_universe (space
);
1033 subscript_sizes
= isl_set_fix_si (subscript_sizes
, isl_dim_set
, 0,
1035 subscript_sizes
= pdr_add_data_dimensions (subscript_sizes
, scop
, dr
);
1038 new_poly_dr (pbb
, DR_STMT (dr
), DR_IS_READ (dr
) ? PDR_READ
: PDR_WRITE
,
1039 acc
, subscript_sizes
);
1043 build_poly_sr_1 (poly_bb_p pbb
, gimple
*stmt
, tree var
, enum poly_dr_type kind
,
1044 isl_map
*acc
, isl_set
*subscript_sizes
)
1046 int max_arrays
= PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP
);
1047 /* Each scalar variables has a unique alias set number starting from
1049 subscript_sizes
= isl_set_fix_si (subscript_sizes
, isl_dim_set
, 0,
1050 max_arrays
+ SSA_NAME_VERSION (var
));
1052 new_poly_dr (pbb
, stmt
, kind
, add_scalar_version_numbers (acc
, var
),
1056 /* Record all cross basic block scalar variables in PBB. */
1059 build_poly_sr (poly_bb_p pbb
)
1061 scop_p scop
= PBB_SCOP (pbb
);
1062 gimple_poly_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1063 vec
<scalar_use
> reads
= gbb
->read_scalar_refs
;
1064 vec
<tree
> writes
= gbb
->write_scalar_refs
;
1066 isl_space
*dc
= isl_set_get_space (pbb
->domain
);
1068 isl_space
*space
= isl_space_add_dims (isl_space_from_domain (dc
),
1069 isl_dim_out
, nb_out
);
1070 isl_id
*id
= isl_id_for_dr (scop
);
1071 space
= isl_space_set_tuple_id (space
, isl_dim_set
, isl_id_copy (id
));
1072 isl_map
*acc
= isl_map_universe (isl_space_copy (space
));
1073 acc
= isl_map_set_tuple_id (acc
, isl_dim_out
, id
);
1074 isl_set
*subscript_sizes
= isl_set_nat_universe (space
);
1078 FOR_EACH_VEC_ELT (writes
, i
, var
)
1079 build_poly_sr_1 (pbb
, SSA_NAME_DEF_STMT (var
), var
, PDR_WRITE
,
1080 isl_map_copy (acc
), isl_set_copy (subscript_sizes
));
1083 FOR_EACH_VEC_ELT (reads
, i
, use
)
1084 build_poly_sr_1 (pbb
, use
->first
, use
->second
, PDR_READ
, isl_map_copy (acc
),
1085 isl_set_copy (subscript_sizes
));
1088 isl_set_free (subscript_sizes
);
1091 /* Build data references in SCOP. */
1094 build_scop_drs (scop_p scop
)
1098 FOR_EACH_VEC_ELT (scop
->drs
, i
, dri
)
1099 build_poly_dr (*dri
);
1102 FOR_EACH_VEC_ELT (scop
->pbbs
, i
, pbb
)
1103 build_poly_sr (pbb
);
1106 /* Builds the polyhedral representation for a SESE region. */
1109 build_poly_scop (scop_p scop
)
1111 set_scop_parameter_dim (scop
);
1112 if (!build_scop_iteration_domain (scop
))
1115 build_scop_context (scop
);
1117 if (!add_conditions_to_constraints (scop
))
1120 build_scop_drs (scop
);
1121 build_scop_scattering (scop
);
1124 #endif /* HAVE_isl */