Hello,

On Mon, Dec 01 2025, Josef Melcr wrote:
> Hi,
> this is the second version of this patch (v1:
> https://gcc.gnu.org/pipermail/gcc-patches/2025-December/702502.html).
> I fixed the formatting issues and added the missing comment in
> cgraph.cc for callback_called_p.  I haven't retested it, since
> these changes should have no effect on the correctness of this patch.
>
> Best regards,
> Josef
>
> gcc/ChangeLog:
>
>       PR ipa/122798
>       * cgraph.cc (cgraph_edge::redirect_callee): Set address taken
>       for new callee.
>       (cgraph_node::callback_called_p): New function.
>       * cgraph.h (struct cgraph_node): Likewise.
>       * cgraphclones.cc (cgraph_node::create_virtual_clone): Set local
>       flag to false when cloning a function with a callback call.
>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/cgraph.cc       | 12 ++++++++++++
>  gcc/cgraph.h        |  3 +++
>  gcc/cgraphclones.cc |  4 ++++
>  3 files changed, 19 insertions(+)
>
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index 3c21e174943..e643b6a61df 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -1698,6 +1698,7 @@ cgraph_edge::redirect_callee (cgraph_node *n)
>        new_ref->lto_stmt_uid = lto_stmt_uid;
>        if (!old_callee->referred_to_p ())
>       old_callee->address_taken = 0;
> +      n->mark_address_taken ();

this is OK.

>      }
>  
>    if (!inline_failed)
> @@ -3575,6 +3576,17 @@ cgraph_node::only_called_directly_p (void)
>                                      NULL, true);
>  }
>  
> +/* Return TRUE if the node has at least one callback edge pointing to it.  */
> +
> +bool
> +cgraph_node::callback_called_p () const
> +{
> +  cgraph_edge *e;
> +  for (e = callers; e; e = e->next_caller)
> +    if (e->callback)
> +      return true;
> +  return false;
> +}
>  
>  /* Collect all callers of NODE.  Worker for collect_callers_of_node.  */
>  
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index 313610fbe2c..b534a470b77 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1278,6 +1278,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : 
> public symtab_node
>       it is not used in any other non-standard way.  */
>    bool only_called_directly_p (void);
>  
> +  /* Return TRUE if the node has at least one callback edge pointing to it.  
> */
> +  bool callback_called_p (void) const;
> +
>    /* Turn profile to global0.  Walk into inlined functions.  */
>    void make_profile_local ();
>  
> diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
> index 49f0e58fa1e..3cfbfec4c1a 100644
> --- a/gcc/cgraphclones.cc
> +++ b/gcc/cgraphclones.cc
> @@ -687,6 +687,7 @@ cgraph_node::create_virtual_clone (const vec<cgraph_edge 
> *> &redirect_callers,
>                          clone_function_name (old_decl, suffix, num_suffix));
>    SET_DECL_RTL (new_decl, NULL);
>  
> +  bool has_callback_call = callback_called_p ();
>    new_node = create_clone (new_decl, count, false,
>                          redirect_callers, false, NULL, param_adjustments,
>                          suffix);
> @@ -697,6 +698,9 @@ cgraph_node::create_virtual_clone (const vec<cgraph_edge 
> *> &redirect_callers,
>       ??? We cannot use COMDAT linkage because there is no
>       ABI support for this.  */
>    set_new_clone_decl_and_node_flags (new_node);
> +  if (has_callback_call)
> +    /* Callback clone can never be local, since it has its address taken.  */
> +    new_node->local = false;

But over here we are basically setting the flag once again after it was
already set by the code you added in the first hunk because
set_new_clone_decl_and_node_flags cleared it, right?

I think the better solution is to change
set_new_clone_decl_and_node_flags to look if there are any references to
the new node (IIUC there should be, cgraph_edge::redirect_callee already
helpfully creates them) and if so, set the flag rather than clear it.

Thanks,

Martin

Reply via email to