@@ -654,7 +654,9 @@ public:
range_cast (tmp, unsigned_type_for (tmp.type ()));
wide_int max = tmp.upper_bound ();
maxi = wi::floor_log2 (max) + 1;
- r.set (type, wi::shwi (mini, prec), wi::shwi (maxi, prec));
+ r.set (type,
+ wi::shwi (mini, TYPE_PRECISION (type)),
+ wi::shwi (maxi, TYPE_PRECISION (type)));
return true;
}
} op_cfn_ffs;
@@ -222,7 +222,7 @@ alloca_call_type (gimple *stmt, bool is_vla)
&& !r.varying_p ())
{
// The invalid bits are anything outside of [0, MAX_SIZE].
- int_range<1> invalid_range (size_type_node,
+ int_range<2> invalid_range (size_type_node,
wi::shwi (0, TYPE_PRECISION (size_type_node)),
wi::shwi (max_size, TYPE_PRECISION (size_type_node)),
VR_ANTI_RANGE);
@@ -827,6 +827,8 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
size_t i, j;
tree op = gimple_switch_index (switch_stmt);
tree type = TREE_TYPE (op);
+ unsigned prec = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
tree tmin = wide_int_to_tree (type, range_of_op->lower_bound ());
tree tmax = wide_int_to_tree (type, range_of_op->upper_bound ());
find_case_label_range (switch_stmt, tmin, tmax, &i, &j);
@@ -837,9 +839,11 @@ find_case_label_range (gswitch *switch_stmt, const irange *range_of_op)
tree label = gimple_switch_label (switch_stmt, i);
tree case_high
= CASE_HIGH (label) ? CASE_HIGH (label) : CASE_LOW (label);
+ wide_int wlow = wi::to_wide (CASE_LOW (label));
+ wide_int whigh = wi::to_wide (case_high);
int_range_max label_range (type,
- wi::to_wide (CASE_LOW (label)),
- wi::to_wide (case_high));
+ wide_int::from (wlow, prec, sign),
+ wide_int::from (whigh, prec, sign));
if (!types_compatible_p (label_range.type (), range_of_op->type ()))
range_cast (label_range, range_of_op->type ());
label_range.intersect (*range_of_op);
@@ -961,98 +961,6 @@ get_legacy_range (const irange &r, tree &min, tree &max)
return VR_RANGE;
}
-void
-irange::irange_set (tree type, const wide_int &min, const wide_int &max)
-{
- m_type = type;
- m_base[0] = min;
- m_base[1] = max;
- m_num_ranges = 1;
- m_kind = VR_RANGE;
- m_nonzero_mask = wi::minus_one (TYPE_PRECISION (type));
- normalize_kind ();
-
- if (flag_checking)
- verify_range ();
-}
-
-void
-irange::irange_set_1bit_anti_range (tree type,
- const wide_int &min, const wide_int &max)
-{
- unsigned prec = TYPE_PRECISION (type);
- signop sign = TYPE_SIGN (type);
- gcc_checking_assert (prec == 1);
-
- if (min == max)
- {
- wide_int tmp;
- // Since these are 1-bit quantities, they can only be [MIN,MIN]
- // or [MAX,MAX].
- if (min == wi::min_value (prec, sign))
- tmp = wi::max_value (prec, sign);
- else
- tmp = wi::min_value (prec, sign);
- set (type, tmp, tmp);
- }
- else
- {
- // The only alternative is [MIN,MAX], which is the empty range.
- gcc_checking_assert (min == wi::min_value (prec, sign));
- gcc_checking_assert (max == wi::max_value (prec, sign));
- set_undefined ();
- }
- if (flag_checking)
- verify_range ();
-}
-
-void
-irange::irange_set_anti_range (tree type,
- const wide_int &min, const wide_int &max)
-{
- if (TYPE_PRECISION (type) == 1)
- {
- irange_set_1bit_anti_range (type, min, max);
- return;
- }
-
- // set an anti-range
- signop sign = TYPE_SIGN (type);
- int_range<2> type_range (type);
- // Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
- m_num_ranges = 0;
- wi::overflow_type ovf;
-
- if (wi::ne_p (min, type_range.lower_bound ()))
- {
- wide_int lim1 = wi::sub (min, 1, sign, &ovf);
- gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
- m_base[0] = type_range.lower_bound (0);
- m_base[1] = lim1;
- m_num_ranges = 1;
- }
- if (wi::ne_p (max, type_range.upper_bound ()))
- {
- if (m_max_ranges == 1 && m_num_ranges)
- {
- set_varying (type);
- return;
- }
- wide_int lim2 = wi::add (max, 1, sign, &ovf);
- gcc_checking_assert (ovf != wi::OVF_OVERFLOW);
- m_base[m_num_ranges * 2] = lim2;
- m_base[m_num_ranges * 2 + 1] = type_range.upper_bound (0);
- ++m_num_ranges;
- }
-
- m_kind = VR_RANGE;
- m_nonzero_mask = wi::minus_one (TYPE_PRECISION (type));
- normalize_kind ();
-
- if (flag_checking)
- verify_range ();
-}
-
/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
This means adjusting VRTYPE, MIN and MAX representing the case of a
wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
@@ -1063,48 +971,69 @@ irange::irange_set_anti_range (tree type,
extract ranges from var + CST op limit. */
void
-irange::set (tree type, const wide_int &rmin, const wide_int &rmax,
+irange::set (tree type, const wide_int &min, const wide_int &max,
value_range_kind kind)
{
- if (kind == VR_UNDEFINED)
- {
- irange::set_undefined ();
- return;
- }
-
- if (kind == VR_VARYING)
- {
- set_varying (type);
- return;
- }
+ unsigned prec = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
+ wide_int min_value = wi::min_value (prec, sign);
+ wide_int max_value = wi::max_value (prec, sign);
m_type = type;
- signop sign = TYPE_SIGN (type);
- unsigned prec = TYPE_PRECISION (type);
- wide_int min = wide_int::from (rmin, prec, sign);
- wide_int max = wide_int::from (rmax, prec, sign);
+ m_nonzero_mask = wi::minus_one (prec);
if (kind == VR_RANGE)
- irange_set (type, min, max);
+ {
+ m_base[0] = min;
+ m_base[1] = max;
+ m_num_ranges = 1;
+ if (min == min_value && max == max_value)
+ m_kind = VR_VARYING;
+ else
+ m_kind = VR_RANGE;
+ }
else
{
gcc_checking_assert (kind == VR_ANTI_RANGE);
- irange_set_anti_range (type, min, max);
+ gcc_checking_assert (m_max_ranges > 1);
+
+ m_kind = VR_UNDEFINED;
+ m_num_ranges = 0;
+ wi::overflow_type ovf;
+ wide_int lim;
+ if (sign == SIGNED)
+ lim = wi::add (min, -1, sign, &ovf);
+ else
+ lim = wi::sub (min, 1, sign, &ovf);
+
+ if (!ovf)
+ {
+ m_kind = VR_RANGE;
+ m_base[0] = min_value;
+ m_base[1] = lim;
+ ++m_num_ranges;
+ }
+ if (sign == SIGNED)
+ lim = wi::sub (max, -1, sign, &ovf);
+ else
+ lim = wi::add (max, 1, sign, &ovf);
+ if (!ovf)
+ {
+ m_kind = VR_RANGE;
+ m_base[m_num_ranges * 2] = lim;
+ m_base[m_num_ranges * 2 + 1] = max_value;
+ ++m_num_ranges;
+ }
}
+
+ if (flag_checking)
+ verify_range ();
}
void
irange::set (tree min, tree max, value_range_kind kind)
{
- if (kind == VR_UNDEFINED)
- {
- irange::set_undefined ();
- return;
- }
-
- if (kind == VR_VARYING
- || POLY_INT_CST_P (min)
- || POLY_INT_CST_P (max))
+ if (POLY_INT_CST_P (min) || POLY_INT_CST_P (max))
{
set_varying (TREE_TYPE (min));
return;
@@ -1113,13 +1042,7 @@ irange::set (tree min, tree max, value_range_kind kind)
gcc_checking_assert (TREE_CODE (min) == INTEGER_CST);
gcc_checking_assert (TREE_CODE (max) == INTEGER_CST);
- if (TREE_OVERFLOW_P (min))
- min = drop_tree_overflow (min);
- if (TREE_OVERFLOW_P (max))
- max = drop_tree_overflow (max);
-
- return set (TREE_TYPE (min),
- wi::to_wide (min), wi::to_wide (max), kind);
+ return set (TREE_TYPE (min), wi::to_wide (min), wi::to_wide (max), kind);
}
// Check the validity of the range.
@@ -172,8 +172,6 @@ protected:
irange (wide_int *, unsigned);
// In-place operators.
- void irange_set (tree type, const wide_int &, const wide_int &);
- void irange_set_anti_range (tree type, const wide_int &, const wide_int &);
bool irange_contains_p (const irange &) const;
bool irange_single_pair_union (const irange &r);
@@ -186,8 +184,6 @@ private:
friend void gt_pch_nx (irange *);
friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
- void irange_set_1bit_anti_range (tree type,
- const wide_int &, const wide_int &);
bool varying_compatible_p () const;
bool intersect_nonzero_bits (const irange &r);
bool union_nonzero_bits (const irange &r);
@@ -831,7 +827,6 @@ inline void
irange::set_undefined ()
{
m_kind = VR_UNDEFINED;
- m_type = NULL;
m_num_ranges = 0;
}