]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
typeless undefine
authorAldy Hernandez <aldyh@gcc.gnu.org>
Mon, 19 Aug 2019 15:59:47 +0000 (15:59 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Mon, 19 Aug 2019 15:59:47 +0000 (15:59 +0000)
From-SVN: r274674

gcc/grange.cc
gcc/range-op.cc
gcc/range.cc
gcc/range.h
gcc/ssa-range-cache.cc
gcc/ssa-range-gori.cc
gcc/ssa-range.cc
gcc/tree-ssanames.c
gcc/tree-vrp.c
gcc/tree-vrp.h
gcc/vr-values.c

index 31802359fd9f84b02bc329ce23cdae5f33a8ea5a..fb9b01909af29ee009edd0b35b8789f6149153d4 100644 (file)
@@ -279,7 +279,7 @@ grange_op::fold (irange &res, const irange &orig_r1) const
   if (lhs ())
     r2.set_varying (TREE_TYPE (lhs ()));
   else
-    r2.set_undefined (r1.type ());
+    r2.set_undefined ();
 
   return fold (res, r1, r2);
 }
@@ -327,7 +327,7 @@ grange_op::calc_op1_irange (irange &r, const irange &lhs_range) const
   tree type = TREE_TYPE (operand1 ());
   if (lhs_range.undefined_p ())
     {
-      r.set_undefined (type);
+      r.set_undefined ();
       return true;
     }
   // Unary operations require the type of the first operand in the second range
@@ -352,7 +352,7 @@ grange_op::calc_op1_irange (irange &r, const irange &lhs_range,
   // An empty range is viral, so return an empty range.
   if (op2_range.undefined_p () || lhs_range.undefined_p ())
     {
-      r.set_undefined (type);
+      r.set_undefined ();
       return true;
     }
   return handler ()->op1_range (r, type, lhs_range, op2_range);
@@ -370,7 +370,7 @@ grange_op::calc_op2_irange (irange &r, const irange &lhs_range,
   // An empty range is viral, so return an empty range.
   if (op1_range.undefined_p () || lhs_range.undefined_p ())
     {
-      r.set_undefined (type);
+      r.set_undefined ();
       return true;
     }
   return handler ()->op2_range (r, type, lhs_range, op1_range);
index ad5443ba1aa1c36cb3f917027fffdd393a1ab6b7..0d36e384cf24b2c40541e2903718f8271be992f7 100644 (file)
@@ -69,7 +69,7 @@ range_operator::fold_range (irange &r, tree type, const irange &lh,
   bool res = false;
 
   // Clear and set result type.
-  r.set_undefined (type);
+  r.set_undefined ();
 
   if (lh.undefined_p () || rh.undefined_p ())
     return true;
@@ -132,11 +132,11 @@ min_limit (const_tree type)
 // undefined and return true.  
 
 inline bool
-empty_range_check (irange &r, const irange &op1, const irange & op2, tree type)
+empty_range_check (irange &r, const irange &op1, const irange & op2)
 {
   if (op1.undefined_p () || op2.undefined_p ())
     {
-      r.set_undefined (type);
+      r.set_undefined ();
       return true;
     }
   else
@@ -309,7 +309,7 @@ get_bool_state (irange &r, const irange &lhs, tree val_type)
   /* If there is no result, then this is unexectuable, so no range. */
   if (lhs.undefined_p ())
     {
-      r.set_undefined (val_type);
+      r.set_undefined ();
       return BRS_EMPTY;
     }
 
@@ -345,7 +345,7 @@ bool
 operator_equal::fold_range (irange &r, tree type, const irange &op1,
                            const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   /* We can be sure the values are always equal or not if both ranges
@@ -425,7 +425,7 @@ bool
 operator_not_equal::fold_range (irange &r, tree type, const irange &op1,
                                const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   /* We can be sure the values are always equal or not if both ranges
@@ -497,7 +497,7 @@ build_lt (irange &r, tree type, const wide_int &val)
 
   /* If val - 1 underflows, check is X < MIN, which is an empty range.  */
   if (ov)
-    r.set_undefined (type);
+    r.set_undefined ();
   else
     r = irange (type, min_limit (type), lim);
 }
@@ -517,7 +517,7 @@ build_gt (irange &r, tree type, const wide_int &val)
   wide_int lim = wi::add (val, 1, TYPE_SIGN (type), &ov);
   /* If val + 1 overflows, check is for X > MAX , which is an empty range.  */
   if (ov)
-    r.set_undefined (type);
+    r.set_undefined ();
   else
     r = irange (type, lim, max_limit (type));
 }
@@ -545,7 +545,7 @@ public:
 bool
 operator_lt::fold_range (irange &r, tree type, const irange &op1, const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   signop sign = TYPE_SIGN (op1.type ());
@@ -616,7 +616,7 @@ public:
 bool
 operator_le::fold_range (irange &r, tree type, const irange &op1, const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   signop sign = TYPE_SIGN (op1.type ());
@@ -687,7 +687,7 @@ public:
 bool
 operator_gt::fold_range (irange &r, tree type, const irange &op1, const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   signop sign = TYPE_SIGN (op1.type ());
@@ -759,7 +759,7 @@ public:
 bool
 operator_ge::fold_range (irange &r, tree type, const irange &op1, const irange &op2) const
 {
-  if (empty_range_check (r, op1, op2, type))
+  if (empty_range_check (r, op1, op2))
     return true;
 
   signop sign = TYPE_SIGN (op1.type ());
@@ -1195,9 +1195,10 @@ public:
    r = (type_of(rh)) lh.  */
 
 bool
-operator_cast::fold_range (irange &r, tree type, const irange &lh, const irange &rh) const
+operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
+                          const irange &lh, const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   if (lh.type () != rh.type ())
@@ -1309,7 +1310,7 @@ bool
 operator_logical_and::fold_range (irange &r, tree type, const irange &lh,
                                  const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   // 0 && anything is 0
@@ -1400,7 +1401,7 @@ operator_bitwise_and::wi_fold (irange &r, tree type,
       // For AND, calculate each subrange separately, and then union
       // the results.
       irange tmp;
-      tmp.set_undefined (type);
+      tmp.set_undefined ();
       accumulate_range (tmp, type, new_lb, new_ub);
       r.union_ (tmp);
       return true;
@@ -1441,10 +1442,10 @@ public:
 
 
 bool
-operator_logical_or::fold_range (irange &r, tree type, const irange &lh,
-                                 const irange &rh) const
+operator_logical_or::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
+                                const irange &lh, const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   r = range_union (lh, rh);
@@ -1632,7 +1633,7 @@ bool
 operator_logical_not::fold_range (irange &r, tree type, const irange &lh,
                                  const irange &rh ATTRIBUTE_UNUSED) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   if (lh.varying_p () || lh.undefined_p ())
@@ -1668,7 +1669,7 @@ bool
 operator_bitwise_not::fold_range (irange &r, tree type, const irange &lh,
                                  const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   // ~X is simply -1 - X.
@@ -1777,7 +1778,7 @@ bool
 operator_abs::op1_range (irange &r, tree type,
                         const irange &lhs, const irange &op2) const
 {
-  if (empty_range_check (r, lhs, op2, type))
+  if (empty_range_check (r, lhs, op2))
     return true;
   if (TYPE_UNSIGNED (type))
     {
@@ -1859,7 +1860,7 @@ bool
 operator_negate::fold_range (irange &r, tree type,
                             const irange &lh, const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
   // -X is simply 0 - X.
   return range_op_handler (MINUS_EXPR, type)->fold_range (r, type, range_zero (type),
@@ -1879,7 +1880,7 @@ bool
 operator_addr_expr::fold_range (irange &r, tree type, const irange &lh,
                                const irange &rh) const
 {
-  if (empty_range_check (r, lh, rh, type))
+  if (empty_range_check (r, lh, rh))
     return true;
 
   // Return a non-null pointer of the LHS type (passed in op2)
index 0867cff699ef99e95ec6ab0d76c0ee9d5c180ab4..1f27eda1a9226b754ea1587b4bcd007c9775c842 100644 (file)
@@ -127,7 +127,7 @@ range_negatives (tree type)
   signop sign = TYPE_SIGN (type);
   irange r;
   if (sign == UNSIGNED)
-    r.set_undefined (type);
+    r.set_undefined ();
   else
     r = irange (type, wi::min_value (prec, sign), wi::minus_one (prec));
   return r;
@@ -370,7 +370,7 @@ range_tests ()
   r0 = range_zero (boolean_type_node);
   ASSERT_TRUE (r0 == irange (build_zero_cst (boolean_type_node),
                             build_zero_cst (boolean_type_node)));
-  r0.invert();
+  r0.invert ();
   ASSERT_TRUE (r0 == irange (build_one_cst (boolean_type_node),
                             build_one_cst (boolean_type_node)));
 
@@ -611,14 +611,14 @@ range_tests ()
 
   // Test irange_storage.
   r0 = irange (INT (5), INT (10));
-  irange_storage *stow = irange_storage::alloc (r0);
+  irange_storage *stow = irange_storage::alloc (r0, integer_type_node);
   r1 = irange (integer_type_node, stow);
   ASSERT_TRUE (r0 == r1);
 
   // Test irange_storage with signed 1-bit fields.
   tree s1bit_type = make_signed_type (1);
   r0 = irange (build_int_cst (s1bit_type, -1), build_int_cst (s1bit_type, 0));
-  stow = irange_storage::alloc (r0);
+  stow = irange_storage::alloc (r0, s1bit_type);
   r1 = irange (s1bit_type, stow);
   ASSERT_TRUE (r0 == r1);
 
@@ -667,7 +667,7 @@ irange::init (tree type, const wide_int &lbound, const wide_int &ubound,
 {
   if (rt == VR_UNDEFINED)
     {
-      set_undefined (type);
+      set_undefined ();
       return;
     }
   if (rt == VR_VARYING)
@@ -1025,8 +1025,6 @@ irange::canonicalize ()
 void
 irange::union_ (const irange &r)
 {
-  gcc_checking_assert (range_compatible_p (m_type, r.m_type));
-
   if (undefined_p ())
     {
       *this = r;
@@ -1035,6 +1033,8 @@ irange::union_ (const irange &r)
   else if (r.undefined_p ())
     return;
 
+  gcc_checking_assert (range_compatible_p (m_type, r.m_type));
+
   // Do not worry about merging and such by reserving twice as many
   // pairs as needed, and then simply sort the 2 ranges into this
   // intermediate form.
@@ -1141,8 +1141,10 @@ irange::union_ (const irange &r)
 void
 irange::intersect (const wide_int &x, const wide_int &y)
 {
-  unsigned pos = 0;
+  if (undefined_p ())
+    return;
 
+  unsigned pos = 0;
   for (unsigned i = 0; i < m_nitems; i += 2)
     {
       signop sign = TYPE_SIGN (m_type);
@@ -1169,13 +1171,16 @@ irange::intersect (const wide_int &x, const wide_int &y)
 void
 irange::intersect (const irange &r)
 {
-  gcc_checking_assert (range_compatible_p (m_type, r.m_type));
   irange orig_range (*this);
 
   // Intersection with an empty range is an empty range.
-  set_undefined ();
   if (orig_range.undefined_p () || r.undefined_p ())
-    return;
+    {
+      set_undefined ();
+      return;
+    }
+
+  gcc_checking_assert (range_compatible_p (m_type, r.m_type));
 
   // The general algorithm is as follows.
   //
@@ -1188,6 +1193,7 @@ irange::intersect (const irange &r)
   // Step 2: [10,20][30,40][50,60] ^ [38,51] => [38,40]
   // Step 3: [10,20][30,40][50,60] ^ [55,70] => [55,60]
   // Final:  [15,20] U [38,40] U [55,60] => [15,20][38,40][55,60]
+  set_undefined ();
   for (unsigned i = 0; i < r.m_nitems; i += 2)
     {
       irange tmp (orig_range);
@@ -1203,6 +1209,9 @@ irange::intersect (const irange &r)
 void
 irange::invert ()
 {
+  if (undefined_p ())
+    return;
+
   // We always need one more set of bounds to represent an inverse, so
   // if we're at the limit, we can't properly represent things.
   //
@@ -1228,13 +1237,6 @@ irange::invert ()
       return;
     }
 
-  // The inverse of the empty set is the entire domain.
-  if (undefined_p ())
-    {
-      set_varying (m_type);
-      return;
-    }
-
   // The algorithm is as follows.  To calculate INVERT ([a,b][c,d]), we
   // generate [-MIN, a-1][b+1, c-1][d+1, MAX].
   //
@@ -1301,6 +1303,13 @@ irange::invert ()
 void
 irange::dump (pretty_printer *buffer) const
 {
+  if (undefined_p ())
+    {
+      pp_string (buffer, "[]");
+      pp_flush (buffer);
+      return;
+    }
+
   wide_int min = wi::min_value (TYPE_PRECISION (m_type), TYPE_SIGN (m_type));
   wide_int max = wi::max_value (TYPE_PRECISION (m_type), TYPE_SIGN (m_type));
   if (POINTER_TYPE_P (m_type) && nonzero_p ())
@@ -1343,8 +1352,6 @@ irange::dump (pretty_printer *buffer) const
        else
          pp_character (buffer, ']');
       }
-  if (undefined_p ())
-    pp_string (buffer, "[]");
 
   pp_character (buffer, ' ');
   dump_generic_node (buffer, m_type, 0, TDF_NONE, false);
@@ -1377,9 +1384,14 @@ irange::dump () const
 // Initialize the current irange_storage to the irange in IR.
 
 void
-irange_storage::set (const irange &ir)
+irange_storage::set (const irange &ir, tree type)
 {
-  unsigned precision = TYPE_PRECISION (ir.type ());
+  if (type)
+    gcc_checking_assert (ir.undefined_p ()
+                        || types_compatible_p (type, ir.type ()));
+  else
+    type = ir.type ();
+  unsigned precision = TYPE_PRECISION (type);
   trailing_bounds.set_precision (precision);
   unsigned i;
   for (i = 0; i < ir.num_pairs () * 2; ++i)
@@ -1387,7 +1399,7 @@ irange_storage::set (const irange &ir)
 
   // Clear the remaining empty ranges.
   for (; i < irange::m_max_pairs * 2; i += 2)
-    set_empty_pair (i, i + 1, ir.type ());
+    set_empty_pair (i, i + 1, type);
 }
 
 // Update a previously initialized irange_storage to NEW_RANGE, iff the
@@ -1395,11 +1407,11 @@ irange_storage::set (const irange &ir)
 // the new range.  Return TRUE if update was successful.
 
 bool
-irange_storage::update (const irange &new_range)
+irange_storage::update (const irange &new_range, tree type)
 {
-  if (trailing_bounds.get_precision () == TYPE_PRECISION (new_range.type ()))
+  if (trailing_bounds.get_precision () == TYPE_PRECISION (type))
     {
-      set (new_range);
+      set (new_range, type);
       return true;
     }
   return false;
@@ -1432,7 +1444,7 @@ irange_to_value_range (const irange &r)
     }
   if (r.undefined_p ())
     {
-      vr.set_undefined (r.type ());
+      vr.set_undefined ();
       return vr;
     }
   tree type = r.type ();
@@ -1485,13 +1497,12 @@ irange_to_value_range (const irange &r)
 static irange
 value_range_to_irange (const value_range_base &vr)
 {
-  tree type = vr.type ();
   if (vr.varying_p ())
-    return irange (type);
+    return irange (vr.type ());
   if (vr.undefined_p ())
     {
       irange r;
-      r.set_undefined (type);
+      r.set_undefined ();
       return r;
     }
   return irange (vr.kind (), vr.min (), vr.max ());
index 0a1bf2cd02f1a2d4caa986b9fb45f60671f7e94e..8c8dd07b983b6755b1ed0c93d14fd270402cead6 100644 (file)
@@ -74,14 +74,14 @@ class irange
   static bool supports_p (tree expr);
 
   void set_varying (tree);
-  void set_undefined (tree = NULL);
+  void set_undefined ();
 
   unsigned num_pairs () const;
   wide_int lower_bound (unsigned pair = 0) const;
   wide_int upper_bound () const;
   wide_int upper_bound (unsigned pair) const;
 
-  tree type () const { return m_type; }
+  tree type () const;
 
   void cast (tree type);
 
@@ -164,11 +164,17 @@ irange::num_pairs () const
   return m_nitems / 2;
 }
 
+inline tree
+irange::type () const
+{
+  gcc_checking_assert (!undefined_p ());
+  return m_type;
+}
+
 inline void
-irange::set_undefined (tree type)
+irange::set_undefined ()
 {
-  if (type)
-    m_type = type;
+  m_type = NULL;
   m_nitems = 0;
 }
 
@@ -181,6 +187,8 @@ irange::undefined_p () const
 inline bool
 irange::zero_p () const
 {
+  if (m_nitems != 2)
+    return false;
   wide_int z = wi::zero (TYPE_PRECISION (m_type));
   return (m_nitems == 2 && m_bounds[0] == z && m_bounds[1] == z);
 }
@@ -188,6 +196,8 @@ irange::zero_p () const
 inline bool
 irange::nonzero_p () const
 {
+  if (undefined_p ())
+    return false;
   unsigned prec = TYPE_PRECISION (m_type);
   return *this == irange (VR_ANTI_RANGE, m_type,
                          wi::zero (prec), wi::zero (prec));
@@ -213,7 +223,7 @@ irange::varying_p () const
 // To store an irange class X into an irange_storage use:
 //
 //     irange X = ...;
-//     irange_storage *stow = irange_storage::alloc (X);
+//     irange_storage *stow = irange_storage::alloc (X, range_type);
 //
 // To convert it back into an irange use:
 //
@@ -231,12 +241,12 @@ class GTY((variable_size)) irange_storage
   friend class irange;
 
  public:
-  static irange_storage *alloc (const irange &);
-  bool update (const irange &);
+  static irange_storage *alloc (const irange &, tree type);
+  bool update (const irange &, tree type);
 
  private:
   static size_t size (unsigned precision);
-  void set (const irange &);
+  void set (const irange &, tree type);
   bool empty_pair_p (unsigned, unsigned, tree) const;
   void set_empty_pair (unsigned, unsigned, tree);
   void set_nonzero_bits (const wide_int &);
@@ -276,12 +286,17 @@ irange_storage::size (unsigned precision)
 // initialize it to IR.
 
 inline irange_storage *
-irange_storage::alloc (const irange &ir)
+irange_storage::alloc (const irange &ir, tree type)
 {
-  unsigned precision = TYPE_PRECISION (ir.m_type);
+  if (type)
+    gcc_checking_assert (ir.undefined_p ()
+                        || types_compatible_p (type, ir.type ()));
+  else
+    type = ir.type ();
+  unsigned precision = TYPE_PRECISION (type);
   irange_storage *stow = static_cast<irange_storage *> (ggc_internal_alloc
                                                        (size (precision)));
-  stow->set (ir);
+  stow->set (ir, type);
   stow->set_nonzero_bits (wi::shwi (-1, precision));
   return stow;
 }
index 1cc17a6b95cc7167b2dac1512d0ac1c6dd8f7193..43be4bde056342a9ed804817459b2ab7aa9348c3 100644 (file)
@@ -168,7 +168,7 @@ ssa_block_ranges::ssa_block_ranges (tree t)
 
   // Create the cached type range.
   tr.set_varying (t);
-  m_type_range = irange_storage::alloc (tr);
+  m_type_range = irange_storage::alloc (tr, t);
 
   m_tab[ENTRY_BLOCK_PTR_FOR_FN (cfun)->index] = m_type_range;
 }
@@ -188,10 +188,10 @@ ssa_block_ranges::set_bb_range (const basic_block bb, const irange &r)
   irange_storage *m = m_tab[bb->index];
 
   // If there is already range memory for this block, reuse it.
-  if (m && m != m_type_range && m->update (r))
+  if (m && m != m_type_range && m->update (r, m_type))
     ;
   else
-    m = irange_storage::alloc (r);
+    m = irange_storage::alloc (r, m_type);
 
   m_tab[bb->index] = m;
 }
@@ -429,11 +429,11 @@ ssa_global_cache::set_global_range (tree name, const irange& r)
     m_tab.safe_grow_cleared (num_ssa_names + 1);
   irange_storage *m = m_tab[v];
 
-  if (m && m->update (r))
+  if (m && m->update (r, TREE_TYPE (name)))
     ;
   else
     {
-      m = irange_storage::alloc (r);
+      m = irange_storage::alloc (r, TREE_TYPE (name));
       m_tab[SSA_NAME_VERSION (name)] = m;
     }
 }
@@ -631,7 +631,7 @@ if (DEBUG_CACHE) fprintf (dump_file, "FWD visiting block %d\n", bb->index);
 
       gcc_assert (m_on_entry.get_bb_range (current_range, name, bb));
       // Calculate the "new" range on entry by unioning the pred edges..
-      new_range.set_undefined (TREE_TYPE (name));
+      new_range.set_undefined ();
       FOR_EACH_EDGE (e, ei, bb->preds)
        {
          gcc_assert (edge_range (e_range, e, name));
@@ -678,7 +678,7 @@ gori_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
   // the range_on_entry cache for.
   m_workback.truncate (0);
   m_workback.quick_push (bb);
-  undefined.set_undefined (TREE_TYPE (name));
+  undefined.set_undefined ();
   m_on_entry.set_bb_range (name, bb, undefined);
   gcc_checking_assert (m_update_list.length () == 0);
 
index f5fdaf013f21210e173d57f996c1f344a0e412d8..fc13d2a3283af11dc829570823daddb0a3051c64 100644 (file)
@@ -738,7 +738,7 @@ gori_compute::compute_operand_range_op (irange &r, grange_op *stmt,
   // Empty ranges are viral as they are on a path which isn't executable.
   if (lhs.undefined_p ())
     {
-      r.set_undefined (TREE_TYPE (name));
+      r.set_undefined ();
       return true;
     }
 
@@ -1165,9 +1165,11 @@ gori_compute::range_from_import (irange &r, tree name, irange &import_range)
   bool res;
   tree import = terminal_name (name);
 
-  gcc_checking_assert (import &&
-                      useless_type_conversion_p (TREE_TYPE (import),
-                                                 import_range.type ()));
+  gcc_checking_assert
+    (import
+     && (import_range.undefined_p ()
+        || useless_type_conversion_p (TREE_TYPE (import),
+                                      import_range.type ())));
 
   // Only handling range_ops until we find a cond-expr that matters.
   // We process this specially so we can handle self-referencing chains. ie:
index 481a45fd7b0a88e00d0609745fd35d973d54d438..3e1ce85966cd9346cc588c314cb4bb39ee48924b 100644 (file)
@@ -227,7 +227,7 @@ switch_edge_manager::calc_single_range (irange &r, gswitch *sw, edge e)
 
   if (e != gimple_switch_default_edge (cfun, sw))
     {
-      r.set_undefined (type);
+      r.set_undefined ();
       // Loop through all the switches edges, ignoring the default edge.
       // unioning the ranges together.
       for (x = 1; x < lim; x++)
@@ -387,7 +387,7 @@ ssa_ranger::range_on_edge (irange &r, edge e, tree name)
   gcc_checking_assert (valid_ssa_p (name));
 
   range_on_exit (r, e->src, name);
-  gcc_checking_assert  (r.type() == TREE_TYPE (name));
+  gcc_checking_assert  (r.undefined_p () || r.type() == TREE_TYPE (name));
 
   // Check to see if NAME is defined on edge e.
   if (outgoing_edge_range_p (edge_range, e, name, &r))
@@ -432,6 +432,8 @@ ssa_ranger::range_of_stmt (irange &r, gimple *s, tree name)
     }
   if (res)
     {
+      if (r.undefined_p ())
+       return true;
       if (name && TREE_TYPE (name) != r.type ())
         r.cast (TREE_TYPE (name));
       return true;
@@ -474,7 +476,7 @@ ssa_ranger::range_on_entry (irange &r, basic_block bb, tree name)
   gcc_checking_assert (irange::supports_type_p (type));
 
   // Start with an empty range.
-  r.set_undefined (type);
+  r.set_undefined ();
 
   gcc_checking_assert (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
@@ -507,7 +509,7 @@ ssa_ranger::range_on_exit (irange &r, basic_block bb, tree name)
     range_on_entry (r, bb, name);
   else
     gcc_assert (range_of_expr (r, name, s));
-  gcc_checking_assert (r.type() == TREE_TYPE (name));
+  gcc_checking_assert (r.undefined_p () || r.type() == TREE_TYPE (name));
 }
 
 // Calculate a range for range_op statement S given RANGE1 and RANGE2 and 
@@ -660,7 +662,7 @@ ssa_ranger::range_of_phi (irange &r, gphi *phi, tree name,
     return false;
 
   // And start with an empty range, unioning in each argument's range.
-  r.set_undefined (type);
+  r.set_undefined ();
   for (x = 0; x < gimple_phi_num_args (phi); x++)
     {
       irange arg_range;
index 343e98488a9fd83f0c664bc00f5a6c4601fb159b..3911db9c26e56017ef045a16cfd9673337105c67 100644 (file)
@@ -443,7 +443,7 @@ get_range_info (const_tree name, value_range_base &vr)
   if (kind == VR_VARYING)
     vr.set_varying (TREE_TYPE (name));
   else if (kind == VR_UNDEFINED)
-    vr.set_undefined (TREE_TYPE (name));
+    vr.set_undefined ();
   else
     {
       min = wide_int_to_tree (TREE_TYPE (name), wmin);
index 33ef25ec946429a524908a714189559df1414e9e..d47712fa2c67d660c1e828eb7989469a1a059bda 100644 (file)
@@ -298,32 +298,16 @@ value_range_base::constant_p () const
 }
 
 void
-value_range_base::set_undefined (tree type)
+value_range_base::set_undefined ()
 {
   m_kind = VR_UNDEFINED;
-  if (type)
-    {
-      if (supports_type_p (type))
-       {
-         m_min = vrp_val_min (type, true);
-         m_max = vrp_val_max (type, true);
-       }
-      else
-       {
-         /* This is a temporary kludge for ipa-cp which is building
-            undefined/varying of floats.  ??  */
-         m_min = m_max = build1 (NOP_EXPR, type, type);
-       }
-    }
-  else
-    m_min = m_max = NULL;
+  m_min = m_max = NULL;
 }
 
 void
-value_range::set_undefined (tree type)
+value_range::set_undefined ()
 {
-  value_range_base::set_undefined (type);
-  equiv_clear ();
+  set (VR_UNDEFINED, NULL, NULL, NULL);
 }
 
 void
@@ -421,25 +405,19 @@ value_range_base::singleton_p (tree *result) const
 tree
 value_range_base::type () const
 {
-  gcc_assert (m_min || undefined_p ());
+  gcc_assert (m_min);
   return TREE_TYPE (min ());
 }
 
 void
 value_range_base::dump (FILE *file) const
 {
-  tree ttype;
-  if (undefined_p () && !m_min)
-    ttype = void_type_node;
-  else ttype = TREE_TYPE (m_min);
-
   if (undefined_p ())
-    {
-      print_generic_expr (file, ttype);
-      fprintf (file, " UNDEFINED");
-    }
+    fprintf (file, "UNDEFINED");
   else if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
     {
+      tree ttype = type ();
+
       print_generic_expr (file, ttype);
       fprintf (file, " ");
 
@@ -737,10 +715,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
 {
   if (kind == VR_UNDEFINED)
     {
-      if (min)
-       set_undefined (TREE_TYPE (min));
-      else
-       set_undefined ();
+      set_undefined ();
       return;
     }
   else if (kind == VR_VARYING)
@@ -863,7 +838,7 @@ value_range_base::set (enum value_range_kind kind, tree min, tree max)
       if (kind == VR_RANGE)
        set_varying (type);
       else if (kind == VR_ANTI_RANGE)
-       set_undefined (type);
+       set_undefined ();
       else
        gcc_unreachable ();
       return;
@@ -1323,8 +1298,8 @@ ranges_from_anti_range (const value_range_base *ar,
 
   tree type = ar->type ();
 
-  vr0->set_undefined (type);
-  vr1->set_undefined (type);
+  vr0->set_undefined ();
+  vr1->set_undefined ();
 
   /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
      [A+1, +INF].  Not sure if this helps in practice, though.  */
@@ -1347,7 +1322,7 @@ ranges_from_anti_range (const value_range_base *ar,
   if (vr0->undefined_p ())
     {
       *vr0 = *vr1;
-      vr1->set_undefined (type);
+      vr1->set_undefined ();
     }
 
   return !vr0->undefined_p ();
@@ -1608,7 +1583,7 @@ extract_range_from_binary_expr (value_range_base *vr,
   /* If both ranges are UNDEFINED, so is the result.  */
   if (vr0.undefined_p () && vr1.undefined_p ())
     {
-      vr->set_undefined (expr_type);
+      vr->set_undefined ();
       return;
     }
   /* If one of the ranges is UNDEFINED drop it to VARYING for the following
@@ -1921,7 +1896,7 @@ extract_range_from_binary_expr (value_range_base *vr,
       /* Special case explicit division by zero as undefined.  */
       if (vr1.zero_p ())
        {
-         vr->set_undefined (expr_type);
+         vr->set_undefined ();
          return;
        }
 
@@ -1960,7 +1935,7 @@ extract_range_from_binary_expr (value_range_base *vr,
     {
       if (vr1.zero_p ())
        {
-         vr->set_undefined (expr_type);
+         vr->set_undefined ();
          return;
        }
       wide_int wmin, wmax, tmp;
@@ -2101,7 +2076,7 @@ extract_range_from_unary_expr (value_range_base *vr,
   /* If VR0 is UNDEFINED, so is the result.  */
   if (vr0.undefined_p ())
     {
-      vr->set_undefined (type);
+      vr->set_undefined ();
       return;
     }
 
@@ -2421,7 +2396,7 @@ range_ops_fold_binary_expr (value_range_base *vr,
   value_range_base vr0 = *vr0_, vr1 = *vr1_;
   if (vr0.undefined_p () && vr1.undefined_p ())
     {
-      vr->set_undefined (expr_type);
+      vr->set_undefined ();
       return;
     }
   if (vr0.undefined_p ())
@@ -2473,7 +2448,7 @@ range_ops_fold_unary_expr (value_range_base *vr,
     }
   if (vr0->undefined_p ())
     {
-      vr->set_undefined (expr_type);
+      vr->set_undefined ();
       return;
     }
 
@@ -2535,8 +2510,10 @@ range_fold_binary_expr (value_range_base *vr,
                        const value_range_base *vr1)
 {
   if (!value_range_base::supports_type_p (expr_type)
-      || !value_range_base::supports_type_p (vr0->type ())
-      || !value_range_base::supports_type_p (vr1->type ()))
+      || (!vr0->undefined_p ()
+         && !value_range_base::supports_type_p (vr0->type ()))
+      || (!vr1->undefined_p ()
+         && !value_range_base::supports_type_p (vr1->type ())))
     {
       *vr = value_range (expr_type);
       return;
@@ -2562,10 +2539,11 @@ void
 range_fold_unary_expr (value_range_base *vr,
                       enum tree_code code,
                       tree expr_type,
-                      const value_range_base *vr0)
+                      const value_range_base *vr0,
+                      tree vr0_type)
 {
   if (!value_range_base::supports_type_p (expr_type)
-      || !value_range_base::supports_type_p (vr0->type ()))
+      || !value_range_base::supports_type_p (vr0_type))
     {
       *vr = value_range (expr_type);
       return;
@@ -2575,7 +2553,7 @@ range_fold_unary_expr (value_range_base *vr,
   if (flag_ranges_mode & RANGES_VRP)
     {
       value_range_base old;
-      extract_range_from_unary_expr (&old, code, expr_type, vr0, vr0->type ());
+      extract_range_from_unary_expr (&old, code, expr_type, vr0, vr0_type);
       if (flag_ranges_mode & RANGES_CHECKING)
        {
          value_range_base vr1 (expr_type);
@@ -6464,7 +6442,7 @@ value_range_base::intersect_helper (const value_range_base *vr0,
      fall back to vr0 when this turns things to varying.  */
   value_range_base tem;
   if (vr0type == VR_UNDEFINED)
-    tem.set_undefined (TREE_TYPE (vr0->min ()));
+    tem.set_undefined ();
   else if (vr0type == VR_VARYING)
     tem.set_varying (TREE_TYPE (vr0->min ()));
   else
@@ -6574,7 +6552,7 @@ value_range_base::union_helper (const value_range_base *vr0,
   /* Work on a temporary so we can still use vr0 when union returns varying.  */
   value_range_base tem;
   if (vr0type == VR_UNDEFINED)
-    tem.set_undefined (TREE_TYPE (vr0->min ()));
+    tem.set_undefined ();
   else if (vr0type == VR_VARYING)
     tem.set_varying (vr0->type ());
   else
@@ -6815,9 +6793,9 @@ void
 value_range_base::invert ()
 {
   if (undefined_p ())
-    set_varying (type ());
-  else if (varying_p ())
-    set_undefined (type ());
+    return;
+  if (varying_p ())
+    set_undefined ();
   else if (m_kind == VR_RANGE)
     m_kind = VR_ANTI_RANGE;
   else if (m_kind == VR_ANTI_RANGE)
@@ -6826,6 +6804,19 @@ value_range_base::invert ()
     gcc_unreachable ();
 }
 
+value_range_storage *
+value_range_storage::alloc (const value_range_base &r, tree type)
+{
+  if (type)
+    gcc_checking_assert (r.undefined_p ()
+                        || types_compatible_p (type, r.type ()));
+  else
+    type = r.type ();
+  value_range_storage *p = ggc_alloc<value_range_storage> ();
+  p->set (r, type);
+  return p;
+}
+
 void
 value_range_base::union_ (const value_range_base &r)
 {
index ba60f47ef0a8b955520462a18ddb854e4b6d7ff7..562928ad260abeddc4d83ca4fe58b5cdac600561 100644 (file)
@@ -57,7 +57,7 @@ public:
   bool undefined_p () const;
   bool varying_p () const;
   void set_varying (tree type);
-  void set_undefined (tree = NULL);
+  void set_undefined ();
 
   void union_ (const value_range_base *);
   void intersect (const value_range_base *);
@@ -148,7 +148,7 @@ class GTY((user)) value_range : public value_range_base
   bool equal_p (const value_range &, bool ignore_equivs) const;
 
   /* Types of value ranges.  */
-  void set_undefined (tree = NULL);
+  void set_undefined ();
   void set_varying (tree);
 
   /* Equivalence bitmap methods.  */
@@ -175,19 +175,14 @@ class value_range_storage
 {
   friend class value_range_base;
 public:
-  static value_range_storage *alloc (const value_range_base &r)
+  static value_range_storage *alloc (const value_range_base &r, tree type);
+  bool update (const value_range_base &r, tree type)
   {
-    value_range_storage *p = ggc_alloc<value_range_storage> ();
-    p->set (r);
-    return p;
-  }
-  bool update (const value_range_base &r)
-  {
-    set (r);
+    set (r, type);
     return true;
   }
 private:
-  void set (const value_range_base &r)
+  void set (const value_range_base &r, tree type ATTRIBUTE_UNUSED)
   {
     m_vr = r;
   }
@@ -372,17 +367,19 @@ void range_fold_binary_expr (value_range_base *, enum tree_code, tree,
                             const value_range_base *,
                             const value_range_base *);
 void range_fold_unary_expr (value_range_base *, enum tree_code, tree,
-                           const value_range_base *);
+                           const value_range_base *, tree);
 
 /* Return TRUE if *VR includes the value zero.  */
 
 inline bool
 range_includes_zero_p (const value_range_base *vr)
 {
-  /* UNDEFINED may not have a type in uninitialized ranges.  */
   if (vr->undefined_p ())
     return false;
 
+  if (vr->varying_p ())
+    return true;
+
   return vr->may_contain_p (build_zero_cst (vr->type ()));
 }
 
index 8e48178962e542ee9e188f6be1c80d30f5305ac3..c37c007606d98e635acc1ba9a0a493f4b5b348e2 100644 (file)
@@ -187,7 +187,7 @@ vr_values::get_lattice_entry (const_tree var)
       return vr;
     }
 
-  vr->set_undefined (TREE_TYPE (var));
+  vr->set_undefined ();
 
   /* If VAR is a default definition of a parameter, the variable can
      take any value in VAR's type.  */
@@ -1032,7 +1032,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
   else
     vr0.set_varying (type);
 
-  range_fold_unary_expr (vr, code, type, &vr0);
+  range_fold_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
 }