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
