/* Conversion of SESE regions to Polyhedra.
- Copyright (C) 2009-2017 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
Contributed by Sebastian Pop <sebastian.pop@amd.com>.
This file is part of GCC.
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
-#include "params.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "graphite.h"
-/* Assigns to RES the value of the INTEGER_CST T. */
-
-static inline void
-tree_int_to_gmp (tree t, mpz_t res)
-{
- wi::to_mpz (wi::to_wide (t), res, TYPE_SIGN (TREE_TYPE (t)));
-}
-
/* Return an isl identifier for the polyhedral basic block PBB. */
static isl_id *
isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
isl_local_space *ls = isl_local_space_from_space (space);
- unsigned pos = sese_loop_depth (s->scop_info->region, get_chrec_loop (e));
+ unsigned pos = sese_loop_depth (s->scop_info->region, get_chrec_loop (e)) - 1;
isl_aff *loop = isl_aff_set_coefficient_si
(isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
isl_pw_aff *l = isl_pw_aff_from_aff (loop);
/* Extract an affine expression from the ssa_name E. */
static isl_pw_aff *
-extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
+extract_affine_name (int dimension, __isl_take isl_space *space)
{
- isl_id *id = isl_id_for_ssa_name (s, e);
- int dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
- isl_id_free (id);
isl_set *dom = isl_set_universe (isl_space_copy (space));
isl_aff *aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
Otherwise returns -1. */
static inline int
-parameter_index_in_region_1 (tree name, sese_info_p region)
+parameter_index_in_region (tree name, sese_info_p region)
{
int i;
tree p;
-
- gcc_assert (TREE_CODE (name) == SSA_NAME);
-
FOR_EACH_VEC_ELT (region->params, i, p)
if (p == name)
return i;
-
return -1;
}
lhs = extract_affine (s, integer_minus_one_node, isl_space_copy (space));
rhs = extract_affine (s, TREE_OPERAND (e, 0), space);
res = isl_pw_aff_sub (lhs, rhs);
- break;
+ /* We need to always wrap the result of a bitwise operation. */
+ return wrap (res, TYPE_PRECISION (type) - (TYPE_UNSIGNED (type) ? 0 : 1));
case NEGATE_EXPR:
lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
break;
case SSA_NAME:
- gcc_assert (-1 != parameter_index_in_region_1 (e, s->scop_info)
- || defined_in_sese_p (e, s->scop_info->region));
- res = extract_affine_name (s, e, space);
- break;
+ {
+ gcc_assert (! defined_in_sese_p (e, s->scop_info->region));
+ int dim = parameter_index_in_region (e, s->scop_info);
+ gcc_assert (dim != -1);
+ /* No need to wrap a parameter. */
+ return extract_affine_name (dim, space);
+ }
case INTEGER_CST:
res = extract_affine_int (e, space);
/* Signed values, even if overflow is undefined, get modulo-reduced.
But only if not all values of the old type fit in the new. */
if (! TYPE_UNSIGNED (type)
- && ((TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (e, 0)))
+ && ((TYPE_UNSIGNED (itype)
&& TYPE_PRECISION (type) <= TYPE_PRECISION (itype))
|| TYPE_PRECISION (type) < TYPE_PRECISION (itype)))
res = wrap (res, TYPE_PRECISION (type) - 1);
- break;
+ else if (TYPE_UNSIGNED (type)
+ && (!TYPE_UNSIGNED (itype)
+ || TYPE_PRECISION (type) < TYPE_PRECISION (itype)))
+ res = wrap (res, TYPE_PRECISION (type));
+ return res;
}
case NON_LVALUE_EXPR:
break;
}
- if (TYPE_UNSIGNED (type))
+ /* For all wrapping arithmetic wrap the result. */
+ if (TYPE_OVERFLOW_WRAPS (type))
res = wrap (res, TYPE_PRECISION (type));
return res;
{
scop_p scop = PBB_SCOP (pbb);
- t = scalar_evolution_in_region (scop->scop_info->region, loop, t);
+ t = cached_scalar_evolution_in_region (scop->scop_info->region, loop, t);
gcc_assert (!chrec_contains_undetermined (t));
gcc_assert (!automatically_generated_chrec_p (t));
of P. */
static void
-add_param_constraints (scop_p scop, graphite_dim_t p)
+add_param_constraints (scop_p scop, graphite_dim_t p, tree parameter)
{
- tree parameter = scop->scop_info->params[p];
tree type = TREE_TYPE (parameter);
- tree lb = NULL_TREE;
- tree ub = NULL_TREE;
+ wide_int min, max;
- if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
- lb = lower_bound_in_type (type, type);
- else
- lb = TYPE_MIN_VALUE (type);
+ gcc_assert (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type));
- if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
- ub = upper_bound_in_type (type, type);
+ if (INTEGRAL_TYPE_P (type)
+ && get_range_info (parameter, &min, &max) == VR_RANGE)
+ ;
else
- ub = TYPE_MAX_VALUE (type);
-
- if (lb)
{
- isl_space *space = isl_set_get_space (scop->param_context);
- isl_constraint *c;
- isl_val *v;
-
- c = isl_inequality_alloc (isl_local_space_from_space (space));
- v = isl_val_int_from_wi (scop->isl_context, wi::to_widest (lb));
- v = isl_val_neg (v);
- c = isl_constraint_set_constant_val (c, v);
- c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
-
- scop->param_context = isl_set_coalesce
- (isl_set_add_constraint (scop->param_context, c));
+ min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
+ max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
}
- if (ub)
- {
- isl_space *space = isl_set_get_space (scop->param_context);
- isl_constraint *c;
- isl_val *v;
-
- c = isl_inequality_alloc (isl_local_space_from_space (space));
-
- v = isl_val_int_from_wi (scop->isl_context, wi::to_widest (ub));
- c = isl_constraint_set_constant_val (c, v);
- c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
-
- scop->param_context = isl_set_coalesce
- (isl_set_add_constraint (scop->param_context, c));
- }
+ isl_space *space = isl_set_get_space (scop->param_context);
+ isl_constraint *c = isl_inequality_alloc (isl_local_space_from_space (space));
+ isl_val *v = isl_val_int_from_wi (scop->isl_context,
+ widest_int::from (min, TYPE_SIGN (type)));
+ v = isl_val_neg (v);
+ c = isl_constraint_set_constant_val (c, v);
+ c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
+ scop->param_context = isl_set_coalesce
+ (isl_set_add_constraint (scop->param_context, c));
+
+ space = isl_set_get_space (scop->param_context);
+ c = isl_inequality_alloc (isl_local_space_from_space (space));
+ v = isl_val_int_from_wi (scop->isl_context,
+ widest_int::from (max, TYPE_SIGN (type)));
+ c = isl_constraint_set_constant_val (c, v);
+ c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
+ scop->param_context = isl_set_coalesce
+ (isl_set_add_constraint (scop->param_context, c));
}
/* Add a constrain to the ACCESSES polyhedron for the alias set of
return domain;
const sese_l ®ion = scop->scop_info->region;
if (!loop_in_sese_p (loop, region))
- ;
- else
- /* Recursion all the way up to the context loop. */
- domain = add_loop_constraints (scop, domain, loop_outer (loop), context);
+ return domain;
+
+ /* Recursion all the way up to the context loop. */
+ domain = add_loop_constraints (scop, domain, loop_outer (loop), context);
/* Then, build constraints over the loop in post-order: outer to inner. */
domain = add_iter_domain_dimension (domain, loop, scop);
isl_space *space = isl_set_get_space (domain);
- if (!loop_in_sese_p (loop, region))
- {
- /* 0 == loop_i */
- isl_local_space *ls = isl_local_space_from_space (space);
- isl_constraint *c = isl_equality_alloc (ls);
- c = isl_constraint_set_coefficient_si (c, isl_dim_set, loop_index, 1);
- if (dump_file)
- {
- fprintf (dump_file, "[sese-to-poly] adding constraint to the domain: ");
- print_isl_constraint (dump_file, c);
- }
- domain = isl_set_add_constraint (domain, c);
- return domain;
- }
-
/* 0 <= loop_i */
isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
isl_constraint *c = isl_inequality_alloc (ls);
}
/* loop_i <= expr_nb_iters */
gcc_assert (!chrec_contains_undetermined (nb_iters));
- nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
+ nb_iters = cached_scalar_evolution_in_region (region, loop, nb_iters);
gcc_assert (!chrec_contains_undetermined (nb_iters));
isl_pw_aff *aff_nb_iters = extract_affine (scop, nb_iters,
scop->param_context = isl_set_universe (space);
- graphite_dim_t p;
- for (p = 0; p < nbp; p++)
- add_param_constraints (scop, p);
+ FOR_EACH_VEC_ELT (region->params, i, e)
+ add_param_constraints (scop, i, e);
}
/* Return true when loop A is nested in loop B. */
/* Build the schedule of the SCOP. */
-static bool
+static void
build_original_schedule (scop_p scop)
{
int i = 0;
fprintf (dump_file, "[sese-to-poly] original schedule:\n");
print_isl_schedule (dump_file, scop->original_schedule);
}
- if (!scop->original_schedule)
- return false;
- return true;
}
/* Builds the polyhedral representation for a SESE region. */
enum isl_error err = isl_ctx_last_error (scop->isl_context);
isl_ctx_reset_error (scop->isl_context);
isl_options_set_on_error (scop->isl_context, old_err);
- if (err != isl_error_none)
+ if (err != isl_error_none
+ && dump_enabled_p ())
dump_printf (MSG_MISSED_OPTIMIZATION,
"ISL error while building poly scop\n");