aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/value-range.cc72
-rw-r--r--gcc/value-range.h3
2 files changed, 44 insertions, 31 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index cdcc6c6..7847104 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -35,18 +35,14 @@ along with GCC; see the file COPYING3. If not see
irange &
irange::operator= (const irange &src)
{
- if (legacy_mode_p () != src.legacy_mode_p ())
+ if (legacy_mode_p ())
{
- copy_legacy_range (src);
+ copy_to_legacy (src);
return *this;
}
- if (legacy_mode_p ())
+ if (src.legacy_mode_p ())
{
- gcc_checking_assert (src.legacy_mode_p ());
- m_num_ranges = src.m_num_ranges;
- m_base[0] = src.m_base[0];
- m_base[1] = src.m_base[1];
- m_kind = src.m_kind;
+ copy_legacy_to_multi_range (src);
return *this;
}
@@ -81,44 +77,60 @@ irange::maybe_anti_range () const
&& upper_bound () == wi::max_value (precision, sign));
}
-// Copy between a legacy and a multi-range, or vice-versa.
-
void
-irange::copy_legacy_range (const irange &src)
+irange::copy_legacy_to_multi_range (const irange &src)
{
- gcc_checking_assert (src.legacy_mode_p () != legacy_mode_p ());
+ gcc_checking_assert (src.legacy_mode_p ());
+ gcc_checking_assert (!legacy_mode_p ());
if (src.undefined_p ())
set_undefined ();
else if (src.varying_p ())
set_varying (src.type ());
- else if (src.kind () == VR_ANTI_RANGE)
- {
- if (src.legacy_mode_p () && !range_has_numeric_bounds_p (&src))
- set_varying (src.type ());
- else
- set (src.min (), src.max (), VR_ANTI_RANGE);
- }
- else if (legacy_mode_p () && src.maybe_anti_range ())
- {
- int_range<3> tmp (src);
- tmp.invert ();
- set (tmp.min (), wide_int_to_tree (src.type (), tmp.upper_bound (0)),
- VR_ANTI_RANGE);
- }
else
{
- // If copying legacy to int_range, normalize any symbolics.
- if (src.legacy_mode_p () && !range_has_numeric_bounds_p (&src))
+ if (range_has_numeric_bounds_p (&src))
+ set (src.min (), src.max (), src.kind ());
+ else
{
value_range cst (src);
cst.normalize_symbolics ();
+ gcc_checking_assert (cst.varying_p () || cst.kind () == VR_RANGE);
set (cst.min (), cst.max ());
- return;
}
- set (src.min (), src.max ());
}
}
+// Copy any type of irange into a legacy.
+
+void
+irange::copy_to_legacy (const irange &src)
+{
+ gcc_checking_assert (legacy_mode_p ());
+ // Copy legacy to legacy.
+ if (src.legacy_mode_p ())
+ {
+ m_num_ranges = src.m_num_ranges;
+ m_base[0] = src.m_base[0];
+ m_base[1] = src.m_base[1];
+ m_kind = src.m_kind;
+ return;
+ }
+ // Copy multi-range to legacy.
+ if (src.undefined_p ())
+ set_undefined ();
+ else if (src.varying_p ())
+ set_varying (src.type ());
+ else if (src.maybe_anti_range ())
+ {
+ int_range<3> r (src);
+ r.invert ();
+ // Use tree variants to save on tree -> wi -> tree conversions.
+ set (r.tree_lower_bound (0), r.tree_upper_bound (0), VR_ANTI_RANGE);
+ }
+ else
+ set (src.tree_lower_bound (), src.tree_upper_bound ());
+}
+
// Swap min/max if they are out of order. Return TRUE if further
// processing of the range is necessary, FALSE otherwise.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 63c9620..760ee77 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -124,7 +124,8 @@ protected:
wide_int legacy_upper_bound (unsigned) const;
int value_inside_range (tree) const;
bool maybe_anti_range () const;
- void copy_legacy_range (const irange &);
+ void copy_to_legacy (const irange &);
+ void copy_legacy_to_multi_range (const irange &);
private:
unsigned char m_num_ranges;