Earlier I introduced the format_prange class to help summarize the
information required to efficiently format a prange storage.
This has turned out to be overkill, so this patch removes the
prange_format class, and replaces it with a function returning a
prange_kind and the number of words required.
Bootstrapped on aarch64-unknown-linux-gnu and x86_64-pc-linux-gnu with
no regressions. Committed.
Andrew
From e5f8327411733ce4ca89d0a7a2a80af528da236f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Mon, 25 May 2026 16:52:31 -0400
Subject: [PATCH 02/12] Replace class format_prange with a function.
The format_prange class is overkill for what it does. It can be replaced
with a simple function call which returns a prange_kind and the number
of words of storage required.
* value-range-storage.cc (prange_storage::alloc): Use new
prange_format function.
(prange_storage::prange_storage): Likewise.
(prange_storage::prange_format): Rename from prange_format
constructor and rework.
(prange_storage::set_prange): Use prange_format function.
(prange_storage::fits_p): Likewise.
* value-range-storage.h (enum prange_kind): Move out of
prange_storage class.
(PRANGE_STORAGE_NINTS): Likewise.
(class prange_format): remove.
(m_trailing_ints): Use PRANGE_STORAGE_NINTS.
---
gcc/value-range-storage.cc | 77 ++++++++++++++++++--------------------
gcc/value-range-storage.h | 38 ++++++++-----------
2 files changed, 53 insertions(+), 62 deletions(-)
diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc
index 7fa104228f7..3f5ad9e966e 100644
--- a/gcc/value-range-storage.cc
+++ b/gcc/value-range-storage.cc
@@ -593,8 +593,17 @@ frange_storage::fits_p (const frange &) const
prange_storage *
prange_storage::alloc (vrange_internal_alloc &allocator, const prange &r)
{
- prange_format format (r);
- size_t size = sizeof (prange_storage) + format.extra_size;
+ unsigned num_words;
+ prange_format (r, num_words);
+ size_t extra_size = 0;
+ if (num_words)
+ {
+ unsigned short precision = TYPE_PRECISION (r.type ());
+ extra_size = trailing_wide_ints<PRANGE_STORAGE_NINTS>
+ ::extra_size (precision, num_words);
+ }
+
+ size_t size = sizeof (prange_storage) + extra_size;
prange_storage *p = static_cast <prange_storage *> (allocator.alloc (size));
new (p) prange_storage (r);
return p;
@@ -604,39 +613,32 @@ prange_storage::alloc (vrange_internal_alloc &allocator, const prange &r)
prange_storage::prange_storage (const prange &r)
{
- prange_format format (r);
- m_trailing_ints.set_precision (format.precision, format.num_words);
+ unsigned num_words;
+ enum prange_kind kind = prange_format (r, num_words);
+ unsigned short prec = (kind == PR_UNDEFINED) ? 0 : TYPE_PRECISION (r.type ());
+ m_trailing_ints.set_precision (prec, num_words);
set_prange (r);
}
-// FIll the format structure for range R.
+// Return the prange_kind for range R, and the number of words of storage
+// it requires in NUM_WORDS.
-prange_storage::prange_format::prange_format (const prange &r)
+enum prange_kind
+prange_storage::prange_format (const prange &r, unsigned &num_words)
{
- kind = PR_UNDEFINED;
- has_bitmask = 0;
- extra_size = 0;
- precision = 0;
num_words = 0;
-
if (r.undefined_p ())
- return;
+ return PR_UNDEFINED;
if (r.varying_p ())
- {
- kind = PR_VARYING;
- return;
- }
+ return PR_VARYING;
if (r.zero_p ())
- {
- kind = PR_ZERO;
- return;
- }
+ return PR_ZERO;
- if (r.nonzero_p ())
- kind = PR_NONZERO;
- else
+ enum prange_kind kind = PR_NONZERO;
+
+ if (!r.nonzero_p ())
{
prange tmp (r.type ());
if (r.lower_bound () == tmp.lower_bound ()
@@ -649,26 +651,23 @@ prange_storage::prange_format::prange_format (const prange &r)
num_words += 2;
}
}
- precision = TYPE_PRECISION (r.type ());
- has_bitmask = !r.get_bitmask ().unknown_p ();
// Bitmasks require 2 words of storage.
- if (has_bitmask)
+ if (!r.get_bitmask ().unknown_p ())
num_words += 2;
- if (num_words != 0)
- extra_size = trailing_wide_ints<NINTS>::extra_size (precision, num_words);
-
- // PR_FULL must have a bitmask, or it should be PR_VARYING.
- gcc_checking_assert (kind != PR_FULL || has_bitmask);
+ // PR_FULL must have a bitmask or points to, or it should be PR_VARYING.
+ gcc_checking_assert (kind != PR_FULL || !r.get_bitmask ().unknown_p ());
+ return kind;
}
void
prange_storage::set_prange (const prange &r)
{
- prange_format format (r);
- m_kind = format.kind;
- m_has_bitmask = format.has_bitmask;
+ unsigned num_words;
+ m_kind = prange_format (r, num_words);
+ m_has_bitmask = !r.get_bitmask ().unknown_p ();
+
unsigned index = 0;
switch (m_kind)
@@ -694,7 +693,7 @@ prange_storage::set_prange (const prange &r)
set_word (index++, r.m_bitmask.value (), r.type ());
set_word (index++, r.m_bitmask.mask (), r.type ());
}
- gcc_checking_assert (index == format.num_words);
+ gcc_checking_assert (index == num_words);
}
void
@@ -775,11 +774,9 @@ prange_storage::fits_p (const prange &r) const
if (r.undefined_p ())
return true;
- prange_format f (r);
- unsigned prec = m_trailing_ints.get_precision ();
- unsigned num = m_trailing_ints.num_elements ();
- size_t curr = num ? trailing_wide_ints<NINTS>::extra_size (prec, num) : 0;
- return f.extra_size <= curr;
+ unsigned num_words;
+ prange_format (r, num_words);
+ return num_words <= m_trailing_ints.num_elements ();
}
diff --git a/gcc/value-range-storage.h b/gcc/value-range-storage.h
index 78a6f4efb62..ebc2f6fda79 100644
--- a/gcc/value-range-storage.h
+++ b/gcc/value-range-storage.h
@@ -98,8 +98,21 @@ private:
irange_storage (const irange &r);
};
-// Efficient memory storage for a prange.
+// A prange_kind summarizes some common variations for a prange, and is used
+// in a prange_storage clas for efficiency.
+
+enum prange_kind { PR_UNDEFINED, // VR_UNDEFINED
+ PR_VARYING, // VR_VARYING
+ PR_ZERO, // [0, 0]
+ PR_NONZERO, // [1, +INF] (May have bitmask)
+ PR_FULL, // [0, +INF] (Must have bitmask)
+ PR_OTHER }; // [x, y] (MAy have bitmask)
+
+// Maximum number of words that may be allocated by a prange_storage class.
+const unsigned int PRANGE_STORAGE_NINTS = 4;
+
+// Efficient memory storage for a prange.
class prange_storage : public vrange_storage
{
public:
@@ -112,25 +125,7 @@ public:
private:
DISABLE_COPY_AND_ASSIGN (prange_storage);
prange_storage (const prange &r);
-
- // A prange_format class summarizes the storage requirements for a prange
- // which are then used to initialize the prange_storage fields.
- enum prange_kind { PR_UNDEFINED, // VR_UNDEFINED
- PR_VARYING, // VR_VARYING
- PR_ZERO, // [0, 0]
- PR_NONZERO, // [1, +INF]
- PR_FULL, // [0, +INF] (Must have bitmask)
- PR_OTHER }; // [x, y]
- class prange_format
- {
- public:
- prange_format (const prange &r);
- enum prange_kind kind;
- bool has_bitmask;
- size_t extra_size;
- unsigned short precision;
- unsigned num_words;
- };
+ static enum prange_kind prange_format (const prange &r, unsigned &num_words);
enum prange_kind m_kind;
bool m_has_bitmask;
@@ -143,8 +138,7 @@ private:
template <typename T> void set_word (unsigned i, const T &x, tree)
{ m_trailing_ints[i] = x; }
- static const unsigned int NINTS = 4;
- trailing_wide_ints<NINTS> m_trailing_ints;
+ trailing_wide_ints<PRANGE_STORAGE_NINTS> m_trailing_ints;
};
// Efficient memory storage for an frange.
--
2.45.0