aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@gcc.gnu.org>2019-08-19 15:59:47 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2019-08-19 15:59:47 +0000
commit09febaec27709d1a05ff422ba1bb29fd3150d643 (patch)
tree71b474ef626789d4f9b9ae355931d4fa095e6217
parentd99d7058288b6c38a0e5fe13ed2f5c3a2f2efeb5 (diff)
downloadgcc-09febaec27709d1a05ff422ba1bb29fd3150d643.zip
gcc-09febaec27709d1a05ff422ba1bb29fd3150d643.tar.gz
gcc-09febaec27709d1a05ff422ba1bb29fd3150d643.tar.bz2
typeless undefine
From-SVN: r274674
-rw-r--r--gcc/grange.cc8
-rw-r--r--gcc/range-op.cc49
-rw-r--r--gcc/range.cc71
-rw-r--r--gcc/range.h39
-rw-r--r--gcc/ssa-range-cache.cc14
-rw-r--r--gcc/ssa-range-gori.cc10
-rw-r--r--gcc/ssa-range.cc12
-rw-r--r--gcc/tree-ssanames.c2
-rw-r--r--gcc/tree-vrp.c99
-rw-r--r--gcc/tree-vrp.h23
-rw-r--r--gcc/vr-values.c4
11 files changed, 175 insertions, 156 deletions
diff --git a/gcc/grange.cc b/gcc/grange.cc
index 3180235..fb9b019 100644
--- a/gcc/grange.cc
+++ b/gcc/grange.cc
@@ -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);
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index ad5443b..0d36e38 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -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)
diff --git a/gcc/range.cc b/gcc/range.cc
index 0867cff..1f27eda 100644
--- a/gcc/range.cc
+++ b/gcc/range.cc
@@ -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 ());
diff --git a/gcc/range.h b/gcc/range.h
index 0a1bf2c..8c8dd07 100644
--- a/gcc/range.h
+++ b/gcc/range.h
@@ -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;
}
diff --git a/gcc/ssa-range-cache.cc b/gcc/ssa-range-cache.cc
index 1cc17a6..43be4bd 100644
--- a/gcc/ssa-range-cache.cc
+++ b/gcc/ssa-range-cache.cc
@@ -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);
diff --git a/gcc/ssa-range-gori.cc b/gcc/ssa-range-gori.cc
index f5fdaf0..fc13d2a 100644
--- a/gcc/ssa-range-gori.cc
+++ b/gcc/ssa-range-gori.cc
@@ -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:
diff --git a/gcc/ssa-range.cc b/gcc/ssa-range.cc
index 481a45f..3e1ce85 100644
--- a/gcc/ssa-range.cc
+++ b/gcc/ssa-range.cc
@@ -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;
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 343e984..3911db9 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -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);
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 33ef25e..d47712f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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)
{
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index ba60f47..562928a 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -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 ()));
}
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 8e48178..c37c007 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -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));
}