On 8/20/26 04:13, Richard Biener wrote:
On Wed, Aug 19, 2026 at 6:57 PM Andrew MacLeod <[email protected]> wrote:
Well there is no restore for ranger... it would recalculate whatever it
needs based on whats in the IL. If you restore a global value, it will
begin with that.
I'll look at making the deletes more efficient for future proofing.
Thanks - I believe "it likely won't happen" isn't a good stance for
software development ...
Richard.
Come on, live dangerously! :-)
OK, here is a 3 patch set which removes the full CFG walk and replaces
it with a targeted list for each of the 3 places that need it. inferred
manager, equiv_oracle and dom_oracle. . Very slight increase in time
when things are created, but nothing of any significance. Overall
compile time increase across GCC of 0.02%.
The inferred range manager already manages a structure which contains a
link ot the next inferred range in a block. Since each structure only
relates to a single ssa-name, I added another link which links all the
ranges associated with an ssa-name together as well. Clear () now
simply walks that list and clears the info.
Bootstraps on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From 02b1fd0fb376fac9f8bb9954e2663ca5061e2ac2 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Thu, 20 Aug 2026 12:00:42 -0400
Subject: [PATCH 1/3] Improve infer::clear performance.
Remove the full CFG walk replace it with a linked list walk.
PR tree-optimization/126856
* gimple-range-infer.cc (exit_range::name_link): New.
(infer_range_manager::infer_range_manager): Adjust for rename
from m_nonzero to m_name_info.
(infer_range_manager::~infer_range_manager): Likewise.
(infer_range_manager::get_nonzero): Likewise
(infer_range_manager::add_range): Add to name_link list.
(infer_range_manager::clear): Walk name_link list.
* gimple-range-infer.h (class ssa_name_link): New vec.
(infer_range_manager::m_nonzero): Retype and rename to m_name_info.
---
gcc/gimple-range-infer.cc | 51 +++++++++++++++++++--------------------
gcc/gimple-range-infer.h | 8 +++++-
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index 5f0f7efcc01..7dea875cb86 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -311,6 +311,7 @@ public:
gimple *stmt;
vrange_storage *range;
exit_range *next;
+ exit_range *name_link;
};
@@ -353,8 +354,8 @@ infer_range_manager::infer_range_manager (bool do_search, range_query *q)
m_seen = NULL;
obstack_init (&m_list_obstack);
// Non-zero elements are very common, so cache them for each ssa-name.
- m_nonzero.create (0);
- m_nonzero.safe_grow_cleared (num_ssa_names + 1);
+ m_name_info.create (0);
+ m_name_info.safe_grow_cleared (num_ssa_names + 1);
m_range_allocator = new vrange_allocator;
}
@@ -362,7 +363,7 @@ infer_range_manager::infer_range_manager (bool do_search, range_query *q)
infer_range_manager::~infer_range_manager ()
{
- m_nonzero.release ();
+ m_name_info.release ();
obstack_free (&m_list_obstack, NULL);
m_on_exit.release ();
bitmap_obstack_release (&m_bitmaps);
@@ -376,15 +377,15 @@ const vrange&
infer_range_manager::get_nonzero (tree name)
{
unsigned v = SSA_NAME_VERSION (name);
- if (v >= m_nonzero.length ())
- m_nonzero.safe_grow_cleared (num_ssa_names + 20);
- if (!m_nonzero[v])
+ if (v >= m_name_info.length ())
+ m_name_info.safe_grow_cleared (num_ssa_names + 20);
+ if (!m_name_info[v].nonzero)
{
- m_nonzero[v]
+ m_name_info[v].nonzero
= (irange *) m_range_allocator->alloc (sizeof (int_range <2>));
- m_nonzero[v]->set_nonzero (TREE_TYPE (name));
+ m_name_info[v].nonzero->set_nonzero (TREE_TYPE (name));
}
- return *(m_nonzero[v]);
+ return *(m_name_info[v].nonzero);
}
// Return TRUE if NAME has a range inference in block BB. If NAME is NULL,
@@ -453,6 +454,9 @@ infer_range_manager::add_range (tree name, gimple *s, const vrange &r)
if (bb->index >= (int)m_on_exit.length ())
m_on_exit.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
+ if (SSA_NAME_VERSION (name) >= m_name_info.length ())
+ m_name_info.safe_grow_cleared (num_ssa_names + 20);
+
// Create the summary list bitmap if it doesn't exist.
if (!m_on_exit[bb->index].m_names)
m_on_exit[bb->index].m_names = BITMAP_ALLOC (&m_bitmaps);
@@ -493,6 +497,8 @@ infer_range_manager::add_range (tree name, gimple *s, const vrange &r)
ptr->name = name;
ptr->stmt = s;
ptr->next = m_on_exit[bb->index].head;
+ ptr->name_link = m_name_info[SSA_NAME_VERSION (name)].name_link;
+ m_name_info[SSA_NAME_VERSION (name)].name_link = ptr;
m_on_exit[bb->index].head = ptr;
}
@@ -538,28 +544,21 @@ infer_range_manager::register_all_uses (tree name)
void
infer_range_manager::clear(tree name)
{
- if (!m_seen)
- return;
-
// Check if this name has any inferred ranges.
unsigned v = SSA_NAME_VERSION (name);
- if (!bitmap_bit_p (m_seen, v))
- return;
+ if (v >= m_name_info.length ())
+ return;
- // Check each basic block for an inferred range.
- basic_block bb;
- FOR_EACH_BB_FN (bb, cfun)
+ exit_range *ptr = m_name_info[v].name_link;
+ for ( ; ptr ; ptr = ptr->name_link)
{
+ basic_block bb = gimple_bb (ptr->stmt);
unsigned bbi = bb->index;
- if (bbi >= m_on_exit.length ())
- continue;
- exit_range *ptr = m_on_exit[bbi].find_ptr (name);
- if (ptr)
- {
- bitmap_clear_bit (m_on_exit[bbi].m_names, v);
- ptr->name = NULL;
- }
+ bitmap_clear_bit (m_on_exit[bbi].m_names, v);
+ ptr->name = NULL;
}
- bitmap_clear_bit (m_seen, v);
+ m_name_info[v].name_link = NULL;
+ if (m_seen)
+ bitmap_clear_bit (m_seen, v);
}
diff --git a/gcc/gimple-range-infer.h b/gcc/gimple-range-infer.h
index ca95e121633..b8eced2558e 100644
--- a/gcc/gimple-range-infer.h
+++ b/gcc/gimple-range-infer.h
@@ -128,10 +128,16 @@ private:
int m_num_ranges;
exit_range *find_ptr (tree name);
};
+ class ssa_name_link
+ {
+ public:
+ vrange *nonzero;
+ exit_range *name_link;
+ };
void register_all_uses (tree name);
vec <exit_range_head> m_on_exit;
+ vec <ssa_name_link> m_name_info;
const vrange &get_nonzero (tree name);
- vec <vrange *> m_nonzero;
bitmap m_seen;
bitmap_obstack m_bitmaps;
struct obstack m_list_obstack;
--
2.45.0