Hi,

On Mon, Sep 21 2026, Josef Melcr wrote:
> This patch adds the basic logic to make the creation of callback edges
> bound to internal calls ("internal callback edges") possible.  Because
> internal calls are not usually represented in the call graph, internal
> callback edges don't have any callback-carrying edges (as opposed to
> their regular counterparts).  Internal callback edges are currently only
> meant to be used for outlined IFN_ASSUME bodies, though I tried to keep
> the logic generic enough for future expansion.
>
> Note that make_callback_internal has no uses in this patch.  The
> creation of the edges sets a lot of the logic in this patch series in
> motion, so I am saving that for a later patch.
>
> gcc/ChangeLog:
>
>       * callback-info.cc (callback_info::create_internal_summary): Add
>       implementation.
>       * callback-info.h: Add create_internal_summary method.  Creates
>       and initializes a callback summary for an internal callback edge.
>       a callback edge bound to an internal call.
>       * cgraph.cc (cgraph_edge::make_callback_internal): Add
>       implementation.
>       * cgraph.h: Add make_callback_internal method.  Creates a
>       callback edge bound to an internal call.


Just one nit...

>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/callback-info.cc | 24 ++++++++++++++++++++++++
>  gcc/callback-info.h  |  4 ++++
>  gcc/cgraph.cc        | 30 ++++++++++++++++++++++++++++++
>  gcc/cgraph.h         |  9 +++++++++
>  4 files changed, 67 insertions(+)
>
> diff --git a/gcc/callback-info.cc b/gcc/callback-info.cc
> index 95357b9c8ff..95897f376f1 100644
> --- a/gcc/callback-info.cc
> +++ b/gcc/callback-info.cc
> @@ -118,6 +118,30 @@ callback_info::init (cgraph_edge *e, unsigned fn_idx, 
> tree attr)
>    redirected = false;
>  }
>  
> +/* Initialize the summary for a callback call CBE of internal function IFN.  
> */
> +callback_info *
> +callback_info::create_internal_summary (cgraph_edge *cbe, internal_fn ifn)
> +{
> +  callback_info_sum_t::check_create_info_sum ();
> +  callback_info *ci = callback_info_sum->get_create (cbe);
> +  switch (ifn)
> +    {
> +    case IFN_ASSUME:
> +      {
> +     ci->fn_idx = 0;
> +     unsigned n = gimple_call_num_args (cbe->call_stmt);
> +     for (unsigned i = 0; i < n - 1; i++)
> +       ci->arg_mapping.safe_push (i + 1);
> +     invert_arg_mapping (cbe, ci);
> +     break;
> +      }
> +    default:
> +      gcc_unreachable ();
> +    }
> +  ci->redirected = false;
> +  return ci;
> +}
> +
>  /* Populates the callback_info_sum if it's NULL.  */
>  void
>  callback_info_sum_t::check_create_info_sum (void)
> diff --git a/gcc/callback-info.h b/gcc/callback-info.h
> index 87455ab1f76..254f336ec3f 100644
> --- a/gcc/callback-info.h
> +++ b/gcc/callback-info.h
> @@ -60,6 +60,10 @@ public:
>  
>    /* Initializes the summary.  */
>    void init (cgraph_edge *e, unsigned fn_idx, tree attr);
> +
> +  /* Create the summary for a callback call CBE of internal function IFN. */
> +  static callback_info *create_internal_summary (cgraph_edge *cbe,
> +                                              internal_fn ifn);
>  };
>  
>  class callback_info_sum_t : public call_summary<callback_info *>
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index ba596966aea..fc1d7838d5d 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -1387,6 +1387,36 @@ cgraph_edge::make_callback (cgraph_node *n2, unsigned 
> fn_idx, tree attr)
>    return e2;
>  }
>  
> +/* Create a callback edge, representing an indirect call to n2

...by n2 you mean TARGET?

> +    passed to an internal function by argument.  As internal calls are not
> +    represented in the callgraph, the created edge won't have any associated
> +    dispatching edge.  The created callback edge will be attached to the
> +    internal call statement STMT.  Returns created callback edge.  */

Returns the created callback edge.

> +
> +cgraph_edge *
> +cgraph_edge::make_callback_internal (cgraph_node *caller, cgraph_node 
> *target,
> +                                  gcall *call_stmt)
> +{
> +  cgraph_edge *ret;
> +
> +  ret
> +    = caller->create_edge (target, call_stmt, profile_count::uninitialized 
> ());
> +  if (dump_file)
> +    {
> +      fprintf (dump_file,
> +            "Created callback edge %s -> %s belonging to internal call ",
> +            ret->caller->dump_name (), ret->callee->dump_name ());
> +      print_gimple_stmt (dump_file, call_stmt, 0);
> +    }
> +  ret->inline_failed = CIF_CALLBACK_EDGE;
> +  ret->callback = true;
> +  if (TREE_NOTHROW (target->decl))
> +    ret->can_throw_external = false;
> +  target->mark_address_taken ();
> +  callback_info::create_internal_summary (ret, IFN_ASSUME);
> +  return ret;
> +}
> +
>  /* Returns the callback_carrying edge of a callback edge on which
>     it is called on or NULL when no such edge can be found.
>  
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index 0f05b5024e9..938b832d95c 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1932,6 +1932,15 @@ public:
>       edge.  */
>    cgraph_edge *make_callback (cgraph_node *n2, unsigned fn_idx, tree attr);
>  
> +  /* Create a callback edge, representing an indirect call to n2
> +     passed to an internal function by argument.  As internal calls are not
> +     represented in the callgraph, the created edge won't have any associated
> +     dispatching edge.  The created callback edge will be attached to the
> +     internal call statement STMT.  Returns created callback edge.
> */

Likewise.

Otherwise OK.

Thanks,

Martin



> +  static cgraph_edge *make_callback_internal (cgraph_node *caller,
> +                                           cgraph_node *target,
> +                                           gcall *call_stmt);
> +
>    /* Returns the callback-carrying edge of a callback edge or NULL, if such 
> edge
>       cannot be found.  An edge is considered callback-carrying, if it has 
> it's
>       has_callback flag set and shares it's call statement with the edge
> -- 
> 2.55.0

Reply via email to