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

commit r17-4988-gfd35294ab1dfd4b0bff5fe6a66d383d7cc91f411
Author: Kyrylo Tkachov <[email protected]>
Date:   Tue Sep 29 16:58:50 2026 +0200

    cprop: Substitute the setter into the jump once per block [PR127661]
    
    bypass_block substitutes the source of SETCC into the condition of JUMP
    for every incoming edge and register that it tries.  The result does
    not depend on the edge, but each substitution allocates new RTL.  For
    the testcase of the PR, which has N tests, this happens about N*N/2
    times, and after the previous patches it makes most of the garbage that
    cprop allocates.
    
    JUMP only changes when an edge from BB itself is redirected.  With
    SETCC that never happens, because the new destination is a successor of
    BB and the find_edge (e->src, dest) check then rejects the redirection.
    So this patch does the substitution once, before the loop over the
    incoming edges.  When the known register value decides the jump, the
    substitution in the loop then returns one arm of the jump without
    allocating.
    
    For the testcase at N=2048 on Grace this cuts the memory that cprop
    allocates by 77%, the peak memory use by 47% and the compile time by a
    further 8%.  The generated code does not change.  The tests added by
    the first patch exercise the new code.
    
    Bootstrapped and tested as a series on aarch64-linux-gnu and
    x86_64-linux-gnu.
    
    gcc/ChangeLog:
    
            PR rtl-optimization/127661
            * cprop.cc (bypass_block): Substitute SETCC into the source of
            JUMP once, before the loop over the incoming edges.
    
    Signed-off-by: Kyrylo Tkachov <[email protected]>

Diff:
---
 gcc/cprop.cc | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/cprop.cc b/gcc/cprop.cc
index 2db8990e634c..8dc30c7537b5 100644
--- a/gcc/cprop.cc
+++ b/gcc/cprop.cc
@@ -1635,6 +1635,15 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn 
*jump)
          }
     }
 
+  /* The source of JUMP with SETCC substituted into it.  JUMP only changes
+     when an edge from BB itself is redirected.  With SETCC that never
+     happens, because DEST is a successor of BB (see the check of
+     find_edge (e->src, dest) below).  Without SETCC, SRC is the source
+     of JUMP itself.  */
+  rtx src = SET_SRC (pc_set (jump));
+  if (setcc != NULL)
+    src = simplify_replace_rtx (src, setcc_dest, setcc_src);
+
   change = false;
   for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
     {
@@ -1669,7 +1678,7 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn 
*jump)
          unsigned int regno = REGNO (reg_used);
          basic_block dest, old_dest;
          struct cprop_expr *set;
-         rtx src, new_rtx;
+         rtx new_rtx;
 
          set = find_bypass_set (regno, e->src->index);
 
@@ -1680,11 +1689,6 @@ bypass_block (basic_block bb, rtx_insn *setcc, rtx_insn 
*jump)
          if (e->insns.r && reg_killed_on_edge (reg_used, e))
            continue;
 
-         src = SET_SRC (pc_set (jump));
-
-         if (setcc != NULL)
-           src = simplify_replace_rtx (src, setcc_dest, setcc_src);
-
          new_rtx = simplify_replace_rtx (src, reg_used, set->src);
 
          /* Jump bypassing may have already placed instructions on

Reply via email to