On Wed Oct 14, 2026 at 3:51 PM CEST, Martin Jambor wrote:
> 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.  */
>
> ?

Sounds good to me :)

>
> ...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?

No, you are right, the comment is the other way around.  I'll update it
in this patch when I commit this, good catch.  I didn't even realize up
until now.

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

Josef

>
>
>
>>    /* 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