https://gcc.gnu.org/g:0209e9da17195bc064c3891fe49cbc45244290f9
commit r17-5620-g0209e9da17195bc064c3891fe49cbc45244290f9 Author: Josef Melcr <[email protected]> Date: Thu Sep 10 16:12:40 2026 +0200 Add inverted_mapping field to callback_info 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]> Diff: --- gcc/callback-info.cc | 24 ++++++++++++++++++++++-- gcc/callback-info.h | 13 ++++++++++--- gcc/cgraph.cc | 2 +- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/gcc/callback-info.cc b/gcc/callback-info.cc index a16b36424698..ec2291f3338c 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; +} + /* 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 3eecbf6f9af5..96fc1f01d249 100644 --- a/gcc/callback-info.h +++ b/gcc/callback-info.h @@ -35,10 +35,17 @@ public: parameter, we will need a separate id field. */ unsigned fn_idx; - /* Mapping from the dispatching function's arguments to the callback - function. */ + /* 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. */ auto_vec<int> arg_mapping; + /* 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. */ + auto_vec<int> inverted_mapping; + /* 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 c1bf53f6c36a..63e660262931 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;
