https://gcc.gnu.org/g:e1424f0b30525ced215042169035ff7c1ef5ca9d

commit r17-4006-ge1424f0b30525ced215042169035ff7c1ef5ca9d
Author: Aldy Hernandez <[email protected]>
Date:   Mon Sep 7 17:57:49 2026 +0000

    backthreader: skip blocks with no inferred ranges in 
adjust_for_non_null_uses
    
    adjust_for_non_null_uses walks every exit dependency of the path in
    every block of the path just to pick out the pointer ones, and then
    asks the infer oracle about each of them.  Since the pointer
    dependencies do not change while a path is being solved, collect them
    once.  Querying the oracle for each of them also forces it to populate
    its per-block summaries, which lets us skip the common case: a block
    with no inferred range at all.
    
    Measured in perf instructions retired over our stage1 .ii corpus, this
    drops back_threader::thread_blocks() by a further 3.6%
    (pass_thread_jumps 4.4%, pass_thread_jumps_full 3.0%,
    pass_early_thread_jumps 1.0%) and the whole compile by a further 0.05%
    over 806 TUs.  Over the three patches back_threader::thread_blocks()
    is 11.9% cheaper (pass_thread_jumps 13.6%, pass_thread_jumps_full
    9.2%, pass_early_thread_jumps 8.1%) and the whole compile 0.14%.
    
    Tested on ppc64le Linux.  The assembly is identical over the .ii
    files, so this is a NFC.
    
    gcc/ChangeLog:
    
            * gimple-range-path.h 
(path_range_query::m_pointer_exit_dependencies):
            New.
            * gimple-range-path.cc (path_range_query::adjust_for_non_null_uses):
            Walk m_pointer_exit_dependencies, and return early for a block with 
no
            inferred ranges.
            (path_range_query::compute_ranges): Fill in 
m_pointer_exit_dependencies.

Diff:
---
 gcc/gimple-range-path.cc | 34 ++++++++++++++++++++++++++--------
 gcc/gimple-range-path.h  |  3 +++
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index aa60db65f4ff..1e9f2b0be6cb 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -465,17 +465,16 @@ path_range_query::compute_ranges_in_block (basic_block bb)
 void
 path_range_query::adjust_for_non_null_uses (basic_block bb)
 {
+  // If there are no pointer exit dependencies with an inferred range, there's
+  // nothing to do.
+  if (m_pointer_exit_dependencies.is_empty ()
+      || !infer_oracle ().has_range_p (bb))
+    return;
+
   prange r;
-  bitmap_iterator bi;
-  unsigned i;
 
-  EXECUTE_IF_SET_IN_BITMAP (m_exit_dependencies, 0, i, bi)
+  for (tree name : m_pointer_exit_dependencies)
     {
-      tree name = ssa_name (i);
-
-      if (!POINTER_TYPE_P (TREE_TYPE (name)))
-       continue;
-
       if (get_cache (r, name))
        {
          if (!r.contains_zero_p ())
@@ -585,6 +584,25 @@ path_range_query::compute_ranges (const bitmap_head 
*dependencies)
   path_oracle *p = get_path_oracle ();
   p->reset_path (&(m_ranger.relation ()));
 
+  // Collect the pointer exit dependencies once per path.
+  m_pointer_exit_dependencies.truncate (0);
+  {
+    bitmap_iterator bi;
+    unsigned i;
+    EXECUTE_IF_SET_IN_BITMAP (m_exit_dependencies, 0, i, bi)
+      {
+       tree name = ssa_name (i);
+       if (POINTER_TYPE_P (TREE_TYPE (name)))
+         {
+           // Querying the infer oracle here is what populates its
+           // per-block summaries, so that adjust_for_non_null_uses can
+           // skip a block with no inferred range in it at all.
+           infer_oracle ().has_range_p (entry_bb (), name);
+           m_pointer_exit_dependencies.safe_push (name);
+         }
+      }
+  }
+
   if (DEBUG_SOLVER)
     {
       fprintf (dump_file, "path_range_query: compute_ranges for path: ");
diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h
index b6a37638a337..776227d0fb18 100644
--- a/gcc/gimple-range-path.h
+++ b/gcc/gimple-range-path.h
@@ -85,6 +85,9 @@ private:
   // Range cache for SSA names.
   ssa_lazy_cache m_cache;
 
+  // All the pointer typed exit dependencies in the path.
+  auto_vec<tree> m_pointer_exit_dependencies;
+
   // Path being analyzed.
   auto_vec<basic_block> m_path;

Reply via email to