public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Keep VR_UNDEFINED and VR_VARYING in sync (speeds up evrp by 8.47%).
@ 2021-04-26 14:16 Aldy Hernandez
  2021-04-26 14:16 ` [PATCH 2/2] Cache irange::num_pairs() for non-legacy code Aldy Hernandez
  2021-04-26 15:03 ` [PATCH 1/2] Keep VR_UNDEFINED and VR_VARYING in sync (speeds up evrp by 8.47%) Andrew MacLeod
  0 siblings, 2 replies; 5+ messages in thread
From: Aldy Hernandez @ 2021-04-26 14:16 UTC (permalink / raw)
  To: Andrew MacLeod, GCC patches

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).

OK?

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::irange_varying_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.
---
 gcc/value-range.cc | 69 +++++++++++++++++++++++++++-------------------
 gcc/value-range.h  | 66 ++++++++++++++++----------------------------
 2 files changed, 63 insertions(+), 72 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index f5ef4808530..369eeabd7d5 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_assert (m_num_ranges == 1);
+      gcc_assert (irange_varying_p ());
+      return;
+    }
   if (!legacy_mode_p ())
     {
-      gcc_checking_assert (m_kind == VR_RANGE);
+      gcc_assert (!irange_varying_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 bb27e706207..bfba1a3469e 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 irange_varying_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::irange_varying_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 (irange_varying_p ())
     {
       if (m_kind == VR_RANGE)
-	set_varying (type ());
+	m_kind = VR_VARYING;
       else if (m_kind == VR_ANTI_RANGE)
 	set_undefined ();
       else
-- 
2.30.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-04-26 16:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-26 14:16 [PATCH 1/2] Keep VR_UNDEFINED and VR_VARYING in sync (speeds up evrp by 8.47%) Aldy Hernandez
2021-04-26 14:16 ` [PATCH 2/2] Cache irange::num_pairs() for non-legacy code Aldy Hernandez
2021-04-26 15:32   ` Andrew MacLeod
2021-04-26 15:03 ` [PATCH 1/2] Keep VR_UNDEFINED and VR_VARYING in sync (speeds up evrp by 8.47%) Andrew MacLeod
2021-04-26 16:23   ` Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).