https://gcc.gnu.org/g:6481867ae01355a2fbf296561daee9af0376f736

commit r17-3257-g6481867ae01355a2fbf296561daee9af0376f736
Author: Josef Melcr <[email protected]>
Date:   Tue Aug 11 10:35:16 2026 +0200

    ipa: Implement a summary for callback edges
    
    Currently in trunk, every edge contains a 16 bit field called
    callback_id, which is used to link callback edges to their attributes,
    from which all additional information is calculated as is needed.
    
    This patch adds a new summary struct for callback edges, called
    callback_info.  It allows us to remove callback_id from the main class
    and aggregate all relevant information, without having to recalculate it
    every single time.
    
    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 cgraph_node fields.
            * attr-callback.h (enum callback_position): Add comment.
            (enum arg_mapping_constants): New enum, defines the identifier
            for -1 in the arg_mapping vector.
            (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): Initialize the callback_info
            summary, add necessary arguments.
            (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, adjust decl of
            cgraph_edge::make_callback.
            * cgraphclones.cc (cgraph_edge::clone): Remove callback_id.
            * ipa-cp.cc (ipcp_driver): Initialize the summary sum.
            * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Remove
            callback_id, adjust call to make_callback, 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]>

Diff:
---
 gcc/Makefile.in      |   1 +
 gcc/attr-callback.cc |  46 ++++++--------------
 gcc/attr-callback.h  |  23 ++++++----
 gcc/callback-info.cc | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/callback-info.h  |  78 ++++++++++++++++++++++++++++++++++
 gcc/cgraph.cc        |  28 ++++++------
 gcc/cgraph.h         |  10 ++---
 gcc/cgraphclones.cc  |   1 -
 gcc/ipa-cp.cc        |   3 ++
 gcc/ipa-prop.cc      |  12 +++---
 gcc/lto-cgraph.cc    |  17 +++++++-
 11 files changed, 265 insertions(+), 71 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ee2f9022eab7..ce5894767fea 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 19a8770707b4..376a17e82b40 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_only",
                                   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_only", 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;
@@ -150,23 +150,14 @@ callback_get_arg_mapping (cgraph_edge *e, cgraph_edge 
*carrying)
     {
       int idx = TREE_INT_CST_LOW (TREE_VALUE (it));
       /* Subtract 1 to account for 1-based indexing.  If the value is unknown,
-        use constant -1 instead.  */
-      idx = idx == CB_UNKNOWN_POS ? -1 : idx - 1;
+        use ARG_MAPPING_UNKNOWN_IDX instead.  */
+      idx = idx == CB_UNKNOWN_POS ? ARG_MAPPING_UNKNOWN_IDX : idx - 1;
       res.safe_push (idx);
     }
 
   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 TRUE if E is considered useful in the callgraph, FALSE otherwise.  
If
    this predicate returns FALSE, then E wasn't used to optimize its callee and
    can be safely removed from the callgraph.  */
@@ -174,19 +165,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 5ed93b3afefc..baefa8701b9e 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -21,6 +21,8 @@
 #ifndef ATTR_CALLBACK_H
 #define ATTR_CALLBACK_H
 
+/* This enum relates to the attribute's arguments.  */
+
 enum callback_position
 {
   /* Value used when an argument of a callback function
@@ -28,6 +30,15 @@ enum callback_position
   CB_UNKNOWN_POS = 0
 };
 
+/* This enum describes values present in the arg_mapping vector.  */
+
+enum arg_mapping_constants
+{
+  /* Value representing an unknown argument position in the arg_mapping
+     vector.  */
+  ARG_MAPPING_UNKNOWN_IDX = -1
+};
+
 /* Returns a callback attribute with callback index FN_IDX, and ARG_COUNT
    arguments specified by VA_ARGS.  */
 tree callback_build_attr (unsigned fn_idx, unsigned arg_count...);
@@ -52,15 +63,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);
 
 /* Returns TRUE if E is considered useful in the callgraph, FALSE otherwise.  
If
    this predicate returns FALSE, then E wasn't used to optimize its callee and
diff --git a/gcc/callback-info.cc b/gcc/callback-info.cc
new file mode 100644
index 000000000000..b277f37154e0
--- /dev/null
+++ b/gcc/callback-info.cc
@@ -0,0 +1,117 @@
+/* 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"
+#include "attr-callback.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;
+}
+
+void
+callback_info::init (unsigned fn_idx, tree attr)
+{
+  this->fn_idx = fn_idx;
+  arg_mapping = callback_get_arg_mapping_from_attr (attr);
+  redirected = false;
+}
+
+/* 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 000000000000..3eecbf6f9af5
--- /dev/null
+++ b/gcc/callback-info.h
@@ -0,0 +1,78 @@
+/* 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;
+
+  /* Initializes the summary.  */
+  void init (unsigned fn_idx, tree attr);
+};
+
+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 da770ccc4af7..cdb3201f49ce 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,13 @@ 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.
+   FN_IDX is the index of the callback function in dispatching function's
+   argument list.  ATTR is the attribute used to derive the edge.
 
    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, unsigned fn_idx, tree attr)
 {
   cgraph_node *n = caller;
   cgraph_edge *e2;
@@ -1377,12 +1377,13 @@ 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
     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);
   symtab->call_edge_duplication_hooks (this, e2);
   n2->mark_address_taken ();
   return e2;
@@ -1709,7 +1710,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;
@@ -1719,6 +1720,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)
@@ -1850,11 +1853,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;
     }
 
@@ -4391,12 +4394,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");
@@ -4720,6 +4717,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 e4a0a6b1bc78..d9f3d4815b0d 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1925,8 +1925,10 @@ public:
   /* Create a callback edge, representing an indirect call to n2
      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);
+     callback edge.  FN_IDX is the index of the callback function in 
dispatching
+     function's argument list.  ATTR is the attribute used to derive the
+     edge.  */
+  cgraph_edge *make_callback (cgraph_node *n2, unsigned fn_idx, tree attr);
 
   /* 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 +2184,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 180ef4e52c87..b5f2ce5ff2f3 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 d2e3254643b6..d5d9709e1185 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.  */
 
@@ -6736,6 +6738,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 e66c84ebcdf4..668932ec3291 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;
@@ -2625,9 +2626,8 @@ 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);
+                       = cs->make_callback (kernel_node, n, callback_attr);
                      callback_edges.safe_push (cbe);
                    }
                }
@@ -2703,12 +2703,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] == ARG_MAPPING_UNKNOWN_IDX)
                continue;
              class ipa_jump_func *src
                = ipa_get_ith_jump_func (args, arg_mapping[i]);
@@ -3582,6 +3582,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)
@@ -5210,6 +5211,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 9a71110d5c25..adbf59ca821f 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)

Reply via email to