prange_storage::equal_p performs a comparison between a prange and a prange_storage object.

It currently constructs a prange, and then calls prange::operator==().  This is short and simple, but if the number of calls increase, the cost of fully constructing a prange can begin to dominate the process.

This is not necessary.  We can simply pick the required words from the prange_storage object an compare them to the wide_ints in the prange class.  This is significantly more efficient.

Bootstrapped on aarch64-unknown-linux-gnu and x86_64-pc-linux-gnu  with no regressions.  Committed.

Andrew
From dc977d58d2dce9513df40e38f730ba934028bb8e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Thu, 28 May 2026 10:07:02 -0400
Subject: [PATCH 03/12] Make prange_storage::equal_p more efficient.

Equal_p created a full prange from storage in order to do a conparison.
This is quite inefficient.  It is better to compar jeust the required
fields directly from storage.

	* value_range_storage.cc (prange_storage::equal_p): Compare just
	the required fields.
---
 gcc/value-range-storage.cc | 46 +++++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc
index 3f5ad9e966e..58d4a3ba21a 100644
--- a/gcc/value-range-storage.cc
+++ b/gcc/value-range-storage.cc
@@ -761,9 +761,49 @@ prange_storage::equal_p (const prange &r) const
   if (r.undefined_p ())
     return m_kind == PR_UNDEFINED;
 
-  prange tmp;
-  get_prange (tmp, r.type ());
-  return tmp == r;
+  unsigned index = 0;
+  switch (m_kind)
+    {
+      case PR_VARYING:
+	return r.varying_p ();
+
+      case PR_ZERO:
+	return r.zero_p ();
+
+      case PR_NONZERO:
+	if (!r.nonzero_p ())
+	  return false;
+	break;
+
+      case PR_FULL:
+	if (r.m_min != wi::zero (TYPE_PRECISION (r.m_type))
+	    || r.m_max != wi::max_value (TYPE_PRECISION (r.m_type),
+					 TYPE_SIGN (r.m_type)))
+	  return false;
+	break;
+
+      case PR_OTHER:
+	if (r.m_min != get_word (index++, r.m_type)
+	    || r.m_max != get_word (index++, r.m_type))
+	  return false;
+	break;
+
+      default:
+	gcc_unreachable ();
+    }
+
+  if (m_has_bitmask)
+    {
+      wide_int value = get_word (index++, r.m_type);
+      wide_int mask = get_word (index++, r.m_type);
+      if (r.m_bitmask != irange_bitmask (value, mask))
+	return false;
+    }
+  else
+    if (!r.m_bitmask.unknown_p ())
+      return false;
+
+  return true;
 }
 
 bool
-- 
2.45.0

Reply via email to