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;
+}
+
/* 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;
+
/* 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