]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Cleanups to bring branch more in line with trunk.
authorAldy Hernandez <aldyh@gcc.gnu.org>
Tue, 27 Aug 2019 14:43:22 +0000 (14:43 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Tue, 27 Aug 2019 14:43:22 +0000 (14:43 +0000)
From-SVN: r274957

gcc/coretypes.h
gcc/gimple-ssa-warn-restrict.c
gcc/range-op.cc
gcc/ssa-range.cc
gcc/ssa.h
gcc/tree-vrp.c
gcc/tree-vrp.h
gcc/vr-values.c
gcc/vr-values.h
gcc/wide-int-range.cc
gcc/wide-int-range.h

index 7f866333e1e859dc845949b760c9e6647a95dda3..eac2f3931aa83d1cc25ce66892939f0634c45eb8 100644 (file)
@@ -202,24 +202,6 @@ enum profile_update {
   PROFILE_UPDATE_PREFER_ATOMIC
 };
 
-/* Types of ranges.
-
-   This is still prefixed with VR_*, even though it is more general
-   purpose, to avoid having to replace everything across the compiler.
-   Perhaps we should change it later.  */
-enum value_range_kind {
-  /* Empty range.  */
-  VR_UNDEFINED,
-  /* Range spans the entire domain.  */
-  VR_VARYING,
-  /* Range is [MIN, MAX].  */
-  VR_RANGE,
-  /* Range is ~[MIN, MAX].  */
-  VR_ANTI_RANGE,
-  /* Range is a nice guy.  */
-  VR_LAST
-};
-
 /* Types of unwind/exception handling info that can be generated.  */
 
 enum unwind_info_type
index c799b0f2a26e4e6fd36efe083ec66fd9c682f76d..95b4bd51132a025e0723571a8379c10ff15650b8 100644 (file)
@@ -302,7 +302,7 @@ ranger_get_range_info (gimple *stmt, tree ssa, wide_int *min, wide_int *max)
   if (r.undefined_p ())
     return VR_UNDEFINED;
 
-  value_range_base vr = r;
+  value_range_base vr = irange_to_value_range (r);
   *min = wi::to_wide (vr.min ());
   *max = wi::to_wide (vr.max ());
   return vr.kind ();
index c2ffbcc42b83e5b2d4fa0ee02dcb0d47355782b2..6b27fb242a9e0ccefb149a10ea1f28d008d6ec12 100644 (file)
@@ -3416,7 +3416,7 @@ range_tests ()
 #undef value_range_base
   {
     irange r0 = irange (VR_ANTI_RANGE, INT (10), INT (20));
-    value_range_base vr = r0;
+    value_range_base vr = irange_to_value_range (r0);
     ASSERT_TRUE (vr.kind () == VR_ANTI_RANGE);
     ASSERT_TRUE (wi::eq_p (10, wi::to_wide (vr.min ()))
                 && wi::eq_p (20, wi::to_wide (vr.max ())));
index ad9797bcdb73f8e9286e2e63f1fa9be697ea1e87..189c054f868ca3e7adc5ee0dd0f7b9c21b974e4b 100644 (file)
@@ -971,7 +971,7 @@ global_ranger::export_global_ranges ()
              if (!dbg_cnt (ranger_export_count))
                return;
 
-             value_range_base vr = r;
+             value_range_base vr = irange_to_value_range (r);
              set_range_info (name, vr);
              if (dump_file)
                {
@@ -1139,7 +1139,7 @@ loop_ranger::adjust_phi_with_loop_info (irange &r, gphi *phi)
   if (l && l->header == gimple_bb (phi))
     {
       tree phi_result = PHI_RESULT (phi);
-      value_range_base vr = r;
+      value_range_base vr = irange_to_value_range (r);
       m_vr_values->adjust_range_with_scev (&vr, l, phi, phi_result);
       if (vr.constant_p ())
        {
index 74dcc732cd2034adf91dd0eeaf5368852de6488a..2fe4addedf2a90759a486d914e8be0f9a6990322 100644 (file)
--- a/gcc/ssa.h
+++ b/gcc/ssa.h
@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "stringpool.h"
 #include "gimple-ssa.h"
-#include "range.h"
 #include "tree-vrp.h"
+#include "range.h"
 #include "tree-ssanames.h"
 #include "tree-phinodes.h"
 #include "ssa-iterators.h" 
index 968c44c235a958237632d1cd4b4b45f7a2978c76..57ba08e0bc1a13d781221efee60c02e23c8a07cb 100644 (file)
@@ -223,6 +223,7 @@ value_range_base::check ()
        break;
       }
     case VR_UNDEFINED:
+      gcc_assert (!min () && !max ());
       break;
     case VR_VARYING:
       gcc_assert (m_min && m_max);
@@ -405,7 +406,7 @@ value_range_base::singleton_p (tree *result) const
 tree
 value_range_base::type () const
 {
-  gcc_assert (m_min);
+  gcc_assert (m_min || undefined_p ());
   return TREE_TYPE (min ());
 }
 
@@ -713,6 +714,7 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
 void
 value_range_base::set (enum value_range_kind kind, tree min, tree max)
 {
+  /* Use the canonical setters for VR_UNDEFINED and VR_VARYING.  */
   if (kind == VR_UNDEFINED)
     {
       set_undefined ();
@@ -1488,6 +1490,112 @@ combine_bound (enum tree_code code, wide_int &wi, wi::overflow_type &ovf,
     wi = wi::shwi (0, prec);
 }
 
+/* Given a range in [WMIN, WMAX], adjust it for possible overflow and
+   put the result in VR.
+
+   TYPE is the type of the range.
+
+   MIN_OVF and MAX_OVF indicate what type of overflow, if any,
+   occurred while originally calculating WMIN or WMAX.  -1 indicates
+   underflow.  +1 indicates overflow.  0 indicates neither.  */
+
+static void
+set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
+                              tree type,
+                              const wide_int &wmin, const wide_int &wmax,
+                              wi::overflow_type min_ovf,
+                              wi::overflow_type max_ovf)
+{
+  const signop sgn = TYPE_SIGN (type);
+  const unsigned int prec = TYPE_PRECISION (type);
+
+  /* For one bit precision if max < min, then the swapped
+     range covers all values.  */
+  if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
+    {
+      kind = VR_VARYING;
+      return;
+    }
+
+  if (TYPE_OVERFLOW_WRAPS (type))
+    {
+      /* If overflow wraps, truncate the values and adjust the
+        range kind and bounds appropriately.  */
+      wide_int tmin = wide_int::from (wmin, prec, sgn);
+      wide_int tmax = wide_int::from (wmax, prec, sgn);
+      if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
+       {
+         /* If the limits are swapped, we wrapped around and cover
+            the entire range.  We have a similar check at the end of
+            extract_range_from_binary_expr.  */
+         if (wi::gt_p (tmin, tmax, sgn))
+           kind = VR_VARYING;
+         else
+           {
+             kind = VR_RANGE;
+             /* No overflow or both overflow or underflow.  The
+                range kind stays VR_RANGE.  */
+             min = wide_int_to_tree (type, tmin);
+             max = wide_int_to_tree (type, tmax);
+           }
+         return;
+       }
+      else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
+              || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
+       {
+         /* Min underflow or max overflow.  The range kind
+            changes to VR_ANTI_RANGE.  */
+         bool covers = false;
+         wide_int tem = tmin;
+         tmin = tmax + 1;
+         if (wi::cmp (tmin, tmax, sgn) < 0)
+           covers = true;
+         tmax = tem - 1;
+         if (wi::cmp (tmax, tem, sgn) > 0)
+           covers = true;
+         /* If the anti-range would cover nothing, drop to varying.
+            Likewise if the anti-range bounds are outside of the
+            types values.  */
+         if (covers || wi::cmp (tmin, tmax, sgn) > 0)
+           {
+             kind = VR_VARYING;
+             return;
+           }
+         kind = VR_ANTI_RANGE;
+         min = wide_int_to_tree (type, tmin);
+         max = wide_int_to_tree (type, tmax);
+         return;
+       }
+      else
+       {
+         /* Other underflow and/or overflow, drop to VR_VARYING.  */
+         kind = VR_VARYING;
+         return;
+       }
+    }
+  else
+    {
+      /* If overflow does not wrap, saturate to the types min/max
+        value.  */
+      wide_int type_min = wi::min_value (prec, sgn);
+      wide_int type_max = wi::max_value (prec, sgn);
+      kind = VR_RANGE;
+      if (min_ovf == wi::OVF_UNDERFLOW)
+       min = wide_int_to_tree (type, type_min);
+      else if (min_ovf == wi::OVF_OVERFLOW)
+       min = wide_int_to_tree (type, type_max);
+      else
+       min = wide_int_to_tree (type, wmin);
+
+      if (max_ovf == wi::OVF_UNDERFLOW)
+       max = wide_int_to_tree (type, type_min);
+      else if (max_ovf == wi::OVF_OVERFLOW)
+       max = wide_int_to_tree (type, type_max);
+      else
+       max = wide_int_to_tree (type, wmax);
+    }
+}
+
 /* Fold two value range's of a POINTER_PLUS_EXPR into VR.  Return TRUE
    if successful.  */
 
@@ -1781,17 +1889,16 @@ extract_range_from_binary_expr (value_range_base *vr,
              return;
            }
 
-         adjust_range_for_overflow (type, wmin, wmax, expr_type,
-                                    min_ovf, max_ovf,
-                                    TYPE_OVERFLOW_WRAPS (expr_type));
+         /* Adjust the range for possible overflow.  */
+         min = NULL_TREE;
+         max = NULL_TREE;
+         set_value_range_with_overflow (type, min, max, expr_type,
+                                        wmin, wmax, min_ovf, max_ovf);
          if (type == VR_VARYING)
            {
              vr->set_varying (expr_type);
              return;
            }
-         gcc_assert (type != VR_UNDEFINED);
-         min = wide_int_to_tree (expr_type, wmin);
-         max = wide_int_to_tree (expr_type, wmax);
 
          /* Build the symbolic bounds if needed.  */
          adjust_symbolic_bound (min, code, expr_type,
@@ -2419,7 +2526,11 @@ range_ops_fold_binary_expr (value_range_base *vr,
   /* Do the range-ops dance.  */
   value_range_base n0 = normalize_for_range_ops (vr0);
   value_range_base n1 = normalize_for_range_ops (vr1);
+#if USE_IRANGE
+  *vr = irange_to_value_range (op->fold_range (expr_type, n0, n1));
+#else
   *vr = op->fold_range (expr_type, n0, n1);
+#endif
 }
 
 /* Fold a unary expression of a value_range with range-ops.  */
@@ -2477,7 +2588,11 @@ range_ops_fold_unary_expr (value_range_base *vr,
   /* Do the range-ops dance.  */
   value_range_base n0 = normalize_for_range_ops (*vr0);
   value_range_base n1 (expr_type);
+#if USE_IRANGE
+  *vr = irange_to_value_range (op->fold_range (expr_type, n0, n1));
+#else
   *vr = op->fold_range (expr_type, n0, n1);
+#endif
 }
 
 /* Generic folding of a binary expression between two value_ranges.
@@ -6426,7 +6541,7 @@ value_range_base::intersect_helper (const value_range_base *vr0,
   if (vr0type == VR_UNDEFINED)
     tem.set_undefined ();
   else if (vr0type == VR_VARYING)
-    tem.set_varying (TREE_TYPE (vr0->min ()));
+    tem.set_varying (vr0->type ());
   else
     tem.set (vr0type, vr0min, vr0max);
   /* If that failed, use the saved original VR0.  */
@@ -6665,7 +6780,9 @@ value_range_base::normalize_symbolics () const
       tree n = wide_int_to_tree (ttype, wi::to_wide (min ()) - 1);
       return value_range_base (VR_RANGE, vrp_val_min (ttype), n);
     }
-  return value_range_base (ttype);
+  value_range_base var;
+  var.set_varying (ttype);
+  return var;
 }
 
 unsigned
index 595a37fd0fce7a9aaf7f52ca7f5b5a280f693c86..a934a34efb68c291eb118572c49395729b0a55f5 100644 (file)
@@ -20,6 +20,21 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_TREE_VRP_H
 #define GCC_TREE_VRP_H
 
+/* Types of value ranges.  */
+enum value_range_kind
+{
+  /* Empty range.  */
+  VR_UNDEFINED,
+  /* Range spans the entire domain.  */
+  VR_VARYING,
+  /* Range is [MIN, MAX].  */
+  VR_RANGE,
+  /* Range is ~[MIN, MAX].  */
+  VR_ANTI_RANGE,
+  /* Range is a nice guy.  */
+  VR_LAST
+};
+
 class value_range_storage;
 
 /* Range of values that can be associated with an SSA_NAME after VRP
@@ -37,10 +52,6 @@ public:
   value_range_base (tree type, const wide_int &, const wide_int &);
   value_range_base (tree type, const value_range_storage *);
   value_range_base (tree type);
-#if USE_IRANGE
-  /* Only for branch.  */
-  value_range_base (const irange &ir) { *this = irange_to_value_range (ir); }
-#endif
 
   void set (value_range_kind, tree, tree);
   void set (tree);
@@ -78,7 +89,6 @@ public:
   static bool supports_type_p (tree);
   value_range_base normalize_symbolics () const;
 
-  /* Support machinery for irange.  */
   static const unsigned int m_max_pairs = 2;
   static bool supports_ssa_p (tree ssa);
   static bool supports_p (tree expr);
index 04e7573e3ad86444449cdddcf568d3bb6dc17b3d..b71291580dce30e3d27d7571acc10193b7fa76bf 100644 (file)
@@ -52,67 +52,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "range-op.h"
 #include "wide-int-range.h"
 
-
-/* Cache VARYING value_ranges indexed by type.  */
-class type_range_cache
-{
-public:
-  type_range_cache ();
-  ~type_range_cache ();
-  value_range *varying_range (tree type);
-private:
-  value_range *new_varying (tree type);
-  hash_map<tree, value_range *> *m_type_table;
-  obstack m_range_obj;
-};
-
-/* Delete type cache.  */
-type_range_cache::~type_range_cache ()
-{
-  delete m_type_table;
-  obstack_free (&m_range_obj, NULL);
-}
-
-/* Create a new type cache.  */
-type_range_cache::type_range_cache ()
-{
-  /* Allocate a map and a local obstack.  */
-  m_type_table = new hash_map<tree, value_range *>;
-  gcc_obstack_init (&m_range_obj);
-}
-
-/* Allocate a new range from the obstack and set it to VARYING for TYPE.  */
-inline value_range *
-type_range_cache::new_varying (tree type)
-{
-  /* Allocate memory.  */
-  void *p = XOBNEW (&m_range_obj, value_range);
-  /* Invoke the constructors on the memory using placement new.  */
-  value_range *new_p = new (p) value_range ();
-  /* Initialize it to varying.  */
-  new_p->set_varying (type);
-  return new_p;
-}
-
-/* Return a varying object for TYPE.  If it already exists, return it.
-   Otherwise allocate a new one and register it in the table.  */
-value_range *
-type_range_cache::varying_range (tree type)
-{
-  bool existed;
-  value_range *&slot = m_type_table->get_or_insert (type, &existed);
-  if (!existed)
-    slot = new_varying (type);
-  else
-    {
-      /* Sanity check to ensure this varying hasn't been modified.  */
-      value_range v;
-      v.set_varying (type);
-      gcc_checking_assert (v.equal_p (*slot, true));
-    }
-  return slot;
-}
-
 /* Convert the value_range in this object to an irange.  This function
    will normalize non-constant ranges into constant ranges by
    degrading them to VARYING.  */
@@ -889,23 +828,6 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
                           vrp_val_max (expr_type));
     }
 
-  /* Temporary testing hack.  */
-  if (getenv("HACK"))
-  {
-    value_range_base v;
-    tree type = signed_char_type_node;
-    enum tree_code code = BIT_AND_EXPR;
-    tree small = TYPE_MIN_VALUE (type);
-    small = fold_build2 (PLUS_EXPR, type, small, build_one_cst (type));
-    value_range_base vr0 (VR_ANTI_RANGE,
-                         small,
-                         build_int_cst (type, 0));
-    value_range_base vr1 (VR_RANGE,
-                         build_int_cst (type, -1),
-                         build_int_cst (type, 0));
-    range_fold_binary_expr (&v, code, type, &vr0, &vr1);
-  }
-
   range_fold_binary_expr (vr, code, expr_type, &vr0, &vr1);
 
   /* Set value_range for n in following sequence:
@@ -1918,8 +1840,10 @@ range_misc::adjust_range_with_loop (irange &ir, class loop *loop,
              /* Normalize the ranges for INIT and TEM to a constant
                 range, and call the generic
                 extract_range_from_binary_expr.  */
-             value_range_base vr0 = get_irange (init, stmt);
-             value_range_base vr1 = get_irange (tem, stmt);
+             value_range_base vr0
+               = irange_to_value_range (get_irange (init, stmt));
+             value_range_base vr1
+               = irange_to_value_range (get_irange (tem, stmt));
              value_range_base maxvr;
              range_fold_binary_expr (&maxvr, PLUS_EXPR,
                                      TREE_TYPE (init), &vr0, &vr1);
@@ -2030,7 +1954,7 @@ vr_values::adjust_range_with_scev (value_range_base *vr, struct loop *loop,
     return;
   irange ir = *vr;
   adjust_range_with_loop (ir, loop, stmt, var);
-  *vr = ir;
+  *vr = irange_to_value_range (ir);
 }
 
 /* Dump value ranges of all SSA_NAMEs to FILE.  */
@@ -2065,14 +1989,12 @@ vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
   bitmap_obstack_initialize (&vrp_equiv_obstack);
   to_remove_edges = vNULL;
   to_update_switch_stmts = vNULL;
-  type_cache = new type_range_cache;
 }
 
 /* Free VRP lattice.  */
 
 vr_values::~vr_values ()
 {
-  delete type_cache;
   /* Free allocated memory.  */
   free (vr_value);
   free (vr_phi_edge_counts);
@@ -3762,7 +3684,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
   if (TREE_CODE (op) == SSA_NAME)
     {
       // FIXME: We should convert this entire function to iranges.
-      vr_obj = get_irange (op, stmt);
+      vr_obj = irange_to_value_range (get_irange (op, stmt));
       vr = &vr_obj;
 
       /* We can only handle integer ranges.  */
index ea4c6b6e3baa36e45870b4cabe96b14be07a1e52..adf72a16f6906cb2ce8511b98f5377928680c7b3 100644 (file)
@@ -168,7 +168,6 @@ class vr_values : public range_misc
     tree vec;
   };
 
-  class type_range_cache *type_cache;
   vec<edge> to_remove_edges;
   vec<switch_update> to_update_switch_stmts;
 };
index 09538aff99511b775b77519953d4e77bb31b77ea..90c58f6bb6ecda09a7d86b103d53b1ef62be6d84 100644 (file)
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
    Return false for division by zero, for which the result is
    indeterminate.  */
 
-bool
+static bool
 wide_int_binop_overflow (wide_int &res,
                         enum tree_code code,
                         const wide_int &w0, const wide_int &w1,
@@ -863,105 +863,3 @@ wide_int_range_div (wide_int &wmin, wide_int &wmax,
     extra_range_p = false;
   return true;
 }
-
-/* Adjust the range in [WMIN, WMAX] for possible overflow and store the
-   parts of the resulting range in KIND, WMIN, WMAX.
-
-   TYPE is the type of the range.
-
-   MIN_OVF and MAX_OVF indicate what type of overflow, if any,
-   occurred while originally calculating WMIN or WMAX.  */
-
-void
-adjust_range_for_overflow (value_range_kind &kind,
-                          wide_int &wmin, wide_int &wmax,
-                          tree type,
-                          wi::overflow_type min_ovf,
-                          wi::overflow_type max_ovf,
-                          bool overflow_wraps)
-{
-  const signop sgn = TYPE_SIGN (type);
-  const unsigned int prec = TYPE_PRECISION (type);
-
-  /* For one bit precision if max < min, then the swapped
-     range covers all values.  */
-  if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
-    {
-      kind = VR_VARYING;
-      return;
-    }
-
-  if (overflow_wraps)
-    {
-      /* If overflow wraps, truncate the values and adjust the
-        range kind and bounds appropriately.  */
-      wide_int tmin = wide_int::from (wmin, prec, sgn);
-      wide_int tmax = wide_int::from (wmax, prec, sgn);
-      if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
-       {
-         /* If the limits are swapped, we wrapped around and cover
-            the entire range.  We have a similar check at the end of
-            extract_range_from_binary_expr.  */
-         if (wi::gt_p (tmin, tmax, sgn))
-           kind = VR_VARYING;
-         else
-           {
-             kind = VR_RANGE;
-             /* No overflow or both overflow or underflow.  The
-                range kind stays VR_RANGE.  */
-             wmin = tmin;
-             wmax = tmax;
-           }
-         return;
-       }
-      else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
-              || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
-       {
-         /* Min underflow or max overflow.  The range kind
-            changes to VR_ANTI_RANGE.  */
-         bool covers = false;
-         wide_int tem = tmin;
-         tmin = tmax + 1;
-         if (wi::cmp (tmin, tmax, sgn) < 0)
-           covers = true;
-         tmax = tem - 1;
-         if (wi::cmp (tmax, tem, sgn) > 0)
-           covers = true;
-         /* If the anti-range would cover nothing, drop to varying.
-            Likewise if the anti-range bounds are outside of the
-            types values.  */
-         if (covers || wi::cmp (tmin, tmax, sgn) > 0)
-           {
-             kind = VR_VARYING;
-             return;
-           }
-         kind = VR_ANTI_RANGE;
-         wmin = tmin;
-         wmax = tmax;
-         return;
-       }
-      else
-       {
-         /* Other underflow and/or overflow, drop to VR_VARYING.  */
-         kind = VR_VARYING;
-         return;
-       }
-    }
-  else
-    {
-      /* If overflow does not wrap, saturate to the types min/max
-        value.  */
-      wide_int type_min = wi::min_value (prec, sgn);
-      wide_int type_max = wi::max_value (prec, sgn);
-      kind = VR_RANGE;
-      if (min_ovf == wi::OVF_UNDERFLOW)
-       wmin = type_min;
-      else if (min_ovf == wi::OVF_OVERFLOW)
-       wmin = type_max;
-
-      if (max_ovf == wi::OVF_UNDERFLOW)
-       wmax = type_min;
-      else if (max_ovf == wi::OVF_OVERFLOW)
-       wmax = type_max;
-    }
-}
index e2c8f88a38e94f769db8978d5750bfa5e25927fe..fc9af72b12732432ef4fd46b993c061f567704d7 100644 (file)
@@ -185,17 +185,4 @@ wide_int_range_zero_p (const wide_int &wmin, const wide_int &wmax,
   return wmin == wmax && wi::eq_p (wmin, wi::zero (prec));
 }
 
-void
-adjust_range_for_overflow (value_range_kind &,
-                          wide_int &, wide_int &,
-                          tree type,
-                          wi::overflow_type, wi::overflow_type,
-                          bool overflow_wraps);
-
-bool
-wide_int_binop_overflow (wide_int &res,
-                        enum tree_code code,
-                        const wide_int &w0, const wide_int &w1,
-                        signop sign, bool overflow_undefined);
-
 #endif /* GCC_WIDE_INT_RANGE_H */