[gcc r17-3257] ipa: Implement a summary for callback edges

Josef Melcr via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.