On Tue, 6 Oct 2026, [email protected] wrote:

> From: Kyrylo Tkachov <[email protected]>
> 
> When can_delay_subst is false, lower_for substitutes the for-iterator
> into both the match and the result for each operator in the list.  If
> the result does not reference the iterator, replace_id still produces a
> fresh deep copy, so every iteration holds a distinct result pointer even
> though the result trees are structurally identical.  The code generator
> then emits the transform inline once per operator, bloating the output.
> 
> The existing sharing mechanism (compare_op, sinfo) already shares a
> transform across operators when can_delay_subst is true, detecting
> identical results by pointer equality.  The same mechanism works for the
> non-delayable case when the result pointer is not replaced.
> 
> Guard the replace_id call on the result with contains_id: skip the copy
> when the iterator does not appear in the result.  All iterations then
> keep result_op pointing to the original s->result, compare_op returns
> true for them, and the code generator outlines the transform once.
> 
> The main beneficiary is match.pd:3732 (combine_comparisons).  Since
> c7ebd58535a and bbc2517fe41 (2026-08-11), its outer (for bitop ...) list
> mixes tcc_binary and tcc_comparison codes, blocking delayed substitution.
> The result does not reference bitop, so without this fix every one of
> the 1764 worklist entries gets its own result copy and its own
> gimple_simplify_N function.  This patch reduces the generated GIMPLE
> matcher by about 1.2% and the GENERIC matcher by about 1.2%.
> 
> Also fix contains_id for c_expr: the previous code checked capture_ids,
> which only tracks @N-style captures, so it always returned false for
> for-iterator names.  Replace it with a scan of the CPP_NAME tokens in
> the inline C code, matching the lookup gen_transform performs at
> code-generation time.

Ah, thanks for catching that.

> 
> Bootstrapped and tested on aarch64-none-linux-gnu.
> Ok for trunk?

OK.

Thanks,
Richard.

> Thanks,
> Kyrill
> 
> gcc/ChangeLog:
> 
>       * genmatch.cc (contains_id): For c_expr, check CPP_NAME tokens
>       rather than capture_ids to detect for-iterator references.
>       (lower_for): Skip result copy in replace_id when the for-iterator
>       does not appear in the result, to preserve pointer identity and
>       enable transform sharing.
> 
> Signed-off-by: Kyrylo Tkachov <[email protected]>
> ---
>  gcc/genmatch.cc | 19 ++++++++++++++++---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> index 1d53283e094..e6065a039ef 100644
> --- a/gcc/genmatch.cc
> +++ b/gcc/genmatch.cc
> @@ -2273,7 +2273,20 @@ contains_id (operand *o, user_id *id)
>           || (ife->falseexpr && contains_id (ife->falseexpr, id)));
>  
>    if (c_expr *ce = dyn_cast<c_expr *> (o))
> -    return ce->capture_ids && ce->capture_ids->get (id->id);
> +    {
> +      /* Check whether any CPP_NAME token in the inline C code spells id->id.
> +      gen_transform looks up CPP_NAME tokens in the id substitution table,
> +      so the same check here determines whether the table needs an entry.  */
> +      for (unsigned i = 0; i < ce->code.length (); ++i)
> +     {
> +       const cpp_token *t = &ce->code[i];
> +       if (t->type == CPP_NAME
> +           && strcmp ((const char *) NODE_NAME (t->val.node.node),
> +                      id->id) == 0)
> +         return true;
> +     }
> +      return false;
> +    }
>  
>    return false;
>  }
> @@ -2460,8 +2473,8 @@ lower_for (simplify *sin, vec<simplify *>& simplifiers)
>                 if (sin->kind == simplify::SIMPLIFY
>                     || !can_delay_subst)
>                   match_op = replace_id (match_op, id, oper);
> -               if (result_op
> -                   && !can_delay_subst)
> +               if (result_op && !can_delay_subst
> +                   && contains_id (result_op, id))
>                   result_op = replace_id (result_op, id, oper);
>               }
>             if (skip)
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to