aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2021-04-16 18:40:44 +0200
committerAldy Hernandez <aldyh@redhat.com>2021-04-26 18:20:38 +0200
commitdc80d5e887ea4fa0e1e950db5f6bdd765c960c22 (patch)
tree5745ec11b2ec0767dd0b33991dd425012b541d45
parent694c956b6b877e48323cf86c90c09237b7b0e8c8 (diff)
downloadgcc-dc80d5e887ea4fa0e1e950db5f6bdd765c960c22.zip
gcc-dc80d5e887ea4fa0e1e950db5f6bdd765c960c22.tar.gz
gcc-dc80d5e887ea4fa0e1e950db5f6bdd765c960c22.tar.bz2
Keep VR_UNDEFINED and VR_VARYING in sync (speeds up evrp by 8.47%).
Currently multi-ranges calculate the undefined and varying bits on the fly, whereas legacy uses the m_kind field. Since we will always have space in the irange class for a kind field, might as well keep it in sync as ranges are created, thus speeding up lookups. This patch, along with an upcoming ones for num_pairs(), speeds up EVRP by 8.47%, VRP proper by 1.84% and overall compilation by 0.24%. FWIW, since evrp is such a fast pass, and is hard to measure clock-wise, we've been using callgrind to estimate improvements. This has coincided more or less with -ftime-report numbers (albeit having to run -ftime-report half a dozen times and use the average). gcc/ChangeLog: * value-range.cc (irange::operator=): Set m_kind. (irange::copy_to_legacy): Handle varying and undefined sources as a legacy copy since they can be easily copied. (irange::irange_set): Set m_kind. (irange::irange_set_anti_range): Same. (irange::set): Rename normalize_min_max to normalize_kind. (irange::verify_range): Adjust for multi-ranges having the m_kind field set. (irange::irange_union): Set m_kind. (irange::irange_intersect): Same. (irange::invert): Same. * value-range.h (irange::kind): Always return m_kind. (irange::varying_p): Rename to... (irange::varying_comptaible_p): ...this. (irange::undefined_p): Only look at m_kind. (irange::irange): Always set VR_UNDEFINED if applicable. (irange::set_undefined): Always set VR_UNDEFINED. (irange::set_varying): Always set m_kind to VR_VARYING. (irange::normalize_min_max): Rename to... (irange::normalize_kind): ...this.
-rw-r--r--gcc/value-range.cc69
-rw-r--r--gcc/value-range.h66
2 files changed, 63 insertions, 72 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index f5ef480..297dd60 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -59,6 +59,7 @@ irange::operator= (const irange &src)
m_base[x - 1] = src.m_base[src.m_num_ranges * 2 - 1];
m_num_ranges = lim;
+ m_kind = src.m_kind;
return *this;
}
@@ -106,8 +107,8 @@ void
irange::copy_to_legacy (const irange &src)
{
gcc_checking_assert (legacy_mode_p ());
- // Copy legacy to legacy.
- if (src.legacy_mode_p ())
+ // Handle legacy to legacy and other things that are easy to copy.
+ if (src.legacy_mode_p () || src.varying_p () || src.undefined_p ())
{
m_num_ranges = src.m_num_ranges;
m_base[0] = src.m_base[0];
@@ -116,11 +117,7 @@ irange::copy_to_legacy (const irange &src)
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 ())
+ if (src.maybe_anti_range ())
{
int_range<3> r (src);
r.invert ();
@@ -180,6 +177,9 @@ irange::irange_set (tree min, tree max)
m_base[0] = min;
m_base[1] = max;
m_num_ranges = 1;
+ m_kind = VR_RANGE;
+ normalize_kind ();
+
if (flag_checking)
verify_range ();
}
@@ -247,6 +247,10 @@ irange::irange_set_anti_range (tree min, tree max)
m_base[m_num_ranges * 2 + 1] = type_range.tree_upper_bound (0);
++m_num_ranges;
}
+
+ m_kind = VR_RANGE;
+ normalize_kind ();
+
if (flag_checking)
verify_range ();
}
@@ -353,7 +357,7 @@ irange::set (tree min, tree max, value_range_kind kind)
m_base[0] = min;
m_base[1] = max;
m_num_ranges = 1;
- normalize_min_max ();
+ normalize_kind ();
if (flag_checking)
verify_range ();
}
@@ -363,9 +367,22 @@ irange::set (tree min, tree max, value_range_kind kind)
void
irange::verify_range ()
{
+ if (m_kind == VR_UNDEFINED)
+ {
+ gcc_assert (m_num_ranges == 0);
+ return;
+ }
+ gcc_assert (m_num_ranges != 0);
+
+ if (m_kind == VR_VARYING)
+ {
+ gcc_checking_assert (m_num_ranges == 1);
+ gcc_checking_assert (varying_compatible_p ());
+ return;
+ }
if (!legacy_mode_p ())
{
- gcc_checking_assert (m_kind == VR_RANGE);
+ gcc_checking_assert (!varying_compatible_p ());
for (unsigned i = 0; i < m_num_ranges; ++i)
{
tree lb = tree_lower_bound (i);
@@ -375,28 +392,11 @@ irange::verify_range ()
}
return;
}
-
- switch (m_kind)
+ if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
{
- case VR_UNDEFINED:
- gcc_assert (m_num_ranges == 0);
- break;
-
- case VR_VARYING:
gcc_assert (m_num_ranges == 1);
- break;
-
- case VR_ANTI_RANGE:
- case VR_RANGE:
- {
- gcc_assert (m_num_ranges == 1);
- int cmp = compare_values (tree_lower_bound (0), tree_upper_bound (0));
- gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
- return;
- }
-
- default:
- gcc_unreachable ();
+ int cmp = compare_values (tree_lower_bound (0), tree_upper_bound (0));
+ gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
}
}
@@ -1667,6 +1667,9 @@ irange::irange_union (const irange &r)
m_base[j] = res [j];
m_num_ranges = i / 2;
+ m_kind = VR_RANGE;
+ normalize_kind ();
+
if (flag_checking)
verify_range ();
}
@@ -1758,6 +1761,10 @@ irange::irange_intersect (const irange &r)
// At the exit of this loop, it is one of 2 things:
// ran out of r1, or r2, but either means we are done.
m_num_ranges = bld_pair;
+
+ m_kind = VR_RANGE;
+ normalize_kind ();
+
if (flag_checking)
verify_range ();
}
@@ -1890,6 +1897,10 @@ irange::invert ()
}
m_num_ranges = nitems / 2;
+ // We disallow undefined or varying coming in, so the result can
+ // only be a VR_RANGE.
+ gcc_checking_assert (m_kind == VR_RANGE);
+
if (flag_checking)
verify_range ();
}
diff --git a/gcc/value-range.h b/gcc/value-range.h
index bb27e70..e000432 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -111,7 +111,7 @@ protected:
void irange_set (tree, tree);
void irange_set_anti_range (tree, tree);
- void normalize_min_max ();
+ void normalize_kind ();
bool legacy_mode_p () const;
bool legacy_equal_p (const irange &) const;
@@ -128,6 +128,7 @@ protected:
private:
void irange_set_1bit_anti_range (tree, tree);
+ bool varying_compatible_p () const;
unsigned char m_num_ranges;
unsigned char m_max_ranges;
@@ -198,16 +199,7 @@ extern bool vrp_operand_equal_p (const_tree, const_tree);
inline value_range_kind
irange::kind () const
{
- if (legacy_mode_p ())
- return m_kind;
-
- if (undefined_p ())
- return VR_UNDEFINED;
-
- if (varying_p ())
- return VR_VARYING;
-
- return VR_RANGE;
+ return m_kind;
}
// Number of sub-ranges in a range.
@@ -271,17 +263,18 @@ irange::max () const
}
inline bool
-irange::varying_p () const
+irange::varying_compatible_p () const
{
- if (legacy_mode_p ())
- return m_kind == VR_VARYING;
-
if (m_num_ranges != 1)
return false;
tree l = m_base[0];
tree u = m_base[1];
tree t = TREE_TYPE (l);
+
+ if (m_kind == VR_VARYING && t == error_mark_node)
+ return true;
+
unsigned prec = TYPE_PRECISION (t);
signop sign = TYPE_SIGN (t);
if (INTEGRAL_TYPE_P (t))
@@ -291,22 +284,17 @@ irange::varying_p () const
return (wi::to_wide (l) == 0
&& wi::to_wide (u) == wi::max_value (prec, sign));
return true;
+}
+inline bool
+irange::varying_p () const
+{
+ return m_kind == VR_VARYING;
}
inline bool
irange::undefined_p () const
{
- if (!legacy_mode_p ())
- return m_num_ranges == 0;
-
- if (CHECKING_P && legacy_mode_p ())
- {
- if (m_kind == VR_UNDEFINED)
- gcc_checking_assert (m_num_ranges == 0);
- else
- gcc_checking_assert (m_num_ranges != 0);
- }
return m_kind == VR_UNDEFINED;
}
@@ -389,10 +377,7 @@ irange::irange (tree *base, unsigned nranges)
m_base = base;
m_num_ranges = 0;
m_max_ranges = nranges;
- if (legacy_mode_p ())
- m_kind = VR_UNDEFINED;
- else
- m_kind = VR_RANGE;
+ m_kind = VR_UNDEFINED;
}
// Constructors for int_range<>.
@@ -459,18 +444,16 @@ irange::set (tree val)
inline void
irange::set_undefined ()
{
+ m_kind = VR_UNDEFINED;
m_num_ranges = 0;
- if (legacy_mode_p ())
- m_kind = VR_UNDEFINED;
}
inline void
irange::set_varying (tree type)
{
- if (legacy_mode_p ())
- m_kind = VR_VARYING;
-
+ m_kind = VR_VARYING;
m_num_ranges = 1;
+
if (INTEGRAL_TYPE_P (type))
{
wide_int min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
@@ -574,17 +557,14 @@ irange::set_zero (tree type)
// Normalize a range to VARYING or UNDEFINED if possible.
inline void
-irange::normalize_min_max ()
-{
- gcc_checking_assert (legacy_mode_p ());
- gcc_checking_assert (!undefined_p ());
- unsigned prec = TYPE_PRECISION (type ());
- signop sign = TYPE_SIGN (type ());
- if (wi::eq_p (wi::to_wide (min ()), wi::min_value (prec, sign))
- && wi::eq_p (wi::to_wide (max ()), wi::max_value (prec, sign)))
+irange::normalize_kind ()
+{
+ if (m_num_ranges == 0)
+ m_kind = VR_UNDEFINED;
+ else if (varying_compatible_p ())
{
if (m_kind == VR_RANGE)
- set_varying (type ());
+ m_kind = VR_VARYING;
else if (m_kind == VR_ANTI_RANGE)
set_undefined ();
else