]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/graphite-sese-to-poly.c
[Ada] Avoid "others => <>" association in resolved record aggregates
[thirdparty/gcc.git] / gcc / graphite-sese-to-poly.c
index 50b6fe8dbb29c570931e82ef8268448e54b088df..c42415e0554fb132c01662b580ea57618ac90c5c 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "gimple.h"
 #include "ssa.h"
-#include "params.h"
 #include "fold-const.h"
 #include "gimple-iterator.h"
 #include "gimplify.h"
@@ -58,14 +57,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #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 *
@@ -86,7 +77,7 @@ extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
   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);
@@ -142,11 +133,8 @@ isl_id_for_dr (scop_p s)
 /* 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);
@@ -211,17 +199,13 @@ wrap (isl_pw_aff *pwaff, unsigned width)
    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;
 }
 
@@ -279,7 +263,8 @@ extract_affine (scop_p s, tree e, __isl_take isl_space *space)
       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));
@@ -288,10 +273,13 @@ extract_affine (scop_p s, tree e, __isl_take isl_space *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);
@@ -305,11 +293,15 @@ extract_affine (scop_p s, tree e, __isl_take isl_space *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:
@@ -321,7 +313,8 @@ extract_affine (scop_p s, tree e, __isl_take isl_space *space)
       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;
@@ -334,7 +327,7 @@ create_pw_aff_from_tree (poly_bb_p pbb, loop_p loop, tree t)
 {
   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));
@@ -431,54 +424,40 @@ add_conditions_to_domain (poly_bb_p pbb)
    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
@@ -763,10 +742,10 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
     return domain;
   const sese_l &region = 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.  */
 
@@ -777,21 +756,6 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
   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);
@@ -817,7 +781,7 @@ add_loop_constraints (scop_p scop, __isl_take isl_set *domain, loop_p loop,
     }
   /* 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,
@@ -945,9 +909,8 @@ build_scop_context (scop_p scop)
 
   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.  */
@@ -1209,7 +1172,7 @@ build_schedule_loop_nest (scop_p scop, int *index, loop_p context_loop)
 
 /* Build the schedule of the SCOP.  */
 
-static bool
+static void
 build_original_schedule (scop_p scop)
 {
   int i = 0;
@@ -1231,9 +1194,6 @@ build_original_schedule (scop_p scop)
       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.  */
@@ -1257,7 +1217,8 @@ build_poly_scop (scop_p scop)
   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");