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

Reply via email to