Last version: 
(https://patchwork.sourceware.org/project/gcc/patch/[email protected]/)

Hi,
I've made the following changes since the last time I posted this patch:
 - Implemented Martin's suggestions: removed the id field, replaced it
   with a get_id method and a comment.
 - Fixed the formatting a little.
 - Me and Martin discussed removing the arg_mapping vector, but
   ultimately decided to keep it for ease of use.

Best regards,
Josef

gcc/ChangeLog:

        * Makefile.in: Add callback-info.o to OBJS.
        * attr-callback.cc (callback_fetch_attr_by_edge): Use fn_idx from
        the summary.
        (callback_get_arg_mapping): Replaced by
        callback_get_arg_mapping_from_attr and the summary field.
        (callback_get_arg_mapping_from_attr): New function, parses the
        attr and returns the computed argument mapping.
        (callback_fetch_fn_position): Delete, obsoleted by the summary.
        (callback_edge_useful_p): Check for the redirected flag in the
        summary instead of the cgraph_node fields.
        * attr-callback.h (enum callback_position): Add
        CB_UNKNOWN_POS_IDX for better readability.
        (callback_get_arg_mapping): Delete.
        (callback_fetch_fn_position): Delete.
        (callback_get_arg_mapping_from_attr): Add decl.
        * cgraph.cc (symbol_table::create_edge): Remove callback_id
        initializer.
        (cgraph_edge::make_callback): Likewise.
        (cgraph_edge::redirect_callee): Set the redirected flag when
        redirecting a callback edge.
        (cgraph_edge::redirect_call_stmt_to_callee): Use the summary.
        (cgraph_node::verify_node): Remove callback_id checks.
        (cgraph_cc_finalize): Free the summaries.
        * cgraph.h: Remove callback_id from cgraph_edge.
        * cgraphclones.cc (cgraph_edge::clone): Remove callback_id.
        * ipa-cp.cc (ipcp_driver): Initialize the summary sum.
        * ipa-prop.cc (init_callback_edge_summary): Initialize the summary.
        (ipa_compute_jump_functions_for_edge): Remove callback_id, use
        the summary.
        (ipa_analyze_node): Initialize the summary sum.
        (ipa_register_cgraph_hooks): Likewise.
        * lto-cgraph.cc (lto_output_edge): Remove callback_id, stream
        out the summary.
        (output_symtab): Initialize the summary sum.
        (input_edge): Remove callback_id, stream in the summary.
        (input_cgraph_1): Initialize the summary sum.
        * callback-info.cc: New file.
        * callback-info.h: New file.

Signed-off-by: Josef Melcr <[email protected]>
---
 gcc/Makefile.in      |   1 +
 gcc/attr-callback.cc |  42 +++++------------
 gcc/attr-callback.h  |  17 +++----
 gcc/callback-info.cc | 108 +++++++++++++++++++++++++++++++++++++++++++
 gcc/callback-info.h  |  75 ++++++++++++++++++++++++++++++
 gcc/cgraph.cc        |  25 ++++------
 gcc/cgraph.h         |   6 +--
 gcc/cgraphclones.cc  |   1 -
 gcc/ipa-cp.cc        |   3 ++
 gcc/ipa-prop.cc      |  29 +++++++-----
 gcc/lto-cgraph.cc    |  17 ++++++-
 11 files changed, 248 insertions(+), 76 deletions(-)
 create mode 100644 gcc/callback-info.cc
 create mode 100644 gcc/callback-info.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0863a72c7d3..4180dc20434 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1868,6 +1868,7 @@ OBJS = \
        wide-int.o \
        wide-int-print.o \
        attr-callback.o \
+       callback-info.o \
        $(out_object_file) \
        $(ANALYZER_OBJS) \
        $(EXTRA_OBJS) \
diff --git a/gcc/attr-callback.cc b/gcc/attr-callback.cc
index c654d74164d..ec89974532c 100644
--- a/gcc/attr-callback.cc
+++ b/gcc/attr-callback.cc
@@ -31,7 +31,10 @@
 #include "options.h"
 #include "gimple-range.h"
 #include "attribs.h"
+#include "symbol-summary.h"
+#include "lto-streamer.h"
 #include "attr-callback.h"
+#include "callback-info.h"
 
 /* Returns a callback attribute with callback index FN_IDX, and ARG_COUNT
    arguments specified by VA_ARGS.  */
@@ -116,12 +119,13 @@ callback_fetch_attr_by_edge (cgraph_edge *e, cgraph_edge 
*carrying)
   tree cb_attr = lookup_attribute (CALLBACK_ATTR_IDENT,
                                   DECL_ATTRIBUTES (carrying->callee->decl));
   gcc_checking_assert (cb_attr);
+  callback_info *ci = callback_info_sum->get (e);
   tree res = NULL_TREE;
   for (; cb_attr;
        cb_attr = lookup_attribute (CALLBACK_ATTR_IDENT, TREE_CHAIN (cb_attr)))
     {
-      unsigned id = callback_get_fn_index (cb_attr);
-      if (id == e->callback_id)
+      unsigned fn_idx = callback_get_fn_index (cb_attr);
+      if (fn_idx == ci->get_id ())
        {
          res = cb_attr;
          break;
@@ -131,15 +135,11 @@ callback_fetch_attr_by_edge (cgraph_edge *e, cgraph_edge 
*carrying)
   return res;
 }
 
-/* Given an instance of callback attribute, return the 0-base indices
-   of arguments passed to the callback.  For a callback function taking
-   n parameters, returns a vector of n indices of their values in the parameter
-   list of it's caller.  Indices with unknown positions contain -1.  */
+/* Returns the argument mapping from the dispatching function to the callback
+   function parsed from the attribute.  */
 auto_vec<int>
-callback_get_arg_mapping (cgraph_edge *e, cgraph_edge *carrying)
+callback_get_arg_mapping_from_attr (tree attr)
 {
-  tree attr = callback_fetch_attr_by_edge (e, carrying);
-  gcc_checking_assert (attr);
   tree args = TREE_VALUE (attr);
   auto_vec<int> res;
   tree it;
@@ -158,15 +158,6 @@ callback_get_arg_mapping (cgraph_edge *e, cgraph_edge 
*carrying)
   return res;
 }
 
-/* For a callback pair, returns the 0-based index of the address of
-   E's callee in the argument list of CARRYING's callee decl.  */
-int
-callback_fetch_fn_position (cgraph_edge *e, cgraph_edge *carrying)
-{
-  tree attr = callback_fetch_attr_by_edge (e, carrying);
-  return callback_get_fn_index (attr);
-}
-
 /* Returns the element at index idx in the list or NULL_TREE if
    the list isn't long enough.  NULL_TREE is used as the endpoint.  */
 static tree
@@ -353,19 +344,8 @@ bool
 callback_edge_useful_p (cgraph_edge *e)
 {
   gcc_checking_assert (e->callback);
-  /* If the edge is pointing towards a clone, it is useful.  */
-  if (e->callee->clone_of)
-    return true;
-
-  /* If the callee has been produced by icf, the edge is useful, as it will be
-     used to for the redirection.  */
-  if (e->callee->icf_merged)
-    return true;
-
-  /* In case some future pass redirects edges, it should be added as a case
-     here.  */
-
-  return false;
+  callback_info *ci = callback_info_sum->get (e);
+  return ci->redirected;
 }
 
 /* Returns the number of arguments the callback function described by ATTR
diff --git a/gcc/attr-callback.h b/gcc/attr-callback.h
index b2c1c3c09c5..8f649006b8c 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -25,7 +25,10 @@ enum callback_position
 {
   /* Value used when an argument of a callback function
      is unknown or when multiple values may be used. */
-  CB_UNKNOWN_POS = 0
+  CB_UNKNOWN_POS = 0,
+  /* Value representing an unknown argument position in the arg_mapping
+     vector.  */
+  CB_UNKNOWN_POS_IDX = -1
 };
 
 #define CALLBACK_ATTR_IDENT " callback"
@@ -54,15 +57,9 @@ int callback_get_fn_index (tree cb_attr);
    to create E from the callee of CARRYING.  */
 tree callback_fetch_attr_by_edge (cgraph_edge *e, cgraph_edge *carrying);
 
-/* Given an instance of callback attribute, return the 0-base indices
-   of arguments passed to the callback.  For a callback function taking
-   n parameters, returns a vector of n indices of their values in the parameter
-   list of it's caller.  Indices with unknown positions contain -1.  */
-auto_vec<int> callback_get_arg_mapping (cgraph_edge *e, cgraph_edge *carrying);
-
-/* For a callback pair, returns the 0-based index of the address of
-   E's callee in the argument list of CARRYING's callee decl.  */
-int callback_fetch_fn_position (cgraph_edge *e, cgraph_edge *carrying);
+/* Returns the argument mapping from the dispatching function to the callback
+   function parsed from the attribute.  */
+auto_vec<int> callback_get_arg_mapping_from_attr (tree attr);
 
 /* Handle a "callback" attribute; arguments as in
    struct attribute_spec.handler.  */
diff --git a/gcc/callback-info.cc b/gcc/callback-info.cc
new file mode 100644
index 00000000000..5309d763936
--- /dev/null
+++ b/gcc/callback-info.cc
@@ -0,0 +1,108 @@
+/* Callback attribute summary
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   Contributed by Josef Melcr <[email protected]>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "alloc-pool.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "builtins.h"
+#include "options.h"
+#include "gimple-range.h"
+#include "attribs.h"
+#include "symbol-summary.h"
+#include "data-streamer.h"
+#include "callback-info.h"
+
+callback_info_sum_t *callback_info_sum = NULL;
+
+/* Stream out callback_info.  */
+void
+callback_info::stream_out (lto_simple_output_block *ob) const
+{
+  streamer_write_uhwi_stream (ob->main_stream, fn_idx);
+  streamer_write_uhwi_stream (ob->main_stream, arg_mapping.length ());
+
+  for (int idx : arg_mapping)
+    streamer_write_hwi_stream (ob->main_stream, idx);
+
+  bitpack_d bp = bitpack_create (ob->main_stream);
+  bp_pack_value (&bp, redirected, 1);
+  streamer_write_bitpack (&bp);
+}
+
+/* Stream in callback_info.  */
+void
+callback_info::stream_in (lto_input_block *ib)
+{
+  fn_idx = streamer_read_uhwi (ib);
+  unsigned length = streamer_read_uhwi (ib);
+  arg_mapping.reserve (length);
+
+  for (unsigned i = 0; i < length; i++)
+    {
+      int idx = streamer_read_hwi (ib);
+      arg_mapping.safe_push (idx);
+    }
+
+  bitpack_d bp = streamer_read_bitpack (ib);
+  redirected = bp_unpack_value (&bp, 1);
+}
+
+/* Returns the id of the associated callback attribute.  See the comment of the
+   fn_idx field.  */
+unsigned
+callback_info::get_id () const
+{
+  return fn_idx;
+}
+
+/* Populates the callback_info_sum if it's NULL.  */
+void
+callback_info_sum_t::check_create_info_sum (void)
+{
+  if (!callback_info_sum)
+    callback_info_sum = new callback_info_sum_t (symtab, false);
+}
+
+/* Frees the callback_info_sum pointer.  */
+void
+callback_info_sum_t::free_info_sum (void)
+{
+  if (callback_info_sum)
+    delete callback_info_sum;
+  callback_info_sum = NULL;
+}
+
+/* Duplication function for the cgraph_edge duplication hook.  */
+void
+callback_info_sum_t::duplicate (cgraph_edge *, cgraph_edge *,
+                               callback_info *src_s, callback_info *dst_s)
+{
+  dst_s->fn_idx = src_s->fn_idx;
+  /* Might need to be adjusted in the future, if argument modifications are
+     implemented.  */
+  dst_s->arg_mapping = src_s->arg_mapping.copy ();
+  dst_s->redirected = src_s->redirected;
+}
diff --git a/gcc/callback-info.h b/gcc/callback-info.h
new file mode 100644
index 00000000000..2443fa426e6
--- /dev/null
+++ b/gcc/callback-info.h
@@ -0,0 +1,75 @@
+/* Callback attribute summary
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   Contributed by Josef Melcr <[email protected]>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef CALLBACK_INFO_H
+#define CALLBACK_INFO_H
+
+/* Summary aggregating all information relevant to callback edges.  Most of the
+   information can be calculated from the attribute as well, but keeping it
+   separate allows us to modify the info without touching the underlying
+   attribute.  */
+class callback_info
+{
+public:
+  /* Index of the callback function in the argument list.  Currently also used
+     as an id for the callback attribute of the function (needed if a function
+     has multiple callback attributes).  This limits us to a single callback
+     attribute per parameter.  If we want to allow multiple attributes per
+     parameter, we will need a separate id field.  */
+  unsigned fn_idx;
+
+  /* Mapping from the dispatching function's arguments to the callback
+     function.  */
+  auto_vec<int> arg_mapping;
+
+  /* TRUE iff the associated callback edge was redirected.  */
+  bool redirected;
+
+  /* Stream in callback_info.  */
+  void stream_in (lto_input_block *ib);
+
+  /* Stream out callback_info.  */
+  void stream_out (lto_simple_output_block *ib) const;
+
+  /* Returns the id of the associated callback attribute.  */
+  unsigned get_id () const;
+};
+
+class callback_info_sum_t : public call_summary<callback_info *>
+{
+public:
+  callback_info_sum_t (symbol_table *table, bool ggc)
+    : call_summary<callback_info *> (table, ggc)
+  {}
+
+  /* Populates the callback_info_sum if it's NULL.  */
+  static void check_create_info_sum ();
+
+  /* Frees the callback_info_sum pointer.  */
+  static void free_info_sum ();
+
+  /* Duplication function for the cgraph_edge duplication hook.  */
+  void duplicate (cgraph_edge *src, cgraph_edge *dst, callback_info *src_s,
+                 callback_info *dst_s) override;
+};
+
+extern callback_info_sum_t *callback_info_sum;
+
+#endif /* CALLBACK_INFO_H */
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 13ea9c34629..b43a249938d 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -70,6 +70,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-thunks.h"
 #include "symtab-clones.h"
 #include "attr-callback.h"
+#include "callback-info.h"
 
 /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  
*/
 #include "tree-pass.h"
@@ -1107,7 +1108,6 @@ symbol_table::create_edge (cgraph_node *caller, 
cgraph_node *callee,
   edge->speculative = false;
   edge->has_callback = false;
   edge->callback = false;
-  edge->callback_id = 0;
   edge->indirect_unknown_callee = indir_unknown_callee;
   if (call_stmt && caller->call_site_hash)
     cgraph_add_edge_to_call_site_hash (edge);
@@ -1356,13 +1356,10 @@ cgraph_edge::make_speculative (cgraph_node *n2, 
profile_count direct_count,
    the callback-carrying edge, which is the instance this method
    is called on.
 
-   callback_id is used to pair the returned edge with the attribute that
-   originated it.
-
    Return the resulting callback edge.  */
 
 cgraph_edge *
-cgraph_edge::make_callback (cgraph_node *n2, unsigned int callback_id)
+cgraph_edge::make_callback (cgraph_node *n2)
 {
   cgraph_node *n = caller;
   cgraph_edge *e2;
@@ -1377,7 +1374,6 @@ cgraph_edge::make_callback (cgraph_node *n2, unsigned int 
callback_id)
       callee->dump_name ());
   e2->inline_failed = CIF_CALLBACK_EDGE;
   e2->callback = true;
-  e2->callback_id = callback_id;
   if (TREE_NOTHROW (n2->decl))
     e2->can_throw_external = false;
   else
@@ -1708,7 +1704,7 @@ cgraph_edge::redirect_callee (cgraph_node *n)
       /* When redirecting a callback callee, redirect its ref as well.  */
       ipa_ref *old_ref = caller->find_reference (old_callee, call_stmt,
                                                 lto_stmt_uid, IPA_REF_ADDR);
-      gcc_checking_assert(old_ref);
+      gcc_checking_assert (old_ref);
       old_ref->remove_reference ();
       ipa_ref *new_ref = caller->create_reference (n, IPA_REF_ADDR, call_stmt);
       new_ref->lto_stmt_uid = lto_stmt_uid;
@@ -1718,6 +1714,8 @@ cgraph_edge::redirect_callee (cgraph_node *n)
       if (!old_callee->iterate_referring (0, old_ref))
        old_callee->address_taken = 0;
       n->mark_address_taken ();
+      callback_info *ci = callback_info_sum->get (this);
+      ci->redirected = true;
     }
 
   if (!inline_failed)
@@ -1849,11 +1847,11 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge 
*e,
           signature, as the indices wouldn't be correct anymore.  These edges
           will get cleaned up later, ignore their redirection for now.  */
        return e->call_stmt;
-      int fn_idx = callback_fetch_fn_position (e, carrying);
-      tree previous_arg = gimple_call_arg (e->call_stmt, fn_idx);
+      callback_info *ci = callback_info_sum->get (e);
+      tree previous_arg = gimple_call_arg (e->call_stmt, ci->fn_idx);
       location_t loc = EXPR_LOCATION (previous_arg);
       tree new_addr = build_fold_addr_expr_loc (loc, e->callee->decl);
-      gimple_call_set_arg (e->call_stmt, fn_idx, new_addr);
+      gimple_call_set_arg (e->call_stmt, ci->fn_idx, new_addr);
       return e->call_stmt;
     }
 
@@ -4390,12 +4388,6 @@ cgraph_node::verify_node (void)
 
       for (e = callees; e; e = e->next_callee)
        {
-         if (!e->callback && e->callback_id)
-           {
-             error ("non-callback edge has callback_id set");
-             error_found = true;
-           }
-
          if (e->callback && e->has_callback)
            {
              error ("edge has both callback and has_callback set");
@@ -4718,6 +4710,7 @@ cgraph_cc_finalize (void)
   nested_function_info::release ();
   thunk_info::release ();
   clone_info::release ();
+  callback_info_sum_t::free_info_sum ();
   symtab = NULL;
 
   x_cgraph_nodes_queue = NULL;
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a7e6ab70b6b..ec7112452da 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1926,7 +1926,7 @@ public:
      passed to a function by argument.  Sets has_callback flag of the original
      edge. Both edges are attached to the same call statement.  Returns created
      callback edge.  */
-  cgraph_edge *make_callback (cgraph_node *n2, unsigned int callback_hash);
+  cgraph_edge *make_callback (cgraph_node *n2);
 
   /* 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
@@ -2182,10 +2182,6 @@ public:
      that the callee of this edge takes a function and it's parameters by
      argument and calls it at a later time.  */
   unsigned int has_callback : 1;
-  /* Used to pair callback edges and the attributes that originated them
-     together.  Currently the index of the callback argument, retrieved
-     from the attribute.  */
-  unsigned int callback_id : 16;
   /* Set to true when caller is a constructor or destructor of polymorphic
      type.  */
   unsigned in_polymorphic_cdtor : 1;
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 180ef4e52c8..b5f2ce5ff2f 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -161,7 +161,6 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, 
unsigned stmt_uid,
   new_edge->speculative = speculative;
   new_edge->callback = callback;
   new_edge->has_callback = has_callback;
-  new_edge->callback_id = callback_id;
   new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
 
   /* Update IPA profile.  Local profiles need no updating in original.  */
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 9e0b698b8cb..b23fc0e59ab 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -132,6 +132,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-clones.h"
 #include "gimple-range.h"
 #include "attr-callback.h"
+#include "lto-streamer.h"
+#include "callback-info.h"
 
 /* Allocation pools for values and their sources in ipa-cp.  */
 
@@ -6759,6 +6761,7 @@ ipcp_driver (void)
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
+  callback_info_sum_t::check_create_info_sum ();
   clone_num_suffixes = new hash_map<const char *, unsigned>;
 
   if (dump_file)
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 330c8a39e5b..233700581f6 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "attribs.h"
 #include "attr-callback.h"
+#include "callback-info.h"
 
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
@@ -2484,12 +2485,16 @@ skip_a_safe_conversion_op (tree t)
    This primarily means allocating the correct amount of jump functions.  */
 
 static inline void
-init_callback_edge_summary (struct cgraph_edge *cbe, tree attr)
+init_callback_edge_summary (struct cgraph_edge *cbe, unsigned fn_idx, tree 
attr)
 {
+  callback_info *ci = callback_info_sum->get_create (cbe);
+  ci->fn_idx = fn_idx;
+  ci->arg_mapping = callback_get_arg_mapping_from_attr (attr);
+  ci->redirected = false;
+
   ipa_edge_args *cb_args = ipa_edge_args_sum->get_create (cbe);
-  size_t jf_vec_length = callback_num_args(attr);
-  vec_safe_grow_cleared (cb_args->jump_functions,
-                        jf_vec_length, true);
+  vec_safe_grow_cleared (cb_args->jump_functions, ci->arg_mapping.length (),
+                        true);
 }
 
 /* Compute jump function for all arguments of callsite CS and insert the
@@ -2637,10 +2642,10 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
                    {
                      cgraph_node *kernel_node
                        = cgraph_node::get_create (pointee);
-                     unsigned callback_id = n;
-                     cgraph_edge *cbe
-                       = cs->make_callback (kernel_node, callback_id);
-                     init_callback_edge_summary (cbe, callback_attr);
+                     cgraph_edge *cbe = cs->make_callback (kernel_node);
+                     /* Callbck attribute's id is currently the function's
+                        index.  */
+                     init_callback_edge_summary (cbe, n, callback_attr);
                      callback_edges.safe_push (cbe);
                    }
                }
@@ -2716,12 +2721,12 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
          cgraph_edge *callback_edge = callback_edges[j];
          ipa_edge_args *cb_summary
            = ipa_edge_args_sum->get_create (callback_edge);
-         auto_vec<int> arg_mapping
-           = callback_get_arg_mapping (callback_edge, cs);
+         callback_info *ci = callback_info_sum->get (callback_edge);
+         auto_vec<int> &arg_mapping = ci->arg_mapping;
          unsigned i;
          for (i = 0; i < arg_mapping.length (); i++)
            {
-             if (arg_mapping[i] == -1)
+             if (arg_mapping[i] == CB_UNKNOWN_POS_IDX)
                continue;
              class ipa_jump_func *src
                = ipa_get_ith_jump_func (args, arg_mapping[i]);
@@ -3595,6 +3600,7 @@ ipa_analyze_node (struct cgraph_node *node)
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
+  callback_info_sum_t::check_create_info_sum ();
   info = ipa_node_params_sum->get_create (node);
 
   if (info->analysis_done)
@@ -5211,6 +5217,7 @@ ipa_register_cgraph_hooks (void)
 {
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
+  callback_info_sum_t::check_create_info_sum ();
 
   function_insertion_hook_holder =
       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 9a71110d5c2..adbf59ca821 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "symbol-summary.h"
 #include "symtab-thunks.h"
 #include "symtab-clones.h"
+#include "callback-info.h"
 
 static void output_cgraph_opt_summary (void);
 static void input_cgraph_opt_summary (vec<symtab_node *>  nodes);
@@ -278,7 +279,6 @@ lto_output_edge (struct lto_simple_output_block *ob, struct 
cgraph_edge *edge,
   bp_pack_value (&bp, edge->speculative, 1);
   bp_pack_value (&bp, edge->callback, 1);
   bp_pack_value (&bp, edge->has_callback, 1);
-  bp_pack_value (&bp, edge->callback_id, 16);
   bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
   gcc_assert (!edge->call_stmt_cannot_inline_p
              || edge->inline_failed != CIF_BODY_NOT_AVAILABLE);
@@ -306,6 +306,11 @@ lto_output_edge (struct lto_simple_output_block *ob, 
struct cgraph_edge *edge,
                     16);
     }
   streamer_write_bitpack (&bp);
+  if (edge->callback)
+    {
+      callback_info *ci = callback_info_sum->get (edge);
+      ci->stream_out (ob);
+    }
 }
 
 /* Return if NODE contain references from other partitions.  */
@@ -1061,6 +1066,7 @@ output_symtab (void)
        lto_output_varpool_node (ob, vnode, encoder);
     }
 
+  callback_info_sum_t::check_create_info_sum ();
   /* Go over the nodes in SET again to write edges.  */
   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
@@ -1585,7 +1591,13 @@ input_edge (class lto_input_block *ib, vec<symtab_node 
*> nodes,
   edge->speculative = bp_unpack_value (&bp, 1);
   edge->callback = bp_unpack_value(&bp, 1);
   edge->has_callback = bp_unpack_value(&bp, 1);
-  edge->callback_id = bp_unpack_value(&bp, 16);
+
+  if (edge->callback)
+    {
+      callback_info *ci = callback_info_sum->get_create (edge);
+      ci->stream_in (ib);
+    }
+
   edge->lto_stmt_uid = stmt_id;
   edge->speculative_id = speculative_id;
   edge->inline_failed = inline_failed;
@@ -1643,6 +1655,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
   tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
   file_data->order_base = symtab->order;
   file_data->unit_base = symtab->max_unit + 1;
+  callback_info_sum_t::check_create_info_sum ();
   while (tag)
     {
       if (tag == LTO_symtab_edge)
-- 
2.54.0

Reply via email to