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