// undefined and return TRUE.
inline bool
-empty_range_check (value_range_base &r,
- const value_range_base &op1,
- const value_range_base & op2)
+empty_range_check (value_range &r,
+ const value_range &op1, const value_range & op2)
{
if (op1.undefined_p () || op2.undefined_p ())
{
// the appropriate range.
static inline bool
-undefined_shift_range_check (value_range_base &r, tree type,
- value_range_base op)
+undefined_shift_range_check (value_range &r, tree type, const value_range op)
{
if (op.undefined_p ())
{
- r = value_range_base ();
+ r = value_range ();
return true;
}
|| wi::ge_p (op.upper_bound (),
TYPE_PRECISION (type), TYPE_SIGN (op.type ())))
{
- r = value_range_base (type);
+ r = value_range (type);
return true;
}
return false;
// Default wide_int fold operation returns [MIN, MAX].
-value_range_base
+value_range
range_operator::wi_fold (tree type,
const wide_int &lh_lb ATTRIBUTE_UNUSED,
const wide_int &lh_ub ATTRIBUTE_UNUSED,
const wide_int &rh_lb ATTRIBUTE_UNUSED,
const wide_int &rh_ub ATTRIBUTE_UNUSED) const
{
- return value_range_base (type);
+ return value_range (type);
}
// The default for fold is to break all ranges into sub-ranges and
// invoke the wi_fold method on each sub-range pair.
-value_range_base
+value_range
range_operator::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
// The default for op1_range is to return false.
bool
-range_operator::op1_range (value_range_base &r ATTRIBUTE_UNUSED,
+range_operator::op1_range (value_range &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
- const value_range_base &lhs ATTRIBUTE_UNUSED,
- const value_range_base &op2 ATTRIBUTE_UNUSED) const
+ const value_range &lhs ATTRIBUTE_UNUSED,
+ const value_range &op2 ATTRIBUTE_UNUSED) const
{
return false;
}
// The default for op2_range is to return false.
bool
-range_operator::op2_range (value_range_base &r ATTRIBUTE_UNUSED,
+range_operator::op2_range (value_range &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
- const value_range_base &lhs ATTRIBUTE_UNUSED,
- const value_range_base &op1 ATTRIBUTE_UNUSED) const
+ const value_range &lhs ATTRIBUTE_UNUSED,
+ const value_range &op1 ATTRIBUTE_UNUSED) const
{
return false;
}
// Create and return a range from a pair of wide-ints that are known
// to have overflowed (or underflowed).
-static value_range_base
+static value_range
value_range_from_overflowed_bounds (tree type,
const wide_int &wmin,
const wide_int &wmax)
// Likewise if the anti-range bounds are outside of the types
// values.
if (covers || wi::cmp (tmin, tmax, sgn) > 0)
- return value_range_base (type);
+ return value_range (type);
- return value_range_base (VR_ANTI_RANGE, type, tmin, tmax);
+ return value_range (VR_ANTI_RANGE, type, tmin, tmax);
}
// Create and return a range from a pair of wide-ints. MIN_OVF and
// MAX_OVF describe any overflow that might have occurred while
// calculating WMIN and WMAX respectively.
-static value_range_base
+static value_range
value_range_with_overflow (tree type,
const wide_int &wmin, const wide_int &wmax,
wi::overflow_type min_ovf = wi::OVF_NONE,
// For one bit precision if max != min, then the range covers all
// values.
if (prec == 1 && wi::ne_p (wmax, wmin))
- return value_range_base (type);
+ return value_range (type);
if (overflow_wraps)
{
// If the limits are swapped, we wrapped around and cover
// the entire range.
if (wi::gt_p (tmin, tmax, sgn))
- return value_range_base (type);
+ return value_range (type);
// No overflow or both overflow or underflow. The range
// kind stays normal.
- return value_range_base (type, tmin, tmax);
+ return value_range (type, tmin, tmax);
}
if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
return value_range_from_overflowed_bounds (type, wmin, wmax);
// Other underflow and/or overflow, drop to VR_VARYING.
- return value_range_base (type);
+ return value_range (type);
}
else
{
else
new_ub = wmax;
- return value_range_base (type, new_lb, new_ub);
+ return value_range (type, new_lb, new_ub);
}
}
// the case where the bounds are swapped. In which case, we transform
// [10,5] into [MIN,5][10,MAX].
-static inline value_range_base
+static inline value_range
create_possibly_reversed_range (tree type,
const wide_int &new_lb, const wide_int &new_ub)
{
return value_range_from_overflowed_bounds (type, new_lb, new_ub);
// Otherwise its just a normal range.
- return value_range_base (type, new_lb, new_ub);
+ return value_range (type, new_lb, new_ub);
}
-// Return a value_range_base instance that is a boolean TRUE.
+// Return a value_range instance that is a boolean TRUE.
-static inline value_range_base
+static inline value_range
range_true (tree type)
{
unsigned prec = TYPE_PRECISION (type);
- return value_range_base (type, wi::one (prec), wi::one (prec));
+ return value_range (type, wi::one (prec), wi::one (prec));
}
-// Return a value_range_base instance that is a boolean FALSE.
+// Return a value_range instance that is a boolean FALSE.
-static inline value_range_base
+static inline value_range
range_false (tree type)
{
unsigned prec = TYPE_PRECISION (type);
- return value_range_base (type, wi::zero (prec), wi::zero (prec));
+ return value_range (type, wi::zero (prec), wi::zero (prec));
}
-// Return a value_range_base that covers both true and false.
+// Return a value_range that covers both true and false.
-static inline value_range_base
+static inline value_range
range_true_and_false (tree type)
{
unsigned prec = TYPE_PRECISION (type);
- return value_range_base (type, wi::zero (prec), wi::one (prec));
+ return value_range (type, wi::zero (prec), wi::one (prec));
}
enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL };
// the bool range.
static bool_range_state
-get_bool_state (value_range_base &r,
- const value_range_base &lhs, tree val_type)
+get_bool_state (value_range &r, const value_range &lhs, tree val_type)
{
// If there is no result, then this is unexecutable.
if (lhs.undefined_p ())
class operator_equal : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &val) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &val) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &val) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &val) const;
} op_equal;
-value_range_base
+value_range
operator_equal::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_equal::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_equal::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_equal::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_equal::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_equal::op1_range (r, type, lhs, op1);
}
class operator_not_equal : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_not_equal;
-value_range_base
+value_range
operator_not_equal::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_not_equal::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_not_equal::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
bool
-operator_not_equal::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_not_equal::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_not_equal::op1_range (r, type, lhs, op1);
}
// (X < VAL) produces the range of [MIN, VAL - 1].
static void
-build_lt (value_range_base &r, tree type, const wide_int &val)
+build_lt (value_range &r, tree type, const wide_int &val)
{
wi::overflow_type ov;
wide_int lim = wi::sub (val, 1, TYPE_SIGN (type), &ov);
if (ov)
r.set_undefined ();
else
- r = value_range_base (type, min_limit (type), lim);
+ r = value_range (type, min_limit (type), lim);
}
// (X <= VAL) produces the range of [MIN, VAL].
static void
-build_le (value_range_base &r, tree type, const wide_int &val)
+build_le (value_range &r, tree type, const wide_int &val)
{
- r = value_range_base (type, min_limit (type), val);
+ r = value_range (type, min_limit (type), val);
}
// (X > VAL) produces the range of [VAL + 1, MAX].
static void
-build_gt (value_range_base &r, tree type, const wide_int &val)
+build_gt (value_range &r, tree type, const wide_int &val)
{
wi::overflow_type ov;
wide_int lim = wi::add (val, 1, TYPE_SIGN (type), &ov);
if (ov)
r.set_undefined ();
else
- r = value_range_base (type, lim, max_limit (type));
+ r = value_range (type, lim, max_limit (type));
}
// (X >= val) produces the range of [VAL, MAX].
static void
-build_ge (value_range_base &r, tree type, const wide_int &val)
+build_ge (value_range &r, tree type, const wide_int &val)
{
- r = value_range_base (type, val, max_limit (type));
+ r = value_range (type, val, max_limit (type));
}
class operator_lt : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_lt;
-value_range_base
+value_range
operator_lt::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_lt::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_lt::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_lt::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_lt::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
switch (get_bool_state (r, lhs, type))
{
class operator_le : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_le;
-value_range_base
+value_range
operator_le::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_le::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_le::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_le::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_le::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
switch (get_bool_state (r, lhs, type))
{
class operator_gt : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_gt;
-value_range_base
+value_range
operator_gt::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1, const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_gt::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_gt::op1_range (value_range &r, tree type,
+ const value_range &lhs, const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_gt::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_gt::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
switch (get_bool_state (r, lhs, type))
{
class operator_ge : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_ge;
-value_range_base
+value_range
operator_ge::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, op1, op2))
return r;
}
bool
-operator_ge::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_ge::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_ge::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_ge::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
switch (get_bool_state (r, lhs, type))
{
class operator_plus : public range_operator
{
public:
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_plus;
-value_range_base
+value_range
operator_plus::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
}
bool
-operator_plus::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_plus::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
r = range_op_handler (MINUS_EXPR, type)->fold_range (type, lhs, op2);
return true;
}
bool
-operator_plus::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_plus::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
r = range_op_handler (MINUS_EXPR, type)->fold_range (type, lhs, op1);
return true;
class operator_minus : public range_operator
{
public:
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_minus;
-value_range_base
+value_range
operator_minus::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
}
bool
-operator_minus::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_minus::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
r = range_op_handler (PLUS_EXPR, type)->fold_range (type, lhs, op2);
return true;
}
bool
-operator_minus::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_minus::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
r = fold_range (type, op1, lhs);
return true;
class operator_min : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_min;
-value_range_base
+value_range
operator_min::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
class operator_max : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_max;
-value_range_base
+value_range
operator_max::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
const wide_int &) const = 0;
// Calculate the cross product of two sets of sub-ranges and return it.
- value_range_base wi_cross_product (tree type,
+ value_range wi_cross_product (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
const wide_int &rh_lb,
// MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP MAX1) and then
// figure the smallest and largest values to form the new range.
-value_range_base
+value_range
cross_product_operator::wi_cross_product (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
// Compute the 4 cross operations, bailing if we get an overflow we
// can't handle.
if (wi_op_overflows (cp1, type, lh_lb, rh_lb))
- return value_range_base (type);
+ return value_range (type);
if (wi::eq_p (lh_lb, lh_ub))
cp3 = cp1;
else if (wi_op_overflows (cp3, type, lh_ub, rh_lb))
- return value_range_base (type);
+ return value_range (type);
if (wi::eq_p (rh_lb, rh_ub))
cp2 = cp1;
else if (wi_op_overflows (cp2, type, lh_lb, rh_ub))
- return value_range_base (type);
+ return value_range (type);
if (wi::eq_p (lh_lb, lh_ub))
cp4 = cp2;
else if (wi_op_overflows (cp4, type, lh_ub, rh_ub))
- return value_range_base (type);
+ return value_range (type);
// Order pairs.
signop sign = TYPE_SIGN (type);
class operator_mult : public cross_product_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
- virtual bool wi_op_overflows (wide_int &res,
- tree type,
- const wide_int &w0,
- const wide_int &w1) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
+ virtual bool wi_op_overflows (wide_int &res, tree type,
+ const wide_int &w0, const wide_int &w1) const;
} op_mult;
bool
-operator_mult::wi_op_overflows (wide_int &res,
- tree type,
- const wide_int &w0,
- const wide_int &w1) const
+operator_mult::wi_op_overflows (wide_int &res, tree type,
+ const wide_int &w0, const wide_int &w1) const
{
wi::overflow_type overflow = wi::OVF_NONE;
signop sign = TYPE_SIGN (type);
return overflow;
}
-value_range_base
+value_range
operator_mult::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
prod2 = prod3 - prod0;
if (wi::geu_p (prod2, sizem1))
// The range covers all values.
- return value_range_base (type);
+ return value_range (type);
wide_int new_lb = wide_int::from (prod0, prec, sign);
wide_int new_ub = wide_int::from (prod3, prec, sign);
{
public:
operator_div (enum tree_code c) { code = c; }
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
- virtual bool wi_op_overflows (wide_int &res,
- tree type,
- const wide_int &,
- const wide_int &) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
+ virtual bool wi_op_overflows (wide_int &res, tree type,
+ const wide_int &, const wide_int &) const;
private:
enum tree_code code;
};
bool
-operator_div::wi_op_overflows (wide_int &res,
- tree type,
- const wide_int &w0,
- const wide_int &w1) const
+operator_div::wi_op_overflows (wide_int &res, tree type,
+ const wide_int &w0, const wide_int &w1) const
{
if (w1 == 0)
return true;
return overflow;
}
-value_range_base
+value_range
operator_div::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
{
// If we know we will divide by zero, return undefined.
if (rh_lb == 0 && rh_ub == 0)
- return value_range_base ();
+ return value_range ();
const wide_int dividend_min = lh_lb;
const wide_int dividend_max = lh_ub;
// If flag_non_call_exceptions, we must not eliminate a division by zero.
if (cfun->can_throw_non_call_exceptions)
- return value_range_base (type);
+ return value_range (type);
// If we're definitely dividing by zero, there's nothing to do.
if (wi_zero_p (type, divisor_min, divisor_max))
- return value_range_base ();
+ return value_range ();
// Perform the division in 2 parts, [LB, -1] and [1, UB], which will
// skip any division by zero.
// First divide by the negative numbers, if any.
- value_range_base r;
+ value_range r;
if (wi::neg_p (divisor_min, sign))
r = wi_cross_product (type, dividend_min, dividend_max,
divisor_min, wi::minus_one (prec));
// Then divide by the non-zero positive numbers, if any.
if (wi::gt_p (divisor_max, wi::zero (prec), sign))
{
- value_range_base tmp;
+ value_range tmp;
tmp = wi_cross_product (type, dividend_min, dividend_max,
wi::one (prec), divisor_max);
r.union_ (tmp);
{
public:
operator_exact_divide () : operator_div (TRUNC_DIV_EXPR) { }
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_exact_div;
bool
-operator_exact_divide::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_exact_divide::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
tree offset;
// [2, 4] = op1 / [3,3] since its exact divide, no need to worry about
class operator_lshift : public cross_product_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
- virtual value_range_base wi_fold (tree type,
+ virtual value_range wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
virtual bool wi_op_overflows (wide_int &res,
const wide_int &) const;
} op_lshift;
-value_range_base
+value_range
operator_lshift::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (undefined_shift_range_check (r, type, op2))
return r;
{
unsigned shift = op2.lower_bound ().to_uhwi ();
wide_int tmp = wi::set_bit_in_zero (shift, TYPE_PRECISION (type));
- value_range_base mult (type, tmp, tmp);
+ value_range mult (type, tmp, tmp);
// Force wrapping multiplication.
bool saved_flag_wrapv = flag_wrapv;
return range_operator::fold_range (type, op1, op2);
}
-value_range_base
+value_range
operator_lshift::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
if (in_bounds)
return wi_cross_product (type, lh_lb, lh_ub, rh_lb, rh_ub);
- return value_range_base (type);
+ return value_range (type);
}
bool
-operator_lshift::wi_op_overflows (wide_int &res,
- tree type,
- const wide_int &w0,
- const wide_int &w1) const
+operator_lshift::wi_op_overflows (wide_int &res, tree type,
+ const wide_int &w0, const wide_int &w1) const
{
signop sign = TYPE_SIGN (type);
if (wi::neg_p (w1))
class operator_rshift : public cross_product_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb, const wide_int &lh_ub,
- const wide_int &rh_lb, const wide_int &rh_ub) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
virtual bool wi_op_overflows (wide_int &res,
tree type,
const wide_int &w0,
return false;
}
-value_range_base
+value_range
operator_rshift::fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const
+ const value_range &op1,
+ const value_range &op2) const
{
- value_range_base r;
+ value_range r;
if (undefined_shift_range_check (r, type, op2))
return r;
return range_operator::fold_range (type, op1, op2);
}
-value_range_base
+value_range
operator_rshift::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const
class operator_cast: public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_convert;
-value_range_base
+value_range
operator_cast::fold_range (tree type ATTRIBUTE_UNUSED,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
if (!wi::eq_p (min, wi::min_value (outer_prec, outer_sign))
|| !wi::eq_p (max, wi::max_value (outer_prec, outer_sign)))
{
- value_range_base tmp;
+ value_range tmp;
tmp = create_possibly_reversed_range (type, min, max);
r.union_ (tmp);
continue;
}
}
- return value_range_base (type);
+ return value_range (type);
}
return r;
}
bool
-operator_cast::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_cast::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
tree lhs_type = lhs.type ();
gcc_checking_assert (types_compatible_p (op2.type(), type));
// the type, see if it fits the LHS, and if so, then we can allow
// it.
r = op2;
- r = fold_range (lhs_type, r, value_range_base (lhs_type));
- r = fold_range (type, r, value_range_base (type));
+ r = fold_range (lhs_type, r, value_range (lhs_type));
+ r = fold_range (type, r, value_range (type));
if (r == op2)
{
// We know the value of the RHS fits in the LHS type, so
// convert the LHS and remove any values that arent in OP2.
r = lhs;
- r = fold_range (type, r, value_range_base (type));
+ r = fold_range (type, r, value_range (type));
r.intersect (op2);
return true;
}
// *not* in the RHS is 0 or -1.
unsigned prec = TYPE_PRECISION (type);
if (lhs.zero_p ())
- r = value_range_base (VR_ANTI_RANGE, type,
- wi::minus_one (prec), wi::minus_one (prec));
+ r = value_range (VR_ANTI_RANGE, type,
+ wi::minus_one (prec), wi::minus_one (prec));
else
- r = value_range_base (VR_ANTI_RANGE, type,
- wi::zero (prec), wi::zero (prec));
+ r = value_range (VR_ANTI_RANGE, type,
+ wi::zero (prec), wi::zero (prec));
// And intersect it with what we know about op2.
r.intersect (op2);
}
if (TYPE_PRECISION (lhs_type) > TYPE_PRECISION (type))
{
// Cast the range of the RHS to the type of the LHS.
- value_range_base op_type (type);
- op_type = fold_range (lhs_type, op_type, value_range_base (lhs_type));
+ value_range op_type (type);
+ op_type = fold_range (lhs_type, op_type, value_range (lhs_type));
// Intersect this with the LHS range will produce the RHS range.
r = range_intersect (lhs, op_type);
r = lhs;
// Cast the calculated range to the type of the RHS.
- r = fold_range (type, r, value_range_base (type));
+ r = fold_range (type, r, value_range (type));
return true;
}
class operator_logical_and : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &lh,
+ const value_range &rh) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_logical_and;
-value_range_base
+value_range
operator_logical_and::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
}
bool
-operator_logical_and::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2 ATTRIBUTE_UNUSED) const
+operator_logical_and::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2 ATTRIBUTE_UNUSED) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_logical_and::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_logical_and::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_logical_and::op1_range (r, type, lhs, op1);
}
class operator_bitwise_and : public range_operator
{
public:
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_bitwise_and;
// Optimize BIT_AND_EXPR and BIT_IOR_EXPR in terms of a mask if
// return TRUE.
static bool
-wi_optimize_and_or (value_range_base &r,
+wi_optimize_and_or (value_range &r,
enum tree_code code,
tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
}
}
-value_range_base
+value_range
operator_bitwise_and::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
const wide_int &rh_lb,
const wide_int &rh_ub) const
{
- value_range_base r;
+ value_range r;
if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
return r;
}
// If the limits got swapped around, return varying.
if (wi::gt_p (new_lb, new_ub,sign))
- return value_range_base (type);
+ return value_range (type);
return value_range_with_overflow (type, new_lb, new_ub);
}
bool
-operator_bitwise_and::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_bitwise_and::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
// If this is really a logical wi_fold, call that.
if (types_compatible_p (type, boolean_type_node))
}
bool
-operator_bitwise_and::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_bitwise_and::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_bitwise_and::op1_range (r, type, lhs, op1);
}
class operator_logical_or : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
+ virtual value_range fold_range (tree type,
+ const value_range &lh,
+ const value_range &rh) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
} op_logical_or;
-value_range_base
+value_range
operator_logical_or::fold_range (tree type ATTRIBUTE_UNUSED,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
}
bool
-operator_logical_or::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2 ATTRIBUTE_UNUSED) const
+operator_logical_or::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2 ATTRIBUTE_UNUSED) const
{
switch (get_bool_state (r, lhs, type))
{
}
bool
-operator_logical_or::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_logical_or::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_logical_or::op1_range (r, type, lhs, op1);
}
class operator_bitwise_or : public range_operator
{
public:
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
- virtual bool op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const;
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
+ virtual bool op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_bitwise_or;
-value_range_base
+value_range
operator_bitwise_or::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
const wide_int &rh_lb,
const wide_int &rh_ub) const
{
- value_range_base r;
+ value_range r;
if (wi_optimize_and_or (r, BIT_IOR_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
return r;
new_lb = wi::max (new_lb, rh_lb, sign);
// If the limits got swapped around, return varying.
if (wi::gt_p (new_lb, new_ub,sign))
- return value_range_base (type);
+ return value_range (type);
return value_range_with_overflow (type, new_lb, new_ub);
}
bool
-operator_bitwise_or::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_bitwise_or::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
// If this is really a logical wi_fold, call that.
if (types_compatible_p (type, boolean_type_node))
}
bool
-operator_bitwise_or::op2_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op1) const
+operator_bitwise_or::op2_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op1) const
{
return operator_bitwise_or::op1_range (r, type, lhs, op1);
}
class operator_bitwise_xor : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_bitwise_xor;
-value_range_base
+value_range
operator_bitwise_xor::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
if (wi::lt_p (new_lb, 0, sign) || wi::ge_p (new_ub, 0, sign))
return value_range_with_overflow (type, new_lb, new_ub);
- return value_range_base (type);
+ return value_range (type);
}
class operator_trunc_mod : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_trunc_mod;
-value_range_base
+value_range
operator_trunc_mod::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
// Mod 0 is undefined. Return undefined.
if (wi_zero_p (type, rh_lb, rh_ub))
- return value_range_base ();
+ return value_range ();
// ABS (A % B) < ABS (B) and either 0 <= A % B <= A or A <= A % B <= 0.
new_ub = rh_ub - 1;
class operator_logical_not : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &lh,
+ const value_range &rh) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_logical_not;
// Folding a logical NOT, oddly enough, involves doing nothing on the
// b_2 = x_1 < 20 [0,0] = x_1 < 20, false, so x_1 == [20, 255]
// which is the result we are looking for.. so.. pass it through.
-value_range_base
+value_range
operator_logical_not::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh ATTRIBUTE_UNUSED) const
+ const value_range &lh,
+ const value_range &rh ATTRIBUTE_UNUSED) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
}
bool
-operator_logical_not::op1_range (value_range_base &r,
+operator_logical_not::op1_range (value_range &r,
tree type ATTRIBUTE_UNUSED,
- const value_range_base &lhs,
- const value_range_base &op2 ATTRIBUTE_UNUSED) const
+ const value_range &lhs,
+ const value_range &op2 ATTRIBUTE_UNUSED) const
{
if (lhs.varying_p () || lhs.undefined_p ())
r = lhs;
class operator_bitwise_not : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &lh,
+ const value_range &rh) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_bitwise_not;
-value_range_base
+value_range
operator_bitwise_not::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
// ~X is simply -1 - X.
- value_range_base minusone (type,
- wi::minus_one (TYPE_PRECISION (type)),
- wi::minus_one (TYPE_PRECISION (type)));
+ value_range minusone (type, wi::minus_one (TYPE_PRECISION (type)),
+ wi::minus_one (TYPE_PRECISION (type)));
r = range_op_handler (MINUS_EXPR, type)->fold_range (type, minusone, lh);
return r;
}
bool
-operator_bitwise_not::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_bitwise_not::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
// ~X is -1 - X and since bitwise NOT is involutary...do it again.
r = fold_range (type, lhs, op2);
class operator_cst : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
} op_integer_cst;
-value_range_base
+value_range
operator_cst::fold_range (tree type ATTRIBUTE_UNUSED,
- const value_range_base &lh,
- const value_range_base &rh ATTRIBUTE_UNUSED) const
+ const value_range &lh,
+ const value_range &rh ATTRIBUTE_UNUSED) const
{
return lh;
}
class operator_identity : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_identity;
-value_range_base
+value_range
operator_identity::fold_range (tree type ATTRIBUTE_UNUSED,
- const value_range_base &lh,
- const value_range_base &rh ATTRIBUTE_UNUSED) const
+ const value_range &lh,
+ const value_range &rh ATTRIBUTE_UNUSED) const
{
return lh;
}
bool
-operator_identity::op1_range (value_range_base &r, tree type ATTRIBUTE_UNUSED,
- const value_range_base &lhs,
- const value_range_base &op2 ATTRIBUTE_UNUSED) const
+operator_identity::op1_range (value_range &r, tree type ATTRIBUTE_UNUSED,
+ const value_range &lhs,
+ const value_range &op2 ATTRIBUTE_UNUSED) const
{
r = lhs;
return true;
class operator_abs : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb,
- const wide_int &lh_ub,
- const wide_int &rh_lb,
- const wide_int &rh_ub) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_abs;
-value_range_base
+value_range
operator_abs::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb ATTRIBUTE_UNUSED,
// Pass through LH for the easy cases.
if (sign == UNSIGNED || wi::ge_p (lh_lb, 0, sign))
- return value_range_base (type, lh_lb, lh_ub);
+ return value_range (type, lh_lb, lh_ub);
// -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get
// a useful range.
wide_int min_value = wi::min_value (prec, sign);
wide_int max_value = wi::max_value (prec, sign);
if (!TYPE_OVERFLOW_UNDEFINED (type) && wi::eq_p (lh_lb, min_value))
- return value_range_base (type);
+ return value_range (type);
// ABS_EXPR may flip the range around, if the original range
// included negative values.
min = wi::zero (prec);
max = max_value;
}
- return value_range_base (type, min, max);
+ return value_range (type, min, max);
}
bool
-operator_abs::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_abs::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
if (empty_range_check (r, lhs, op2))
return true;
return true;
}
// Start with the positives because negatives are an impossible result.
- value_range_base positives = range_positives (type);
+ value_range positives = range_positives (type);
positives.intersect (lhs);
r = positives;
// Then add the negative of each pair:
// ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
for (unsigned i = 0; i < positives.num_pairs (); ++i)
- r.union_ (value_range_base (type,
- -positives.upper_bound (i),
- -positives.lower_bound (i)));
+ r.union_ (value_range (type,
+ -positives.upper_bound (i),
+ -positives.lower_bound (i)));
return true;
}
class operator_absu : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
+ virtual value_range wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
} op_absu;
-value_range_base
+value_range
operator_absu::wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb ATTRIBUTE_UNUSED,
}
gcc_checking_assert (TYPE_UNSIGNED (type));
- return value_range_base (type, new_lb, new_ub);
+ return value_range (type, new_lb, new_ub);
}
class operator_negate : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_negate;
-value_range_base
+value_range
operator_negate::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
// -X is simply 0 - X.
}
bool
-operator_negate::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_negate::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
// NEGATE is involutory.
r = fold_range (type, lhs, op2);
class operator_addr_expr : public range_operator
{
public:
- virtual value_range_base fold_range (tree type,
- const value_range_base &op1,
- const value_range_base &op2) const;
- virtual bool op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const;
+ virtual value_range fold_range (tree type,
+ const value_range &op1,
+ const value_range &op2) const;
+ virtual bool op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const;
} op_addr;
-value_range_base
+value_range
operator_addr_expr::fold_range (tree type,
- const value_range_base &lh,
- const value_range_base &rh) const
+ const value_range &lh,
+ const value_range &rh) const
{
- value_range_base r;
+ value_range r;
if (empty_range_check (r, lh, rh))
return r;
return range_zero (type);
if (!lh.contains_p (build_zero_cst (lh.type ())))
return range_nonzero (type);
- return value_range_base (type);
+ return value_range (type);
}
bool
-operator_addr_expr::op1_range (value_range_base &r, tree type,
- const value_range_base &lhs,
- const value_range_base &op2) const
+operator_addr_expr::op1_range (value_range &r, tree type,
+ const value_range &lhs,
+ const value_range &op2) const
{
r = operator_addr_expr::fold_range (type, lhs, op2);
return true;
class pointer_plus_operator : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
- const wide_int &lh_lb, const wide_int &lh_ub,
- const wide_int &rh_lb, const wide_int &rh_ub) const;
+ virtual value_range wi_fold (tree type,
+ const wide_int &lh_lb,
+ const wide_int &lh_ub,
+ const wide_int &rh_lb,
+ const wide_int &rh_ub) const;
} op_pointer_plus;
-value_range_base
+value_range
pointer_plus_operator::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
if (lh_lb == lh_ub && lh_lb == 0
&& rh_lb == rh_ub && rh_lb == 0)
return range_zero (type);
- return value_range_base (type);
+ return value_range (type);
}
class pointer_min_max_operator : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
+ virtual value_range wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
} op_ptr_min_max;
-value_range_base
+value_range
pointer_min_max_operator::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
return range_nonzero (type);
if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
return range_zero (type);
- return value_range_base (type);
+ return value_range (type);
}
class pointer_and_operator : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
+ virtual value_range wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
} op_pointer_and;
-value_range_base
+value_range
pointer_and_operator::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
if (wi_zero_p (type, lh_lb, lh_ub) || wi_zero_p (type, lh_lb, lh_ub))
return range_zero (type);
- return value_range_base (type);
+ return value_range (type);
}
class pointer_or_operator : public range_operator
{
public:
- virtual value_range_base wi_fold (tree type,
+ virtual value_range wi_fold (tree type,
const wide_int &lh_lb, const wide_int &lh_ub,
const wide_int &rh_lb, const wide_int &rh_ub) const;
} op_pointer_or;
-value_range_base
+value_range
pointer_or_operator::wi_fold (tree type,
const wide_int &lh_lb,
const wide_int &lh_ub,
return range_nonzero (type);
if (wi_zero_p (type, lh_lb, lh_ub) && wi_zero_p (type, rh_lb, rh_ub))
return range_zero (type);
- return value_range_base (type);
+ return value_range (type);
}
\f
// This implements the range operator tables as local objects in this file.
// Cast the range in R to TYPE.
void
-range_cast (value_range_base &r, tree type)
+range_cast (value_range &r, tree type)
{
range_operator *op = range_op_handler (CONVERT_EXPR, type);
- r = op->fold_range (type, r, value_range_base (type));
+ r = op->fold_range (type, r, value_range (type));
}
#if CHECKING_P
#include "stor-layout.h"
// Ideally this should go in namespace selftest, but range_tests
-// needs to be a friend of class value_range_base so it can access
-// value_range_base::m_max_pairs.
+// needs to be a friend of class value_range so it can access
+// value_range::m_max_pairs.
#define INT(N) build_int_cst (integer_type_node, (N))
#define UINT(N) build_int_cstu (unsigned_type_node, (N))
#define SCHAR(N) build_int_cst (signed_char_type_node, (N))
#define RANGE3(A,B,C,D,E,F) \
-( i1 = value_range_base (INT (A), INT (B)), \
- i2 = value_range_base (INT (C), INT (D)), \
- i3 = value_range_base (INT (E), INT (F)), \
+( i1 = value_range (INT (A), INT (B)), \
+ i2 = value_range (INT (C), INT (D)), \
+ i3 = value_range (INT (E), INT (F)), \
i1.union_ (i2), \
i1.union_ (i3), \
i1 )
range_tests ()
{
tree u128_type = build_nonstandard_integer_type (128, /*unsigned=*/1);
- value_range_base i1, i2, i3;
- value_range_base r0, r1, rold;
+ value_range i1, i2, i3;
+ value_range r0, r1, rold;
// Test that NOT(255) is [0..254] in 8-bit land.
- value_range_base not_255 (VR_ANTI_RANGE, UCHAR (255), UCHAR (255));
- ASSERT_TRUE (not_255 == value_range_base (UCHAR (0), UCHAR (254)));
+ value_range not_255 (VR_ANTI_RANGE, UCHAR (255), UCHAR (255));
+ ASSERT_TRUE (not_255 == value_range (UCHAR (0), UCHAR (254)));
// Test that NOT(0) is [1..255] in 8-bit land.
- value_range_base not_zero = range_nonzero (unsigned_char_type_node);
- ASSERT_TRUE (not_zero == value_range_base (UCHAR (1), UCHAR (255)));
+ value_range not_zero = range_nonzero (unsigned_char_type_node);
+ ASSERT_TRUE (not_zero == value_range (UCHAR (1), UCHAR (255)));
// Check that [0,127][0x..ffffff80,0x..ffffff]
// => ~[128, 0x..ffffff7f].
- r0 = value_range_base (UINT128 (0), UINT128 (127));
+ r0 = value_range (UINT128 (0), UINT128 (127));
tree high = build_minus_one_cst (u128_type);
// low = -1 - 127 => 0x..ffffff80.
tree low = fold_build2 (MINUS_EXPR, u128_type, high, UINT128(127));
- r1 = value_range_base (low, high); // [0x..ffffff80, 0x..ffffffff]
+ r1 = value_range (low, high); // [0x..ffffff80, 0x..ffffffff]
// r0 = [0,127][0x..ffffff80,0x..fffffff].
r0.union_ (r1);
// r1 = [128, 0x..ffffff7f].
- r1 = value_range_base (UINT128(128),
+ r1 = value_range (UINT128(128),
fold_build2 (MINUS_EXPR, u128_type,
build_minus_one_cst (u128_type),
UINT128(128)));
tree maxuint = wide_int_to_tree (unsigned_type_node, r0.upper_bound ());
// Check that ~[0,5] => [6,MAX] for unsigned int.
- r0 = value_range_base (UINT (0), UINT (5));
+ r0 = value_range (UINT (0), UINT (5));
r0.invert ();
- ASSERT_TRUE (r0 == value_range_base (UINT(6), maxuint));
+ ASSERT_TRUE (r0 == value_range (UINT(6), maxuint));
// Check that ~[10,MAX] => [0,9] for unsigned int.
- r0 = value_range_base (VR_RANGE, UINT(10), maxuint);
+ r0 = value_range (VR_RANGE, UINT(10), maxuint);
r0.invert ();
- ASSERT_TRUE (r0 == value_range_base (UINT (0), UINT (9)));
+ ASSERT_TRUE (r0 == value_range (UINT (0), UINT (9)));
// Check that ~[0,5] => [6,MAX] for unsigned 128-bit numbers.
- r0 = value_range_base (VR_ANTI_RANGE, UINT128 (0), UINT128 (5));
- r1 = value_range_base (UINT128(6), build_minus_one_cst (u128_type));
+ r0 = value_range (VR_ANTI_RANGE, UINT128 (0), UINT128 (5));
+ r1 = value_range (UINT128(6), build_minus_one_cst (u128_type));
ASSERT_TRUE (r0 == r1);
// Check that [~5] is really [-MIN,4][6,MAX].
- r0 = value_range_base (VR_ANTI_RANGE, INT (5), INT (5));
- r1 = value_range_base (minint, INT (4));
- r1.union_ (value_range_base (INT (6), maxint));
+ r0 = value_range (VR_ANTI_RANGE, INT (5), INT (5));
+ r1 = value_range (minint, INT (4));
+ r1.union_ (value_range (INT (6), maxint));
ASSERT_FALSE (r1.undefined_p ());
ASSERT_TRUE (r0 == r1);
- r1 = value_range_base (INT (5), INT (5));
+ r1 = value_range (INT (5), INT (5));
r1.check ();
- value_range_base r2 (r1);
+ value_range r2 (r1);
ASSERT_TRUE (r1 == r2);
- r1 = value_range_base (INT (5), INT (10));
+ r1 = value_range (INT (5), INT (10));
r1.check ();
- r1 = value_range_base (integer_type_node,
+ r1 = value_range (integer_type_node,
wi::to_wide (INT (5)), wi::to_wide (INT (10)));
r1.check ();
ASSERT_TRUE (r1.contains_p (INT (7)));
- r1 = value_range_base (SCHAR (0), SCHAR (20));
+ r1 = value_range (SCHAR (0), SCHAR (20));
ASSERT_TRUE (r1.contains_p (SCHAR(15)));
ASSERT_FALSE (r1.contains_p (SCHAR(300)));
if (TYPE_PRECISION (TREE_TYPE (maxint))
> TYPE_PRECISION (short_integer_type_node))
{
- r1 = value_range_base (integer_zero_node, maxint);
+ r1 = value_range (integer_zero_node, maxint);
range_cast (r1, short_integer_type_node);
ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort)
&& r1.upper_bound() == wi::to_wide (maxshort));
}
// (unsigned char)[-5,-1] => [251,255].
- r0 = rold = value_range_base (SCHAR (-5), SCHAR (-1));
+ r0 = rold = value_range (SCHAR (-5), SCHAR (-1));
range_cast (r0, unsigned_char_type_node);
- ASSERT_TRUE (r0 == value_range_base (UCHAR (251), UCHAR (255)));
+ ASSERT_TRUE (r0 == value_range (UCHAR (251), UCHAR (255)));
range_cast (r0, signed_char_type_node);
ASSERT_TRUE (r0 == rold);
// (signed char)[15, 150] => [-128,-106][15,127].
- r0 = rold = value_range_base (UCHAR (15), UCHAR (150));
+ r0 = rold = value_range (UCHAR (15), UCHAR (150));
range_cast (r0, signed_char_type_node);
- r1 = value_range_base (SCHAR (15), SCHAR (127));
- r2 = value_range_base (SCHAR (-128), SCHAR (-106));
+ r1 = value_range (SCHAR (15), SCHAR (127));
+ r2 = value_range (SCHAR (-128), SCHAR (-106));
r1.union_ (r2);
ASSERT_TRUE (r1 == r0);
range_cast (r0, unsigned_char_type_node);
ASSERT_TRUE (r0 == rold);
// (unsigned char)[-5, 5] => [0,5][251,255].
- r0 = rold = value_range_base (SCHAR (-5), SCHAR (5));
+ r0 = rold = value_range (SCHAR (-5), SCHAR (5));
range_cast (r0, unsigned_char_type_node);
- r1 = value_range_base (UCHAR (251), UCHAR (255));
- r2 = value_range_base (UCHAR (0), UCHAR (5));
+ r1 = value_range (UCHAR (251), UCHAR (255));
+ r2 = value_range (UCHAR (0), UCHAR (5));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
range_cast (r0, signed_char_type_node);
ASSERT_TRUE (r0 == rold);
// (unsigned char)[-5,5] => [0,5][251,255].
- r0 = value_range_base (INT (-5), INT (5));
+ r0 = value_range (INT (-5), INT (5));
range_cast (r0, unsigned_char_type_node);
- r1 = value_range_base (UCHAR (0), UCHAR (5));
- r1.union_ (value_range_base (UCHAR (251), UCHAR (255)));
+ r1 = value_range (UCHAR (0), UCHAR (5));
+ r1.union_ (value_range (UCHAR (251), UCHAR (255)));
ASSERT_TRUE (r0 == r1);
// (unsigned char)[5U,1974U] => [0,255].
- r0 = value_range_base (UINT (5), UINT (1974));
+ r0 = value_range (UINT (5), UINT (1974));
range_cast (r0, unsigned_char_type_node);
- ASSERT_TRUE (r0 == value_range_base (UCHAR (0), UCHAR (255)));
+ ASSERT_TRUE (r0 == value_range (UCHAR (0), UCHAR (255)));
range_cast (r0, integer_type_node);
// Going to a wider range should not sign extend.
- ASSERT_TRUE (r0 == value_range_base (INT (0), INT (255)));
+ ASSERT_TRUE (r0 == value_range (INT (0), INT (255)));
// (unsigned char)[-350,15] => [0,255].
- r0 = value_range_base (INT (-350), INT (15));
+ r0 = value_range (INT (-350), INT (15));
range_cast (r0, unsigned_char_type_node);
- ASSERT_TRUE (r0 == (value_range_base
+ ASSERT_TRUE (r0 == (value_range
(TYPE_MIN_VALUE (unsigned_char_type_node),
TYPE_MAX_VALUE (unsigned_char_type_node))));
// Casting [-120,20] from signed char to unsigned short.
// => [0, 20][0xff88, 0xffff].
- r0 = value_range_base (SCHAR (-120), SCHAR (20));
+ r0 = value_range (SCHAR (-120), SCHAR (20));
range_cast (r0, short_unsigned_type_node);
- r1 = value_range_base (UINT16 (0), UINT16 (20));
- r2 = value_range_base (UINT16 (0xff88), UINT16 (0xffff));
+ r1 = value_range (UINT16 (0), UINT16 (20));
+ r2 = value_range (UINT16 (0xff88), UINT16 (0xffff));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
// A truncating cast back to signed char will work because [-120, 20]
// is representable in signed char.
range_cast (r0, signed_char_type_node);
- ASSERT_TRUE (r0 == value_range_base (SCHAR (-120), SCHAR (20)));
+ ASSERT_TRUE (r0 == value_range (SCHAR (-120), SCHAR (20)));
// unsigned char -> signed short
// (signed short)[(unsigned char)25, (unsigned char)250]
// => [(signed short)25, (signed short)250]
- r0 = rold = value_range_base (UCHAR (25), UCHAR (250));
+ r0 = rold = value_range (UCHAR (25), UCHAR (250));
range_cast (r0, short_integer_type_node);
- r1 = value_range_base (INT16 (25), INT16 (250));
+ r1 = value_range (INT16 (25), INT16 (250));
ASSERT_TRUE (r0 == r1);
range_cast (r0, unsigned_char_type_node);
ASSERT_TRUE (r0 == rold);
// Test casting a wider signed [-MIN,MAX] to a nar`rower unsigned.
- r0 = value_range_base (TYPE_MIN_VALUE (long_long_integer_type_node),
+ r0 = value_range (TYPE_MIN_VALUE (long_long_integer_type_node),
TYPE_MAX_VALUE (long_long_integer_type_node));
range_cast (r0, short_unsigned_type_node);
- r1 = value_range_base (TYPE_MIN_VALUE (short_unsigned_type_node),
+ r1 = value_range (TYPE_MIN_VALUE (short_unsigned_type_node),
TYPE_MAX_VALUE (short_unsigned_type_node));
ASSERT_TRUE (r0 == r1);
// NOT([10,20]) ==> [-MIN,9][21,MAX].
- r0 = r1 = value_range_base (INT (10), INT (20));
- r2 = value_range_base (minint, INT(9));
- r2.union_ (value_range_base (INT(21), maxint));
+ r0 = r1 = value_range (INT (10), INT (20));
+ r2 = value_range (minint, INT(9));
+ r2.union_ (value_range (INT(21), maxint));
ASSERT_FALSE (r2.undefined_p ());
r1.invert ();
ASSERT_TRUE (r1 == r2);
// Test that booleans and their inverse work as expected.
r0 = range_zero (boolean_type_node);
- ASSERT_TRUE (r0 == value_range_base (build_zero_cst (boolean_type_node),
+ ASSERT_TRUE (r0 == value_range (build_zero_cst (boolean_type_node),
build_zero_cst (boolean_type_node)));
r0.invert ();
- ASSERT_TRUE (r0 == value_range_base (build_one_cst (boolean_type_node),
+ ASSERT_TRUE (r0 == value_range (build_one_cst (boolean_type_node),
build_one_cst (boolean_type_node)));
// Casting NONZERO to a narrower type will wrap/overflow so
{
r0 = range_nonzero (integer_type_node);
range_cast (r0, short_integer_type_node);
- r1 = value_range_base (TYPE_MIN_VALUE (short_integer_type_node),
+ r1 = value_range (TYPE_MIN_VALUE (short_integer_type_node),
TYPE_MAX_VALUE (short_integer_type_node));
ASSERT_TRUE (r0 == r1);
}
// Converting this to 32-bits signed is [-MIN_16,-1][1, +MAX_16].
r0 = range_nonzero (short_integer_type_node);
range_cast (r0, integer_type_node);
- r1 = value_range_base (INT (-32768), INT (-1));
- r2 = value_range_base (INT (1), INT (32767));
+ r1 = value_range (INT (-32768), INT (-1));
+ r2 = value_range (INT (1), INT (32767));
r1.union_ (r2);
ASSERT_TRUE (r0 == r1);
- if (value_range_base::m_max_pairs > 2)
+ if (value_range::m_max_pairs > 2)
{
// ([10,20] U [5,8]) U [1,3] ==> [1,3][5,8][10,20].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (5), INT (8));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (5), INT (8));
r0.union_ (r1);
- r1 = value_range_base (INT (1), INT (3));
+ r1 = value_range (INT (1), INT (3));
r0.union_ (r1);
ASSERT_TRUE (r0 == RANGE3 (1, 3, 5, 8, 10, 20));
// [1,3][5,8][10,20] U [-5,0] => [-5,3][5,8][10,20].
- r1 = value_range_base (INT (-5), INT (0));
+ r1 = value_range (INT (-5), INT (0));
r0.union_ (r1);
ASSERT_TRUE (r0 == RANGE3 (-5, 3, 5, 8, 10, 20));
}
// [10,20] U [30,40] ==> [10,20][30,40].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (30), INT (40));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (30), INT (40));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (30), INT (40))));
- if (value_range_base::m_max_pairs > 2)
+ ASSERT_TRUE (r0 == range_union (value_range (INT (10), INT (20)),
+ value_range (INT (30), INT (40))));
+ if (value_range::m_max_pairs > 2)
{
// [10,20][30,40] U [50,60] ==> [10,20][30,40][50,60].
- r1 = value_range_base (INT (50), INT (60));
+ r1 = value_range (INT (50), INT (60));
r0.union_ (r1);
ASSERT_TRUE (r0 == RANGE3 (10, 20, 30, 40, 50, 60));
// [10,20][30,40][50,60] U [70, 80] ==> [10,20][30,40][50,60][70,80].
- r1 = value_range_base (INT (70), INT (80));
+ r1 = value_range (INT (70), INT (80));
r0.union_ (r1);
r2 = RANGE3 (10, 20, 30, 40, 50, 60);
- r2.union_ (value_range_base (INT (70), INT (80)));
+ r2.union_ (value_range (INT (70), INT (80)));
ASSERT_TRUE (r0 == r2);
}
r0.invert ();
ASSERT_TRUE (r0 == r1);
- if (value_range_base::m_max_pairs > 2)
+ if (value_range::m_max_pairs > 2)
{
// [10,20][30,40][50,60] U [6,35] => [6,40][50,60].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (6), INT (35));
+ r1 = value_range (INT (6), INT (35));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (6), INT (40)),
- value_range_base (INT (50), INT (60))));
+ ASSERT_TRUE (r0 == range_union (value_range (INT (6), INT (40)),
+ value_range (INT (50), INT (60))));
// [10,20][30,40][50,60] U [6,60] => [6,60].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (6), INT (60));
+ r1 = value_range (INT (6), INT (60));
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (6), INT (60)));
+ ASSERT_TRUE (r0 == value_range (INT (6), INT (60)));
// [10,20][30,40][50,60] U [6,70] => [6,70].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (6), INT (70));
+ r1 = value_range (INT (6), INT (70));
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (6), INT (70)));
+ ASSERT_TRUE (r0 == value_range (INT (6), INT (70)));
// [10,20][30,40][50,60] U [35,70] => [10,20][30,70].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (35), INT (70));
+ r1 = value_range (INT (35), INT (70));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (30), INT (70))));
+ ASSERT_TRUE (r0 == range_union (value_range (INT (10), INT (20)),
+ value_range (INT (30), INT (70))));
}
// [10,20][30,40] U [25,70] => [10,70].
- r0 = range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (30), INT (40)));
- r1 = value_range_base (INT (25), INT (70));
+ r0 = range_union (value_range (INT (10), INT (20)),
+ value_range (INT (30), INT (40)));
+ r1 = value_range (INT (25), INT (70));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (25), INT (70))));
+ ASSERT_TRUE (r0 == range_union (value_range (INT (10), INT (20)),
+ value_range (INT (25), INT (70))));
- if (value_range_base::m_max_pairs > 2)
+ if (value_range::m_max_pairs > 2)
{
// [10,20][30,40][50,60] U [15,35] => [10,40][50,60].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (15), INT (35));
+ r1 = value_range (INT (15), INT (35));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (10), INT (40)),
- value_range_base (INT (50), INT (60))));
+ ASSERT_TRUE (r0 == range_union (value_range (INT (10), INT (40)),
+ value_range (INT (50), INT (60))));
}
// [10,20] U [15, 30] => [10, 30].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (15), INT (30));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (15), INT (30));
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (10), INT (30)));
+ ASSERT_TRUE (r0 == value_range (INT (10), INT (30)));
// [10,20] U [25,25] => [10,20][25,25].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (25), INT (25));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (25), INT (25));
r0.union_ (r1);
- ASSERT_TRUE (r0 == range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (25), INT (25))));
+ ASSERT_TRUE (r0 == range_union (value_range (INT (10), INT (20)),
+ value_range (INT (25), INT (25))));
- if (value_range_base::m_max_pairs > 2)
+ if (value_range::m_max_pairs > 2)
{
// [10,20][30,40][50,60] U [35,35] => [10,20][30,40][50,60].
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
- r1 = value_range_base (INT (35), INT (35));
+ r1 = value_range (INT (35), INT (35));
r0.union_ (r1);
ASSERT_TRUE (r0 == RANGE3 (10, 20, 30, 40, 50, 60));
}
// [15,40] U [] => [15,40].
- r0 = value_range_base (INT (15), INT (40));
+ r0 = value_range (INT (15), INT (40));
r1.set_undefined ();
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (15), INT (40)));
+ ASSERT_TRUE (r0 == value_range (INT (15), INT (40)));
// [10,20] U [10,10] => [10,20].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (10), INT (10));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (10), INT (10));
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (10), INT (20)));
+ ASSERT_TRUE (r0 == value_range (INT (10), INT (20)));
// [10,20] U [9,9] => [9,20].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (9), INT (9));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (9), INT (9));
r0.union_ (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (9), INT (20)));
+ ASSERT_TRUE (r0 == value_range (INT (9), INT (20)));
- if (value_range_base::m_max_pairs > 2)
+ if (value_range::m_max_pairs > 2)
{
// [10,10][12,12][20,100] ^ [15,200].
r0 = RANGE3 (10, 10, 12, 12, 20, 100);
- r1 = value_range_base (INT (15), INT (200));
+ r1 = value_range (INT (15), INT (200));
r0.intersect (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (20), INT (100)));
+ ASSERT_TRUE (r0 == value_range (INT (20), INT (100)));
// [10,20][30,40][50,60] ^ [15,25][38,51][55,70]
// => [15,20][38,40][50,51][55,60]
r0 = RANGE3 (10, 20, 30, 40, 50, 60);
r1 = RANGE3 (15, 25, 38, 51, 55, 70);
r0.intersect (r1);
- if (value_range_base::m_max_pairs == 3)
+ if (value_range::m_max_pairs == 3)
{
// When pairs==3, we don't have enough space, so
// conservatively handle things. Thus, the ...[50,60].
else
{
r2 = RANGE3 (15, 20, 38, 40, 50, 51);
- r2.union_ (value_range_base (INT (55), INT (60)));
+ r2.union_ (value_range (INT (55), INT (60)));
ASSERT_TRUE (r0 == r2);
}
r0 = RANGE3 (15, 20, 30, 40, 50, 60);
r1 = RANGE3 (15, 35, 40, 90, 100, 200);
r0.intersect (r1);
- if (value_range_base::m_max_pairs == 3)
+ if (value_range::m_max_pairs == 3)
{
// When pairs==3, we don't have enough space, so
// conservatively handle things.
else
{
r2 = RANGE3 (15, 20, 30, 35, 40, 40);
- r2.union_ (value_range_base (INT (50), INT (60)));
+ r2.union_ (value_range (INT (50), INT (60)));
ASSERT_TRUE (r0 == r2);
}
// range.
//
// [8,10][135,255] U [14,14] => [8,10][14,14][135,255]
- r0 = range_union (value_range_base (INT (8), INT (10)),
- value_range_base (INT (135), INT (255)));
- r1 = value_range_base (INT (14), INT (14));
+ r0 = range_union (value_range (INT (8), INT (10)),
+ value_range (INT (135), INT (255)));
+ r1 = value_range (INT (14), INT (14));
r0.union_ (r1);
ASSERT_TRUE (r0 == RANGE3 (8, 10, 14, 14, 135, 255));
}
// [10,20] ^ [15,30] => [15,20].
- r0 = value_range_base (INT (10), INT (20));
- r1 = value_range_base (INT (15), INT (30));
+ r0 = value_range (INT (10), INT (20));
+ r1 = value_range (INT (15), INT (30));
r0.intersect (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (15), INT (20)));
+ ASSERT_TRUE (r0 == value_range (INT (15), INT (20)));
// [10,20][30,40] ^ [40,50] => [40,40].
- r0 = range_union (value_range_base (INT (10), INT (20)),
- value_range_base (INT (30), INT (40)));
- r1 = value_range_base (INT (40), INT (50));
+ r0 = range_union (value_range (INT (10), INT (20)),
+ value_range (INT (30), INT (40)));
+ r1 = value_range (INT (40), INT (50));
r0.intersect (r1);
- ASSERT_TRUE (r0 == value_range_base (INT (40), INT (40)));
+ ASSERT_TRUE (r0 == value_range (INT (40), INT (40)));
// Test non-destructive intersection.
- r0 = rold = value_range_base (INT (10), INT (20));
- ASSERT_FALSE (range_intersect (r0, value_range_base (INT (15),
+ r0 = rold = value_range (INT (10), INT (20));
+ ASSERT_FALSE (range_intersect (r0, value_range (INT (15),
INT (30))).undefined_p ());
ASSERT_TRUE (r0 == rold);
== wi::uhwi (1, TYPE_PRECISION (boolean_type_node)));
// Test zero_p().
- r0 = value_range_base (INT (0), INT (0));
+ r0 = value_range (INT (0), INT (0));
ASSERT_TRUE (r0.zero_p ());
// Test nonzero_p().
- r0 = value_range_base (INT (0), INT (0));
+ r0 = value_range (INT (0), INT (0));
r0.invert ();
ASSERT_TRUE (r0.nonzero_p ());
}
#include "range-op.h"
static bool
-ranges_from_anti_range (const value_range_base *ar,
- value_range_base *vr0, value_range_base *vr1);
+ranges_from_anti_range (const value_range *ar,
+ value_range *vr0, value_range *vr1);
/* Set of SSA names found live during the RPO traversal of the function
for still active basic-blocks. */
static sbitmap *live;
void
-value_range::set_equiv (bitmap equiv)
+value_range_equiv::set_equiv (bitmap equiv)
{
if (undefined_p () || varying_p ())
equiv = NULL;
/* Initialize value_range. */
void
-value_range::set (enum value_range_kind kind, tree min, tree max,
- bitmap equiv)
+value_range_equiv::set (enum value_range_kind kind, tree min, tree max,
+ bitmap equiv)
{
- value_range_base::set (kind, min, max);
+ value_range::set (kind, min, max);
set_equiv (equiv);
if (flag_checking)
check ();
}
-value_range_base::value_range_base (value_range_kind kind, tree min, tree max)
+value_range::value_range (value_range_kind kind, tree min, tree max)
{
set (kind, min, max);
}
-value_range::value_range (value_range_kind kind, tree min, tree max,
- bitmap equiv)
+value_range_equiv::value_range_equiv (value_range_kind kind,
+ tree min, tree max, bitmap equiv)
{
m_equiv = NULL;
set (kind, min, max, equiv);
}
-value_range::value_range (const value_range_base &other)
+value_range_equiv::value_range_equiv (const value_range &other)
{
m_equiv = NULL;
set (other.kind (), other.min(), other.max (), NULL);
}
-value_range_base::value_range_base (tree type)
+value_range::value_range (tree type)
{
set_varying (type);
}
-value_range_base::value_range_base (enum value_range_kind kind,
+value_range::value_range (enum value_range_kind kind,
tree type,
const wide_int &wmin,
const wide_int &wmax)
set (kind, min, max);
}
-value_range_base::value_range_base (tree type,
+value_range::value_range (tree type,
const wide_int &wmin,
const wide_int &wmax)
{
set (VR_RANGE, min, max);
}
-value_range_base::value_range_base (tree min, tree max)
+value_range::value_range (tree min, tree max)
{
set (VR_RANGE, min, max);
}
/* Like set, but keep the equivalences in place. */
void
-value_range::update (value_range_kind kind, tree min, tree max)
+value_range_equiv::update (value_range_kind kind, tree min, tree max)
{
set (kind, min, max,
(kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL);
object. Use the constructors for initialization. */
void
-value_range::deep_copy (const value_range *from)
+value_range_equiv::deep_copy (const value_range_equiv *from)
{
set (from->m_kind, from->min (), from->max (), from->m_equiv);
}
void
-value_range::move (value_range *from)
+value_range_equiv::move (value_range_equiv *from)
{
set (from->m_kind, from->min (), from->max ());
m_equiv = from->m_equiv;
/* Check the validity of the range. */
void
-value_range_base::check ()
+value_range::check ()
{
switch (m_kind)
{
}
void
-value_range::check ()
+value_range_equiv::check ()
{
- value_range_base::check ();
+ value_range::check ();
switch (m_kind)
{
case VR_UNDEFINED:
class. */
bool
-value_range_base::equal_p (const value_range_base &other) const
+value_range::equal_p (const value_range &other) const
{
/* Ignore types for undefined. All undefines are equal. */
if (undefined_p ())
IGNORE_EQUIVS is TRUE. */
bool
-value_range::equal_p (const value_range &other, bool ignore_equivs) const
+value_range_equiv::equal_p (const value_range_equiv &other,
+ bool ignore_equivs) const
{
- return (value_range_base::equal_p (other)
+ return (value_range::equal_p (other)
&& (ignore_equivs
|| vrp_bitmap_equal_p (m_equiv, other.m_equiv)));
}
/* Return TRUE if this is a symbolic range. */
bool
-value_range_base::symbolic_p () const
+value_range::symbolic_p () const
{
return (!varying_p ()
&& !undefined_p ()
constants would be represented as [-MIN, +MAX]. */
bool
-value_range_base::constant_p () const
+value_range::constant_p () const
{
return (!varying_p ()
&& !undefined_p ()
}
void
-value_range_base::set_undefined ()
+value_range::set_undefined ()
{
m_kind = VR_UNDEFINED;
m_min = m_max = NULL;
}
void
-value_range::set_undefined ()
+value_range_equiv::set_undefined ()
{
set (VR_UNDEFINED, NULL, NULL, NULL);
}
void
-value_range_base::set_varying (tree type)
+value_range::set_varying (tree type)
{
m_kind = VR_VARYING;
if (supports_type_p (type))
}
void
-value_range::set_varying (tree type)
+value_range_equiv::set_varying (tree type)
{
- value_range_base::set_varying (type);
+ value_range::set_varying (type);
equiv_clear ();
}
/* Return TRUE if it is possible that range contains VAL. */
bool
-value_range_base::may_contain_p (tree val) const
+value_range::may_contain_p (tree val) const
{
return value_inside_range (val) != 0;
}
void
-value_range::equiv_clear ()
+value_range_equiv::equiv_clear ()
{
if (m_equiv)
bitmap_clear (m_equiv);
turned on/off. */
void
-value_range::equiv_add (const_tree var,
- const value_range *var_vr,
- bitmap_obstack *obstack)
+value_range_equiv::equiv_add (const_tree var,
+ const value_range_equiv *var_vr,
+ bitmap_obstack *obstack)
{
if (!m_equiv)
m_equiv = BITMAP_ALLOC (obstack);
So, [&x, &x] counts as a singleton. */
bool
-value_range_base::singleton_p (tree *result) const
+value_range::singleton_p (tree *result) const
{
if (m_kind == VR_ANTI_RANGE)
{
}
if (num_pairs () == 1)
{
- value_range_base vr0, vr1;
+ value_range vr0, vr1;
ranges_from_anti_range (this, &vr0, &vr1);
return vr0.singleton_p (result);
}
}
tree
-value_range_base::type () const
+value_range::type () const
{
gcc_checking_assert (m_min);
return TREE_TYPE (min ());
}
void
-value_range_base::dump (FILE *file) const
+value_range::dump (FILE *file) const
{
if (undefined_p ())
fprintf (file, "UNDEFINED");
}
void
-value_range_base::dump () const
+value_range::dump () const
{
dump (stderr);
}
void
-value_range::dump (FILE *file) const
+value_range_equiv::dump (FILE *file) const
{
- value_range_base::dump (file);
+ value_range::dump (file);
if ((m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
&& m_equiv)
{
}
void
-value_range::dump () const
+value_range_equiv::dump () const
{
dump (stderr);
}
void
-dump_value_range (FILE *file, const value_range *vr)
+dump_value_range (FILE *file, const value_range_equiv *vr)
{
if (!vr)
fprintf (file, "[]");
}
void
-dump_value_range (FILE *file, const value_range_base *vr)
+dump_value_range (FILE *file, const value_range *vr)
{
if (!vr)
fprintf (file, "[]");
}
DEBUG_FUNCTION void
-debug (const value_range_base *vr)
+debug (const value_range *vr)
{
dump_value_range (stderr, vr);
}
DEBUG_FUNCTION void
-debug (const value_range_base &vr)
+debug (const value_range &vr)
{
dump_value_range (stderr, &vr);
}
DEBUG_FUNCTION void
-debug (const value_range *vr)
+debug (const value_range_equiv *vr)
{
dump_value_range (stderr, vr);
}
DEBUG_FUNCTION void
-debug (const value_range &vr)
+debug (const value_range_equiv &vr)
{
dump_value_range (stderr, &vr);
}
extract ranges from var + CST op limit. */
void
-value_range_base::set (enum value_range_kind kind, tree min, tree max)
+value_range::set (enum value_range_kind kind, tree min, tree max)
{
/* Use the canonical setters for VR_UNDEFINED and VR_VARYING. */
if (kind == VR_UNDEFINED)
}
void
-value_range_base::set (tree val)
+value_range::set (tree val)
{
gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
if (TREE_OVERFLOW_P (val))
}
void
-value_range::set (tree val)
+value_range_equiv::set (tree val)
{
gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
if (TREE_OVERFLOW_P (val))
/* Set value range VR to a nonzero range of type TYPE. */
void
-value_range_base::set_nonzero (tree type)
+value_range::set_nonzero (tree type)
{
tree zero = build_int_cst (type, 0);
set (VR_ANTI_RANGE, zero, zero);
/* Set value range VR to a ZERO range of type TYPE. */
void
-value_range_base::set_zero (tree type)
+value_range::set_zero (tree type)
{
set (build_int_cst (type, 0));
}
}
static bool
-range_has_numeric_bounds_p (const value_range_base *vr)
+range_has_numeric_bounds_p (const value_range *vr)
{
return (vr->min ()
&& TREE_CODE (vr->min ()) == INTEGER_CST
a singleton. */
bool
-range_int_cst_p (const value_range_base *vr)
+range_int_cst_p (const value_range *vr)
{
return (vr->kind () == VR_RANGE && range_has_numeric_bounds_p (vr));
}
function. */
int
-value_range_base::value_inside_range (tree val) const
+value_range::value_inside_range (tree val) const
{
int cmp1, cmp2;
*VR1 will be VR_UNDEFINED. */
static bool
-ranges_from_anti_range (const value_range_base *ar,
- value_range_base *vr0, value_range_base *vr1)
+ranges_from_anti_range (const value_range *ar,
+ value_range *vr0, value_range *vr1)
{
tree type = ar->type ();
/* Fold two value range's of a POINTER_PLUS_EXPR into VR. */
static void
-extract_range_from_pointer_plus_expr (value_range_base *vr,
+extract_range_from_pointer_plus_expr (value_range *vr,
enum tree_code code,
tree expr_type,
- const value_range_base *vr0,
- const value_range_base *vr1)
+ const value_range *vr0,
+ const value_range *vr1)
{
gcc_checking_assert (POINTER_TYPE_P (expr_type)
&& code == POINTER_PLUS_EXPR);
result in *VR. */
static void
-extract_range_from_plus_minus_expr (value_range_base *vr,
+extract_range_from_plus_minus_expr (value_range *vr,
enum tree_code code,
tree expr_type,
- const value_range_base *vr0_,
- const value_range_base *vr1_)
+ const value_range *vr0_,
+ const value_range *vr1_)
{
gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR);
- value_range_base vr0 = *vr0_, vr1 = *vr1_;
- value_range_base vrtem0, vrtem1;
+ value_range vr0 = *vr0_, vr1 = *vr1_;
+ value_range vrtem0, vrtem1;
/* Now canonicalize anti-ranges to ranges when they are not symbolic
and express ~[] op X as ([]' op X) U ([]'' op X). */
extract_range_from_plus_minus_expr (vr, code, expr_type, &vrtem0, vr1_);
if (!vrtem1.undefined_p ())
{
- value_range_base vrres;
+ value_range vrres;
extract_range_from_plus_minus_expr (&vrres, code, expr_type,
&vrtem1, vr1_);
vr->union_ (&vrres);
extract_range_from_plus_minus_expr (vr, code, expr_type, vr0_, &vrtem0);
if (!vrtem1.undefined_p ())
{
- value_range_base vrres;
+ value_range vrres;
extract_range_from_plus_minus_expr (&vrres, code, expr_type,
vr0_, &vrtem1);
vr->union_ (&vrres);
suitable operator is found, return NULL and set VR to VARYING. */
static const range_operator *
-get_range_op_handler (value_range_base *vr,
+get_range_op_handler (value_range *vr,
enum tree_code code,
tree expr_type)
{
VARYING and return FALSE. */
static bool
-supported_types_p (value_range_base *vr,
+supported_types_p (value_range *vr,
tree type0,
tree type1 = NULL)
{
- if (!value_range_base::supports_type_p (type0)
- || (type1 && !value_range_base::supports_type_p (type1)))
+ if (!value_range::supports_type_p (type0)
+ || (type1 && !value_range::supports_type_p (type1)))
{
vr->set_varying (type0);
return false;
VR to UNDEFINED and return FALSE. */
static bool
-defined_ranges_p (value_range_base *vr,
- const value_range_base *vr0,
- const value_range_base *vr1 = NULL)
+defined_ranges_p (value_range *vr,
+ const value_range *vr0,
+ const value_range *vr1 = NULL)
{
if (vr0->undefined_p () && (!vr1 || vr1->undefined_p ()))
{
return true;
}
-static value_range_base
-drop_undefines_to_varying (const value_range_base *vr, tree expr_type)
+static value_range
+drop_undefines_to_varying (const value_range *vr, tree expr_type)
{
if (vr->undefined_p ())
- return value_range_base (expr_type);
+ return value_range (expr_type);
else
return *vr;
}
return TRUE, otherwise return FALSE. */
static bool
-range_fold_binary_symbolics_p (value_range_base *vr,
+range_fold_binary_symbolics_p (value_range *vr,
tree_code code,
tree expr_type,
- const value_range_base *vr0,
- const value_range_base *vr1)
+ const value_range *vr0,
+ const value_range *vr1)
{
if (vr0->symbolic_p () || vr1->symbolic_p ())
{
TRUE, otherwise return FALSE. */
static bool
-range_fold_unary_symbolics_p (value_range_base *vr,
+range_fold_unary_symbolics_p (value_range *vr,
tree_code code,
tree expr_type,
- const value_range_base *vr0)
+ const value_range *vr0)
{
if (vr0->symbolic_p ())
{
if (code == NEGATE_EXPR)
{
/* -X is simply 0 - X. */
- value_range_base zero;
+ value_range zero;
zero.set_zero (vr0->type ());
range_fold_binary_expr (vr, MINUS_EXPR, expr_type, &zero, vr0);
return true;
if (code == BIT_NOT_EXPR)
{
/* ~X is simply -1 - X. */
- value_range_base minusone;
+ value_range minusone;
minusone.set (build_int_cst (vr0->type (), -1));
range_fold_binary_expr (vr, MINUS_EXPR, expr_type, &minusone, vr0);
return true;
const range_operator *op = get_range_op_handler (vr, code, expr_type);
*vr = op->fold_range (expr_type,
vr0->normalize_symbolics (),
- value_range_base (expr_type));
+ value_range (expr_type));
return true;
}
return false;
/* Perform a binary operation on a pair of ranges. */
void
-range_fold_binary_expr (value_range_base *vr,
+range_fold_binary_expr (value_range *vr,
enum tree_code code,
tree expr_type,
- const value_range_base *vr0_,
- const value_range_base *vr1_)
+ const value_range *vr0_,
+ const value_range *vr1_)
{
if (!supported_types_p (vr, expr_type)
|| !defined_ranges_p (vr, vr0_, vr1_))
if (!op)
return;
- value_range_base vr0 = drop_undefines_to_varying (vr0_, expr_type);
- value_range_base vr1 = drop_undefines_to_varying (vr1_, expr_type);
+ value_range vr0 = drop_undefines_to_varying (vr0_, expr_type);
+ value_range vr1 = drop_undefines_to_varying (vr1_, expr_type);
if (range_fold_binary_symbolics_p (vr, code, expr_type, &vr0, &vr1))
return;
/* Perform a unary operation on a range. */
void
-range_fold_unary_expr (value_range_base *vr,
+range_fold_unary_expr (value_range *vr,
enum tree_code code, tree expr_type,
- const value_range_base *vr0,
+ const value_range *vr0,
tree vr0_type)
{
if (!supported_types_p (vr, expr_type, vr0_type)
*vr = op->fold_range (expr_type,
vr0->normalize_addresses (),
- value_range_base (expr_type));
+ value_range (expr_type));
}
/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
class vr_values vr_values;
/* Temporary delegator to minimize code churn. */
- const value_range *get_value_range (const_tree op)
+ const value_range_equiv *get_value_range (const_tree op)
{ return vr_values.get_value_range (op); }
void set_def_to_varying (const_tree def)
{ vr_values.set_def_to_varying (def); }
void set_defs_to_varying (gimple *stmt)
{ vr_values.set_defs_to_varying (stmt); }
void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
- tree *output_p, value_range *vr)
+ tree *output_p, value_range_equiv *vr)
{ vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
- bool update_value_range (const_tree op, value_range *vr)
+ bool update_value_range (const_tree op, value_range_equiv *vr)
{ return vr_values.update_value_range (op, vr); }
- void extract_range_basic (value_range *vr, gimple *stmt)
+ void extract_range_basic (value_range_equiv *vr, gimple *stmt)
{ vr_values.extract_range_basic (vr, stmt); }
- void extract_range_from_phi_node (gphi *phi, value_range *vr)
+ void extract_range_from_phi_node (gphi *phi, value_range_equiv *vr)
{ vr_values.extract_range_from_phi_node (phi, vr); }
};
/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
"array subscript %E is above array bounds of %qT",
low_bound, artype);
- const value_range *vr = NULL;
+ const value_range_equiv *vr = NULL;
if (TREE_CODE (low_sub) == SSA_NAME)
{
vr = get_value_range (low_sub);
/* The range of the byte offset into the reference. */
offset_int offrange[2] = { 0, 0 };
- const value_range *vr = NULL;
+ const value_range_equiv *vr = NULL;
/* Determine the offsets and increment OFFRANGE for the bounds of each.
The loop computes the range of the final offset for expressions such
vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
{
tree lhs = gimple_get_lhs (stmt);
- value_range vr;
+ value_range_equiv vr;
extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
if (*output_p)
SSA_PROP_NOT_INTERESTING. If there are no
{REAL,IMAG}PART_EXPR uses at all,
return SSA_PROP_VARYING. */
- value_range new_vr;
+ value_range_equiv new_vr;
extract_range_basic (&new_vr, use_stmt);
- const value_range *old_vr = get_value_range (use_lhs);
+ const value_range_equiv *old_vr = get_value_range (use_lhs);
if (!old_vr->equal_p (new_vr, /*ignore_equivs=*/false))
res = SSA_PROP_INTERESTING;
else
value ranges VR0 and VR1, return the intersection of the two
ranges. This may not be the smallest possible such range. */
-value_range_base
-value_range_base::intersect_helper (const value_range_base *vr0,
- const value_range_base *vr1)
+value_range
+value_range::intersect_helper (const value_range *vr0,
+ const value_range *vr1)
{
/* If either range is VR_VARYING the other one wins. */
if (vr1->varying_p ())
/* Make sure to canonicalize the result though as the inversion of a
VR_RANGE can still be a VR_RANGE. Work on a temporary so we can
fall back to vr0 when this turns things to varying. */
- value_range_base tem;
+ value_range tem;
if (vr0type == VR_UNDEFINED)
tem.set_undefined ();
else if (vr0type == VR_VARYING)
}
void
-value_range_base::intersect (const value_range_base *other)
+value_range::intersect (const value_range *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
}
void
-value_range::intersect (const value_range *other)
+value_range_equiv::intersect (const value_range_equiv *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
this->deep_copy (other);
else
{
- value_range_base tem = intersect_helper (this, other);
+ value_range tem = intersect_helper (this, other);
this->update (tem.kind (), tem.min (), tem.max ());
/* If the result is VR_UNDEFINED there is no need to mess with
VR1, return a range that contains both VR0 and VR1. This may not be the
smallest possible such range. */
-value_range_base
-value_range_base::union_helper (const value_range_base *vr0,
- const value_range_base *vr1)
+value_range
+value_range::union_helper (const value_range *vr0,
+ const value_range *vr1)
{
/* VR0 has the resulting range if VR1 is undefined or VR0 is varying. */
if (vr1->undefined_p ()
vr1->kind (), vr1->min (), vr1->max ());
/* Work on a temporary so we can still use vr0 when union returns varying. */
- value_range_base tem;
+ value_range tem;
if (vr0type == VR_UNDEFINED)
tem.set_undefined ();
else if (vr0type == VR_VARYING)
may not be the smallest possible such range. */
void
-value_range_base::union_ (const value_range_base *other)
+value_range::union_ (const value_range *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
}
void
-value_range::union_ (const value_range *other)
+value_range_equiv::union_ (const value_range_equiv *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
this->deep_copy (other);
else
{
- value_range_base tem = union_helper (this, other);
+ value_range tem = union_helper (this, other);
this->update (tem.kind (), tem.min (), tem.max ());
/* The resulting set of equivalences is always the intersection of
/* Normalize addresses into constants. */
-value_range_base
-value_range_base::normalize_addresses () const
+value_range
+value_range::normalize_addresses () const
{
if (undefined_p ())
return *this;
|| TREE_CODE (m_max) == ADDR_EXPR);
return range_nonzero (type ());
}
- return value_range_base (type ());
+ return value_range (type ());
}
/* Normalize symbolics and addresses into constants. */
-value_range_base
-value_range_base::normalize_symbolics () const
+value_range
+value_range::normalize_symbolics () const
{
if (varying_p () || undefined_p ())
return *this;
// [SYM, SYM] -> VARYING
if (min_symbolic && max_symbolic)
{
- value_range_base var;
+ value_range var;
var.set_varying (ttype);
return var;
}
{
// [SYM, NUM] -> [-MIN, NUM]
if (min_symbolic)
- return value_range_base (VR_RANGE, vrp_val_min (ttype), max ());
+ return value_range (VR_RANGE, vrp_val_min (ttype), max ());
// [NUM, SYM] -> [NUM, +MAX]
- return value_range_base (VR_RANGE, min (), vrp_val_max (ttype));
+ return value_range (VR_RANGE, min (), vrp_val_max (ttype));
}
gcc_checking_assert (kind () == VR_ANTI_RANGE);
// ~[SYM, NUM] -> [NUM + 1, +MAX]
if (!vrp_val_is_max (max ()))
{
tree n = wide_int_to_tree (ttype, wi::to_wide (max ()) + 1);
- return value_range_base (VR_RANGE, n, vrp_val_max (ttype));
+ return value_range (VR_RANGE, n, vrp_val_max (ttype));
}
- value_range_base var;
+ value_range var;
var.set_varying (ttype);
return var;
}
if (!vrp_val_is_min (min ()))
{
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 (VR_RANGE, vrp_val_min (ttype), n);
}
- value_range_base var;
+ value_range var;
var.set_varying (ttype);
return var;
}
/* Return the number of sub-ranges in a range. */
unsigned
-value_range_base::num_pairs () const
+value_range::num_pairs () const
{
if (undefined_p ())
return 0;
question. */
wide_int
-value_range_base::lower_bound (unsigned pair) const
+value_range::lower_bound (unsigned pair) const
{
if (symbolic_p ())
return normalize_symbolics ().lower_bound (pair);
question. */
wide_int
-value_range_base::upper_bound (unsigned pair) const
+value_range::upper_bound (unsigned pair) const
{
if (symbolic_p ())
return normalize_symbolics ().upper_bound (pair);
/* Return the highest bound in a range. */
wide_int
-value_range_base::upper_bound () const
+value_range::upper_bound () const
{
unsigned pairs = num_pairs ();
gcc_checking_assert (pairs > 0);
/* Return TRUE if range contains INTEGER_CST. */
bool
-value_range_base::contains_p (tree cst) const
+value_range::contains_p (tree cst) const
{
gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST);
if (symbolic_p ())
/* Return the inverse of a range. */
void
-value_range_base::invert ()
+value_range::invert ()
{
/* We can't just invert VR_RANGE and VR_ANTI_RANGE because we may
create non-canonical ranges. Use the constructors instead. */
if (m_kind == VR_RANGE)
- *this = value_range_base (VR_ANTI_RANGE, m_min, m_max);
+ *this = value_range (VR_ANTI_RANGE, m_min, m_max);
else if (m_kind == VR_ANTI_RANGE)
- *this = value_range_base (VR_RANGE, m_min, m_max);
+ *this = value_range (VR_RANGE, m_min, m_max);
else
gcc_unreachable ();
}
/* Range union, but for references. */
void
-value_range_base::union_ (const value_range_base &r)
+value_range::union_ (const value_range &r)
{
/* Disable details for now, because it makes the ranger dump
unnecessarily verbose. */
/* Range intersect, but for references. */
void
-value_range_base::intersect (const value_range_base &r)
+value_range::intersect (const value_range &r)
{
/* Disable details for now, because it makes the ranger dump
unnecessarily verbose. */
}
bool
-value_range_base::operator== (const value_range_base &r) const
+value_range::operator== (const value_range &r) const
{
return equal_p (r);
}
vrp_prop::visit_phi (gphi *phi)
{
tree lhs = PHI_RESULT (phi);
- value_range vr_result;
+ value_range_equiv vr_result;
extract_range_from_phi_node (phi, &vr_result);
if (update_value_range (lhs, &vr_result))
{
op = lhs_of_dominating_assert (op, bb, stmt);
- const value_range *vr = vr_values->get_value_range (op);
+ const value_range_equiv *vr = vr_values->get_value_range (op);
if (vr->undefined_p ()
|| vr->varying_p ()
|| vr->symbolic_p ())
{
edge dummy_e;
tree dummy_tree;
- value_range new_vr;
+ value_range_equiv new_vr;
vr_values->extract_range_from_stmt (stmt, &dummy_e,
&dummy_tree, &new_vr);
tree singleton;
if (!name)
continue;
- const value_range *vr = get_value_range (name);
+ const value_range_equiv *vr = get_value_range (name);
if (!name || !vr->constant_p ())
continue;
/* Worker for determine_value_range. */
static void
-determine_value_range_1 (value_range_base *vr, tree expr)
+determine_value_range_1 (value_range *vr, tree expr)
{
if (BINARY_CLASS_P (expr))
{
- value_range_base vr0, vr1;
+ value_range vr0, vr1;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
range_fold_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
}
else if (UNARY_CLASS_P (expr))
{
- value_range_base vr0;
+ value_range vr0;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
range_fold_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
&vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
value_range_kind
determine_value_range (tree expr, wide_int *min, wide_int *max)
{
- value_range_base vr;
+ value_range vr;
determine_value_range_1 (&vr, expr);
if (vr.constant_p ())
{
/* Set value range VR to a non-negative range of type TYPE. */
static inline void
-set_value_range_to_nonnegative (value_range *vr, tree type)
+set_value_range_to_nonnegative (value_range_equiv *vr, tree type)
{
tree zero = build_int_cst (type, 0);
vr->update (VR_RANGE, zero, vrp_val_max (type));
/* Set value range VR to a range of a truthvalue of type TYPE. */
static inline void
-set_value_range_to_truthvalue (value_range *vr, tree type)
+set_value_range_to_truthvalue (value_range_equiv *vr, tree type)
{
if (TYPE_PRECISION (type) == 1)
vr->set_varying (type);
/* Return the lattice entry for VAR or NULL if it doesn't exist or cannot
be initialized. */
-value_range *
+value_range_equiv *
vr_values::get_lattice_entry (const_tree var)
{
- value_range *vr;
+ value_range_equiv *vr;
tree sym;
unsigned ver = SSA_NAME_VERSION (var);
If we have no values ranges recorded (ie, VRP is not running), then
return NULL. Otherwise create an empty range if none existed for VAR. */
-const value_range *
+const value_range_equiv *
vr_values::get_value_range (const_tree var)
{
/* If we have no recorded ranges, then return NULL. */
if (!vr_value)
return NULL;
- value_range *vr = get_lattice_entry (var);
+ value_range_equiv *vr = get_lattice_entry (var);
/* Reallocate the lattice if needed. */
if (!vr)
{
unsigned int old_sz = num_vr_values;
num_vr_values = num_ssa_names + num_ssa_names / 10;
- vr_value = XRESIZEVEC (value_range *, vr_value, num_vr_values);
+ vr_value = XRESIZEVEC (value_range_equiv *, vr_value, num_vr_values);
for ( ; old_sz < num_vr_values; old_sz++)
vr_value [old_sz] = NULL;
void
vr_values::set_def_to_varying (const_tree def)
{
- value_range *vr = get_lattice_entry (def);
+ value_range_equiv *vr = get_lattice_entry (def);
if (vr)
vr->set_varying (TREE_TYPE (def));
}
is the range object associated with another SSA name. */
bool
-vr_values::update_value_range (const_tree var, value_range *new_vr)
+vr_values::update_value_range (const_tree var, value_range_equiv *new_vr)
{
- value_range *old_vr;
+ value_range_equiv *old_vr;
bool is_new;
/* If there is a value-range on the SSA name from earlier analysis
factor that in. */
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
{
- value_range nr;
- value_range_kind rtype = get_range_info (var, nr);
- if (rtype == VR_RANGE || rtype == VR_ANTI_RANGE)
+ value_range_equiv nr;
+ get_range_info (var, nr);
+ if (!nr.undefined_p ())
new_vr->intersect (&nr);
}
/* Return true if value range VR involves exactly one symbol SYM. */
static bool
-symbolic_range_based_on_p (value_range_base *vr, const_tree sym)
+symbolic_range_based_on_p (value_range *vr, const_tree sym)
{
bool neg, min_has_symbol, max_has_symbol;
tree inv;
|| (flag_delete_null_pointer_checks
&& !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))))
{
- const value_range *vr = get_value_range (TREE_OPERAND (base, 0));
+ const value_range_equiv *vr
+ = get_value_range (TREE_OPERAND (base, 0));
if (!range_includes_zero_p (vr))
return true;
}
bool
vr_values::op_with_boolean_value_range_p (tree op)
{
- const value_range *vr;
+ const value_range_equiv *vr;
if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
return true;
vr_values::extract_range_for_var_from_comparison_expr (tree var,
enum tree_code cond_code,
tree op, tree limit,
- value_range *vr_p)
+ value_range_equiv *vr_p)
{
tree min, max, type;
- const value_range *limit_vr;
+ const value_range_equiv *limit_vr;
type = TREE_TYPE (var);
/* For pointer arithmetic, we only keep track of pointer equality
vice-versa. Use set_and_canonicalize which does this for
us. */
if (cond_code == LE_EXPR)
- vr_p->set (VR_RANGE, min, max, vr_p->equiv ());
+ vr_p->set (VR_RANGE, min, max, vr_p->equiv ());
else if (cond_code == GT_EXPR)
vr_p->set (VR_ANTI_RANGE, min, max, vr_p->equiv ());
else
it in *VR_P. */
void
-vr_values::extract_range_from_assert (value_range *vr_p, tree expr)
+vr_values::extract_range_from_assert (value_range_equiv *vr_p, tree expr)
{
tree var = ASSERT_EXPR_VAR (expr);
tree cond = ASSERT_EXPR_COND (expr);
always false. */
void
-vr_values::extract_range_from_ssa_name (value_range *vr, tree var)
+vr_values::extract_range_from_ssa_name (value_range_equiv *vr, tree var)
{
- const value_range *var_vr = get_value_range (var);
+ const value_range_equiv *var_vr = get_value_range (var);
if (!var_vr->varying_p ())
vr->deep_copy (var_vr);
The resulting range is stored in *VR. */
void
-vr_values::extract_range_from_binary_expr (value_range *vr,
+vr_values::extract_range_from_binary_expr (value_range_equiv *vr,
enum tree_code code,
tree expr_type, tree op0, tree op1)
{
/* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */
- value_range_base vr0, vr1;
+ value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
&& TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
{
if (vr0.varying_p () && !vr1.varying_p ())
- vr0 = value_range (VR_RANGE,
- vrp_val_min (expr_type),
- vrp_val_max (expr_type));
+ vr0 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
else if (vr1.varying_p () && !vr0.varying_p ())
- vr1 = value_range (VR_RANGE,
- vrp_val_min (expr_type),
- vrp_val_max (expr_type));
+ vr1 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
}
range_fold_binary_expr (vr, code, expr_type, &vr0, &vr1);
The resulting range is stored in *VR. */
void
-vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
+vr_values::extract_range_from_unary_expr (value_range_equiv *vr,
+ enum tree_code code,
tree type, tree op0)
{
- value_range_base vr0;
+ value_range vr0;
/* Get value ranges for the operand. For constant operands, create
a new value range with the operand to simplify processing. */
the ranges of each of its operands and the expression code. */
void
-vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
+vr_values::extract_range_from_cond_expr (value_range_equiv *vr, gassign *stmt)
{
/* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */
tree op0 = gimple_assign_rhs2 (stmt);
- value_range tem0;
- const value_range *vr0 = &tem0;
+ value_range_equiv tem0;
+ const value_range_equiv *vr0 = &tem0;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = get_value_range (op0);
else if (is_gimple_min_invariant (op0))
tem0.set_varying (TREE_TYPE (op0));
tree op1 = gimple_assign_rhs3 (stmt);
- value_range tem1;
- const value_range *vr1 = &tem1;
+ value_range_equiv tem1;
+ const value_range_equiv *vr1 = &tem1;
if (TREE_CODE (op1) == SSA_NAME)
vr1 = get_value_range (op1);
else if (is_gimple_min_invariant (op1))
on the range of its operand and the expression code. */
void
-vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code,
+vr_values::extract_range_from_comparison (value_range_equiv *vr,
+ enum tree_code code,
tree type, tree op0, tree op1)
{
bool sop;
vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
tree op0, tree op1, bool *ovf)
{
- value_range_base vr0, vr1;
+ value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *get_value_range (op0);
else if (TREE_CODE (op0) == INTEGER_CST)
Store the result in *VR */
void
-vr_values::extract_range_basic (value_range *vr, gimple *stmt)
+vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
{
bool sop;
tree type = gimple_expr_type (stmt);
maxi = prec;
if (TREE_CODE (arg) == SSA_NAME)
{
- const value_range *vr0 = get_value_range (arg);
+ const value_range_equiv *vr0 = get_value_range (arg);
/* If arg is non-zero, then ffs or popcount are non-zero. */
if (range_includes_zero_p (vr0) == 0)
mini = 1;
mini = -2;
if (TREE_CODE (arg) == SSA_NAME)
{
- const value_range *vr0 = get_value_range (arg);
+ const value_range_equiv *vr0 = get_value_range (arg);
/* From clz of VR_RANGE minimum we can compute
result maximum. */
if (vr0->kind () == VR_RANGE
}
if (TREE_CODE (arg) == SSA_NAME)
{
- const value_range *vr0 = get_value_range (arg);
+ const value_range_equiv *vr0 = get_value_range (arg);
/* If arg is non-zero, then use [0, prec - 1]. */
if ((vr0->kind () == VR_RANGE
&& integer_nonzerop (vr0->min ()))
}
else
{
- value_range vr0, vr1;
+ value_range_equiv vr0, vr1;
bool saved_flag_wrapv = flag_wrapv;
/* Pretend the arithmetics is wrapping. If there is
any overflow, IMAGPART_EXPR will be set. */
in *VR. */
void
-vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
+vr_values::extract_range_from_assignment (value_range_equiv *vr, gassign *stmt)
{
enum tree_code code = gimple_assign_rhs_code (stmt);
static tree
-compare_ranges (enum tree_code comp, const value_range *vr0,
- const value_range *vr1, bool *strict_overflow_p)
+compare_ranges (enum tree_code comp, const value_range_equiv *vr0,
+ const value_range_equiv *vr1, bool *strict_overflow_p)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
if (vr0->varying_p ()
assumed signed overflow is undefined. */
static tree
-compare_range_with_value (enum tree_code comp, const value_range *vr, tree val,
- bool *strict_overflow_p)
+compare_range_with_value (enum tree_code comp, const value_range_equiv *vr,
+ tree val, bool *strict_overflow_p)
{
if (vr->varying_p () || vr->undefined_p ())
return NULL_TREE;
for VAR. If so, update VR with the new limits. */
void
-vr_values::adjust_range_with_scev (value_range *vr, class loop *loop,
+vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop,
gimple *stmt, tree var)
{
tree init, step, chrec, tmin, tmax, min, max, type, tem;
the number of latch executions is the correct thing to use. */
if (max_loop_iterations (loop, &nit))
{
- value_range maxvr;
signop sgn = TYPE_SIGN (TREE_TYPE (step));
wi::overflow_type overflow;
&& (sgn == UNSIGNED
|| wi::gts_p (wtmp, 0) == wi::gts_p (wi::to_wide (step), 0)))
{
+ value_range_equiv maxvr;
tem = wide_int_to_tree (TREE_TYPE (init), wtmp);
extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
TREE_TYPE (init), init, tem);
/* Likewise if the addition did. */
if (maxvr.kind () == VR_RANGE)
{
- value_range_base initvr;
+ value_range initvr;
if (TREE_CODE (init) == SSA_NAME)
initvr = *(get_value_range (init));
{
values_propagated = false;
num_vr_values = num_ssa_names * 2;
- vr_value = XCNEWVEC (value_range *, num_vr_values);
+ vr_value = XCNEWVEC (value_range_equiv *, num_vr_values);
vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
bitmap_obstack_initialize (&vrp_equiv_obstack);
to_remove_edges = vNULL;
{
if (TREE_CODE (name) == SSA_NAME)
{
- const value_range *vr = x_vr_values->get_value_range (name);
+ const value_range_equiv *vr = x_vr_values->get_value_range (name);
if (vr->kind () == VR_RANGE
&& (TREE_CODE (vr->min ()) == SSA_NAME
|| is_gimple_min_invariant (vr->min ()))
if (!gimple_nop_p (def_stmt)
&& prop_simulate_again_p (def_stmt))
return NULL_TREE;
- const value_range *vr = x_vr_values->get_value_range (name);
+ const value_range_equiv *vr = x_vr_values->get_value_range (name);
tree singleton;
if (vr->singleton_p (&singleton))
return singleton;
void
vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
- value_range *vr)
+ value_range_equiv *vr)
{
tree lhs = get_output_for_vrp (stmt);
*output_p = lhs;
or a symbolic range containing the SSA_NAME only if the value range
is varying or undefined. Uses TEM as storage for the alternate range. */
-const value_range *
-vr_values::get_vr_for_comparison (int i, value_range *tem)
+const value_range_equiv *
+vr_values::get_vr_for_comparison (int i, value_range_equiv *tem)
{
/* Shallow-copy equiv bitmap. */
- const value_range *vr = get_value_range (ssa_name (i));
+ const value_range_equiv *vr = get_value_range (ssa_name (i));
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
bool *strict_overflow_p, bool use_equiv_p)
{
- bitmap_iterator bi;
- unsigned i;
- bitmap e;
- tree retval, t;
- int used_strict_overflow;
- bool sop;
- const value_range *equiv_vr;
- value_range tem_vr;
-
/* Get the set of equivalences for VAR. */
- e = get_value_range (var)->equiv ();
+ bitmap e = get_value_range (var)->equiv ();
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
- used_strict_overflow = -1;
+ int used_strict_overflow = -1;
/* Compare vars' value range with val. */
- equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr);
- sop = false;
- retval = compare_range_with_value (comp, equiv_vr, val, &sop);
+ value_range_equiv tem_vr;
+ const value_range_equiv *equiv_vr
+ = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr);
+ bool sop = false;
+ tree retval = compare_range_with_value (comp, equiv_vr, val, &sop);
if (retval)
used_strict_overflow = sop ? 1 : 0;
/* If the equiv set is empty we have done all work we need to do. */
if (e == NULL)
{
- if (retval
- && used_strict_overflow > 0)
+ if (retval && used_strict_overflow > 0)
*strict_overflow_p = true;
return retval;
}
+ unsigned i;
+ bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
{
tree name = ssa_name (i);
- if (! name)
+ if (!name)
continue;
- if (! use_equiv_p
- && ! SSA_NAME_IS_DEFAULT_DEF (name)
+ if (!use_equiv_p
+ && !SSA_NAME_IS_DEFAULT_DEF (name)
&& prop_simulate_again_p (SSA_NAME_DEF_STMT (name)))
continue;
equiv_vr = get_vr_for_comparison (i, &tem_vr);
sop = false;
- t = compare_range_with_value (comp, equiv_vr, val, &sop);
+ tree t = compare_range_with_value (comp, equiv_vr, val, &sop);
if (t)
{
/* If we get different answers from different members
}
}
- if (retval
- && used_strict_overflow > 0)
+ if (retval && used_strict_overflow > 0)
*strict_overflow_p = true;
return retval;
vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
bool *strict_overflow_p)
{
- tree t, retval;
- bitmap e1, e2;
- bitmap_iterator bi1, bi2;
- unsigned i1, i2;
- int used_strict_overflow;
- static bitmap_obstack *s_obstack = NULL;
- static bitmap s_e1 = NULL, s_e2 = NULL;
-
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
- e1 = get_value_range (n1)->equiv ();
- e2 = get_value_range (n2)->equiv ();
+ bitmap e1 = get_value_range (n1)->equiv ();
+ bitmap e2 = get_value_range (n2)->equiv ();
/* Use the fake bitmaps if e1 or e2 are not available. */
+ static bitmap s_e1 = NULL, s_e2 = NULL;
+ static bitmap_obstack *s_obstack = NULL;
if (s_obstack == NULL)
{
s_obstack = XNEW (bitmap_obstack);
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
- used_strict_overflow = -1;
+ int used_strict_overflow = -1;
/* Otherwise, compare all the equivalent ranges. First, add N1 and
N2 to their own set of equivalences to avoid duplicating the body
of the loop just to check N1 and N2 ranges. */
+ bitmap_iterator bi1;
+ unsigned i1;
EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
{
- if (! ssa_name (i1))
+ if (!ssa_name (i1))
continue;
- value_range tem_vr1;
- const value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1);
+ value_range_equiv tem_vr1;
+ const value_range_equiv *vr1 = get_vr_for_comparison (i1, &tem_vr1);
- t = retval = NULL_TREE;
+ tree t = NULL_TREE, retval = NULL_TREE;
+ bitmap_iterator bi2;
+ unsigned i2;
EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
{
- if (! ssa_name (i2))
+ if (!ssa_name (i2))
continue;
bool sop = false;
- value_range tem_vr2;
- const value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2);
+ value_range_equiv tem_vr2;
+ const value_range_equiv *vr2 = get_vr_for_comparison (i2, &tem_vr2);
t = compare_ranges (comp, vr1, vr2, &sop);
if (t)
of the equivalence set this check must be in a dead
code region. Folding it to a trap representation
would be correct here. For now just return don't-know. */
- if (retval != NULL
- && t != retval)
+ if (retval != NULL && t != retval)
{
bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p)
{
- const value_range *vr0, *vr1;
-
+ const value_range_equiv *vr0, *vr1;
vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
}
else
{
- value_range_base vro, vri;
+ value_range vro, vri;
if (code == GT_EXPR || code == GE_EXPR)
{
vro.set (VR_ANTI_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
}
else
gcc_unreachable ();
- const value_range *vr0 = get_value_range (op0);
+ const value_range_equiv *vr0 = get_value_range (op0);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
always fold regardless of the value of OP0. If -Wtype-limits
was specified, emit a warning. */
tree type = TREE_TYPE (op0);
- const value_range *vr0 = get_value_range (op0);
+ const value_range_equiv *vr0 = get_value_range (op0);
if (vr0->kind () == VR_RANGE
&& INTEGRAL_TYPE_P (type)
Returns true if the default label is not needed. */
static bool
-find_case_label_ranges (gswitch *stmt, const value_range *vr, size_t *min_idx1,
- size_t *max_idx1, size_t *min_idx2,
- size_t *max_idx2)
+find_case_label_ranges (gswitch *stmt, const value_range_equiv *vr,
+ size_t *min_idx1, size_t *max_idx1,
+ size_t *min_idx2, size_t *max_idx2)
{
size_t i, j, k, l;
unsigned int n = gimple_switch_num_labels (stmt);
vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
{
tree op, val;
- const value_range *vr;
+ const value_range_equiv *vr;
size_t i = 0, j = 0, k, l;
bool take_default;
void
vr_values::extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
- tree *output_p, value_range *vr)
+ tree *output_p, value_range_equiv *vr)
{
if (dump_file && (dump_flags & TDF_DETAILS))
value ranges, set a new range in VR_RESULT. */
void
-vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
+vr_values::extract_range_from_phi_node (gphi *phi,
+ value_range_equiv *vr_result)
{
- size_t i;
tree lhs = PHI_RESULT (phi);
- const value_range *lhs_vr = get_value_range (lhs);
+ const value_range_equiv *lhs_vr = get_value_range (lhs);
bool first = true;
- int edges, old_edges;
+ int old_edges;
class loop *l;
if (dump_file && (dump_flags & TDF_DETAILS))
}
bool may_simulate_backedge_again = false;
- edges = 0;
- for (i = 0; i < gimple_phi_num_args (phi); i++)
+ int edges = 0;
+ for (size_t i = 0; i < gimple_phi_num_args (phi); i++)
{
edge e = gimple_phi_arg_edge (phi, i);
if (e->flags & EDGE_EXECUTABLE)
{
- tree arg = PHI_ARG_DEF (phi, i);
- value_range vr_arg_tem;
- const value_range *vr_arg = &vr_arg_tem;
+ value_range_equiv vr_arg_tem;
+ const value_range_equiv *vr_arg = &vr_arg_tem;
++edges;
+ tree arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) == SSA_NAME)
{
/* See if we are eventually going to change one of the args. */
&& e->flags & EDGE_DFS_BACK)
may_simulate_backedge_again = true;
- const value_range *vr_arg_ = get_value_range (arg);
+ const value_range_equiv *vr_arg_ = get_value_range (arg);
/* Do not allow equivalences or symbolic ranges to leak in from
backedges. That creates invalid equivalencies.
See PR53465 and PR54767. */
tree op1 = gimple_assign_rhs2 (stmt);
tree op0min = NULL_TREE, op0max = NULL_TREE;
tree op1min = op1;
- const value_range *vr = NULL;
+ const value_range_equiv *vr = NULL;
if (TREE_CODE (op0) == INTEGER_CST)
{
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
- const value_range *vr1 = get_value_range (op1);
+ const value_range_equiv *vr1 = get_value_range (op1);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}
vr_values::simplify_abs_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
{
tree op = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (op);
+ const value_range_equiv *vr = get_value_range (op);
if (vr)
{
static bool
vr_set_zero_nonzero_bits (const tree expr_type,
- const value_range_base *vr,
+ const value_range *vr,
wide_int *may_be_nonzero,
wide_int *must_be_nonzero)
{
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
tree op = NULL_TREE;
- value_range_base vr0, vr1;
+ value_range vr0, vr1;
wide_int may_be_nonzero0, may_be_nonzero1;
wide_int must_be_nonzero0, must_be_nonzero1;
wide_int mask;
static tree
test_for_singularity (enum tree_code cond_code, tree op0,
- tree op1, const value_range *vr)
+ tree op1, const value_range_equiv *vr)
{
tree min = NULL;
tree max = NULL;
by PRECISION and UNSIGNED_P. */
static bool
-range_fits_type_p (const value_range *vr,
+range_fits_type_p (const value_range_equiv *vr,
unsigned dest_precision, signop dest_sgn)
{
tree src_type;
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
{
- const value_range *vr = get_value_range (op0);
+ const value_range_equiv *vr = get_value_range (op0);
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
&& desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
- const value_range *vr = get_value_range (innerop);
+ const value_range_equiv *vr = get_value_range (innerop);
if (range_int_cst_p (vr)
&& range_fits_type_p (vr,
vr_values::simplify_switch_using_ranges (gswitch *stmt)
{
tree op = gimple_switch_index (stmt);
- const value_range *vr = NULL;
+ const value_range_equiv *vr = NULL;
bool take_default;
edge e;
edge_iterator ei;
gimple *stmt)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- const value_range *vr = get_value_range (rhs1);
+ const value_range_equiv *vr = get_value_range (rhs1);
scalar_float_mode fltmode
= SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
scalar_int_mode mode;
bool
vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
{
- const value_range *vr = get_value_range (var);
+ const value_range_equiv *vr = get_value_range (var);
if (vr->varying_p ()
|| vr->undefined_p ()
|| TREE_CODE (vr->min ()) != INTEGER_CST
/* Set the lattice entry for VAR to VR. */
void
-vr_values::set_vr_value (tree var, value_range *vr)
+vr_values::set_vr_value (tree var, value_range_equiv *vr)
{
if (SSA_NAME_VERSION (var) >= num_vr_values)
return;
/* Swap the lattice entry for VAR with VR and return the old entry. */
-value_range *
-vr_values::swap_vr_value (tree var, value_range *vr)
+value_range_equiv *
+vr_values::swap_vr_value (tree var, value_range_equiv *vr)
{
if (SSA_NAME_VERSION (var) >= num_vr_values)
return NULL;