Hi,

On Mon, Sep 21 2026, Josef Melcr wrote:
> This patch adds a new auto_vec to callback_info called inverted_mapping.
> While arg_mapping covers the indices translation from the callback's
> parameters to the actual arguments, this vector does the exact opposite.
> When working with an index of an argument, it allows us to fetch the
> index of the callback's parameter using this argument (if it exists).
> If not, it's filled with ARG_MAPPING_UNKNOWN_IDX instead.  The reverse
> translation is particularly important for ipa-sra, when associating
> argument flows with a callee's parameter.
>
> gcc/ChangeLog:
>
>       * callback-info.cc (invert_arg_mapping): New function,
>       calculates the inverted mapping.
>       (callback_info::stream_out): Stream out inverted_mapping.
>       (callback_info::stream_in): Stream in inverted mapping.
>       (callback_info::init): Use invert_arg_mapping.
>       (callback_info_sum_t::duplicate): Copy over inverted_mapping.
>       * callback-info.h: Add inverted_mapping auto_vec to
>       callback_info containing mapping from call args to callbacks
>       params.  Adjust decl of callback_info::init.
>       * cgraph.cc (cgraph_edge::make_callback): Adjust call to
>       callback_info::init.
>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/callback-info.cc | 24 ++++++++++++++++++++++--
>  gcc/callback-info.h  |  9 ++++++++-
>  gcc/cgraph.cc        |  2 +-
>  3 files changed, 31 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/callback-info.cc b/gcc/callback-info.cc
> index a16b3642469..ec2291f3338 100644
> --- a/gcc/callback-info.cc
> +++ b/gcc/callback-info.cc
> @@ -33,11 +33,27 @@
>  #include "attribs.h"
>  #include "symbol-summary.h"
>  #include "data-streamer.h"
> -#include "callback-info.h"
>  #include "attr-callback.h"
> +#include "callback-info.h"
>  
>  callback_info_sum_t *callback_info_sum = NULL;
>  
> +/* Calculates the CI->INVERTED_MAPPING field from CI->ARG_MAPPING.  */
> +static void
> +invert_arg_mapping (cgraph_edge *e, callback_info *ci)
> +{
> +  auto &mapping = ci->arg_mapping;
> +  auto &inverted_mapping = ci->inverted_mapping;
> +  unsigned num = gimple_call_num_args (e->call_stmt);
> +  inverted_mapping.reserve (num);
> +  for (unsigned i = 0; i < num; i++)
> +    inverted_mapping.quick_push (ARG_MAPPING_UNKNOWN_IDX);
> +
> +  for (unsigned i = 0; i < mapping.length (); i++)
> +    if (mapping[i] != ARG_MAPPING_UNKNOWN_IDX)
> +      inverted_mapping[mapping[i]] = i;
> +}

I wonder why this is not a member-function of callback_info but keep it
this way if that is what you prefer.

> +
>  /* Streams a vector into an output block, in format N ELEM_1 ... ELEM_N*/
>  static void
>  stream_vector_out (lto_simple_output_block *ob, const auto_vec<int> &v)
> @@ -68,6 +84,7 @@ callback_info::stream_out (lto_simple_output_block *ob) 
> const
>  {
>    streamer_write_uhwi_stream (ob->main_stream, fn_idx);
>    stream_vector_out (ob, arg_mapping);
> +  stream_vector_out (ob, inverted_mapping);
>    bitpack_d bp = bitpack_create (ob->main_stream);
>    bp_pack_value (&bp, redirected, 1);
>    streamer_write_bitpack (&bp);
> @@ -79,6 +96,7 @@ callback_info::stream_in (lto_input_block *ib)
>  {
>    fn_idx = streamer_read_uhwi (ib);
>    stream_vector_in (ib, arg_mapping);
> +  stream_vector_in (ib, inverted_mapping);
>    bitpack_d bp = streamer_read_bitpack (ib);
>    redirected = bp_unpack_value (&bp, 1);
>  }
> @@ -92,10 +110,11 @@ callback_info::get_id () const
>  }
>  
>  void
> -callback_info::init (unsigned fn_idx, tree attr)
> +callback_info::init (cgraph_edge *e, unsigned fn_idx, tree attr)
>  {
>    this->fn_idx = fn_idx;
>    arg_mapping = callback_get_arg_mapping_from_attr (attr);
> +  invert_arg_mapping (e, this);
>    redirected = false;
>  }
>  
> @@ -125,5 +144,6 @@ callback_info_sum_t::duplicate (cgraph_edge *, 
> cgraph_edge *,
>    /* Might need to be adjusted in the future, if argument modifications are
>       implemented.  */
>    dst_s->arg_mapping = src_s->arg_mapping.copy ();
> +  dst_s->inverted_mapping = src_s->inverted_mapping.copy ();
>    dst_s->redirected = src_s->redirected;
>  }
> diff --git a/gcc/callback-info.h b/gcc/callback-info.h
> index 3eecbf6f9af..75894c7a361 100644
> --- a/gcc/callback-info.h
> +++ b/gcc/callback-info.h
> @@ -39,6 +39,13 @@ public:
>       function.  */
>    auto_vec<int> arg_mapping;
>  
> +  /* Contains the inverted argument mapping.  While arg_mapping contains the
> +     mapping from the parameter's index to the argument's index,
> +     inverted_mapping is from the argument's index to the parameter's index. 
>  If
> +     the argument doesn't correspond to any of the callback's parameters, the
> +     field will contain ARG_MAPPING_UNKNOWN_IDX instead.  */
> +  auto_vec<int> inverted_mapping;
> +

I'm afraid the comment must be made more understandable.  What about

/* Mapping in the opposite direction, from indices of the actual
   arguments of the call to the dispatcher to indices of arguments in
   which they are passed to the callback or to ARG_MAPPING_UNKNOWN_IDX
   if they are not passed to the callback.  */

?

...which however makes me wonder if the description of the arg_mapping
is correct.  I guess that should be: Mapping from the indices of the
arguments passed to the callback to their indices in the call to the
dispatching function or to ARG_MAPPING_UNKNOWN_IDX if they do not
correspond to any.

Or is it me who has it backwards?

Apart from this, the patch is OK once a patch using inverted_mapping is
approved.

Martin



>    /* TRUE iff the associated callback edge was redirected.  */
>    bool redirected;
>  
> @@ -52,7 +59,7 @@ public:
>    unsigned get_id () const;
>  
>    /* Initializes the summary.  */
> -  void init (unsigned fn_idx, tree attr);
> +  void init (cgraph_edge *e, unsigned fn_idx, tree attr);
>  };
>  
>  class callback_info_sum_t : public call_summary<callback_info *>
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index c1bf53f6c36..63e66026293 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -1380,7 +1380,7 @@ cgraph_edge::make_callback (cgraph_node *n2, unsigned 
> fn_idx, tree attr)
>      e2->can_throw_external = can_throw_external;
>    e2->lto_stmt_uid = lto_stmt_uid;
>    callback_info *ci = callback_info_sum->get_create (e2);
> -  ci->init (fn_idx, attr);
> +  ci->init (e2, fn_idx, attr);
>    symtab->call_edge_duplication_hooks (this, e2);
>    n2->mark_address_taken ();
>    return e2;
> -- 
> 2.55.0

Reply via email to