[gcc(refs/users/jmelcr/heads/omp-cp)] omp-cp: Fix one segfault, introduce a different one

Josef Melcr jmelcr@gcc.gnu.org
Mon Mar 31 18:51:31 GMT 2025


https://gcc.gnu.org/g:86ef6c04591ed9b8deda7f1c86ff7f88e1efd734

commit 86ef6c04591ed9b8deda7f1c86ff7f88e1efd734
Author: Josef Melcr <melcrjos@fit.cvut.cz>
Date:   Mon Mar 31 20:48:52 2025 +0200

    omp-cp: Fix one segfault, introduce a different one
    
    gcc/ChangeLog:
    
            * attr-callback.h (callback_fetch_fn_position): Rewrite with the
            new function below.
            (callback_fetch_attr_by_decl): New function.
            (callback_remove_callback_edge): New function.
            * cgraph.cc (cgraph_edge::get_callback_parent_edge): Add
            lto_stmt_uid check.
            (cgraph_edge::first_callback_target): Likewise.
            (cgraph_edge::next_callback_target): Likewise.
            (cgraph_node::verify_node): Likewise.
            * ipa-cp.cc (purge_useless_callback_edges): Reformat, use the
            new remove function.
            (ipcp_decision_stage): Add back purge function.
            * ipa-fnsummary.cc (analyze_function_body): Set call stmt size
            and time to 0 for callback edges.
    
    Signed-off-by: Josef Melcr <melcrjos@fit.cvut.cz>

Diff:
---
 gcc/attr-callback.h  | 58 +++++++++++++++++++++++++++++++++++++++++++---------
 gcc/cgraph.cc        | 21 +++++++++++--------
 gcc/ipa-cp.cc        | 34 +++++++++++++++++-------------
 gcc/ipa-fnsummary.cc |  2 ++
 4 files changed, 82 insertions(+), 33 deletions(-)

diff --git a/gcc/attr-callback.h b/gcc/attr-callback.h
index b6a1a0c4106c..622949c03ac3 100644
--- a/gcc/attr-callback.h
+++ b/gcc/attr-callback.h
@@ -86,18 +86,13 @@ callback_get_arg_mapping (tree decl)
   return res;
 }
 
-/* Given a call statement of the parent, it's attribute list and
-   a decl of the callback, returns a 0-based index of the callback
-   function in the parameters of it's caller function. Arguments
-   are extracted from the call statement. If kernel_decl is a decl
-   of a clone, it's parent decl will be considered as well. */
-inline int
-callback_fetch_fn_position (gcall *call, tree attr_list, tree kernel_decl)
+inline tree
+callback_fetch_attr_by_decl(gcall *call, tree attr_list, tree kernel_decl)
 {
   tree original_decl = DECL_ORIGIN (kernel_decl);
   tree cb_attr = lookup_attribute ("callback", attr_list);
   gcc_checking_assert (cb_attr);
-  int res = -1;
+  tree res = NULL_TREE;
   for (; cb_attr; cb_attr = lookup_attribute ("callback", TREE_CHAIN (cb_attr)))
     {
       int idx = callback_get_fn_index (cb_attr);
@@ -108,15 +103,27 @@ callback_fetch_fn_position (gcall *call, tree attr_list, tree kernel_decl)
 	  if (pointee != NULL_TREE
 	      && (pointee == kernel_decl || pointee == original_decl))
 	    {
-	      res = idx;
+	      res = cb_attr;
 	      break;
 	    }
 	}
     }
-  gcc_checking_assert (res != -1);
+  gcc_checking_assert (res != NULL_TREE);
   return res;
 }
 
+/* Given a call statement of the parent, it's attribute list and
+   a decl of the callback, returns a 0-based index of the callback
+   function in the parameters of it's caller function. Arguments
+   are extracted from the call statement. If kernel_decl is a decl
+   of a clone, it's parent decl will be considered as well. */
+inline int
+callback_fetch_fn_position (gcall *call, tree attr_list, tree kernel_decl)
+{
+  tree attr = callback_fetch_attr_by_decl(call, attr_list, kernel_decl);
+  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
@@ -281,4 +288,35 @@ callback_edge_useful_p (cgraph_edge *e)
   return true;
 }
 
+inline void
+callback_remove_callback_edge (cgraph_edge *e)
+{
+  gcc_checking_assert (e->callback);
+  cgraph_edge *parent = e->get_callback_parent_edge ();
+  tree offload_decl = parent->callee->decl;
+  if (parent->call_stmt)
+    {
+      tree attr = callback_fetch_attr_by_decl (parent->call_stmt,
+					       DECL_ATTRIBUTES (offload_decl),
+					       e->callee->decl);
+
+      tree *p;
+      tree list = DECL_ATTRIBUTES (offload_decl);
+      for (p = &list; *p;)
+	{
+	  tree l = *p;
+
+	  if (l == attr)
+	    {
+	      *p = TREE_CHAIN (l);
+	      continue;
+	    }
+	  p = &TREE_CHAIN (l);
+	}
+
+      DECL_ATTRIBUTES (offload_decl) = list;
+    }
+  cgraph_edge::remove (e);
+}
+
 #endif /* ATTR_CALLBACK_H  */
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 3bcfe1f2da12..60a4f49014c3 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1212,7 +1212,8 @@ cgraph_edge::get_callback_parent_edge ()
   cgraph_edge *e;
   for (e = caller->callees; e; e = e->next_callee)
     {
-      if (e->has_callback && e->call_stmt == call_stmt)
+      if (e->has_callback && e->call_stmt == call_stmt
+	  && e->lto_stmt_uid == lto_stmt_uid)
 	break;
     }
   return e;
@@ -1225,7 +1226,8 @@ cgraph_edge::first_callback_target ()
   cgraph_edge *e = NULL;
   for (e = caller->callees; e; e = e->next_callee)
     {
-      if (e->callback && e->call_stmt == call_stmt)
+      if (e->callback && e->call_stmt == call_stmt
+	  && e->lto_stmt_uid == lto_stmt_uid)
 	{
 	  break;
 	}
@@ -1240,7 +1242,8 @@ cgraph_edge::next_callback_target ()
   cgraph_edge *e = NULL;
   for (e = next_callee; e; e = e->next_callee)
     {
-      if (e->callback && e->call_stmt == call_stmt)
+      if (e->callback && e->call_stmt == call_stmt
+	  && e->lto_stmt_uid == lto_stmt_uid)
 	{
 	  break;
 	}
@@ -4099,16 +4102,16 @@ cgraph_node::verify_node (void)
 		;
 	      for (cgraph_edge *cbe = callees; cbe; cbe = cbe->next_callee)
 		{
-		  if (cbe->callback && cbe->call_stmt == e->call_stmt) {
-
-		    nfound_edges++;
-
-		      }
+		  if (cbe->callback && cbe->call_stmt == e->call_stmt
+		      && cbe->lto_stmt_uid == e->lto_stmt_uid)
+		    {
+		      nfound_edges++;
+		    }
 		  else if (cbe->callback) {
 		    fprintf (stderr, "sus verify %s -> %s\n",
 			     cbe->caller->name (), cbe->callee->name ());
 		      }
-	}
+		}
 	      if (ncallbacks != nfound_edges)
 		{
 		  error ("callback edge %s->%s child edge count mismatch, "
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index b259e51d8e74..02447da03144 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -6229,26 +6229,33 @@ purge_useless_callback_edges ()
 				     DECL_ATTRIBUTES (e->callee->decl)))
 		{
 		  if (dump_file)
-		    fprintf (dump_file,
-			     "\t\tPurging children, because the offloading "
-			     "function no longer has any callback attributes.\n");
+		    fprintf (
+		      dump_file,
+		      "\t\tPurging children, because the offloading "
+		      "function no longer has any callback attributes.\n");
 		  e->purge_callback_children ();
 		  continue;
 		}
-		    cgraph_edge *cbe, *next;
-		    for (cbe = e->first_callback_target(); cbe; cbe = next) {
-          next = cbe->next_callback_target();
-          if (!callback_edge_useful_p(cbe)) {
-            if (dump_file)
-              fprintf(dump_file, "\t\tCallback edge %s -> %s not deemed useful, removing.\n", cbe->caller->name(), cbe->callee->name());
-            cgraph_edge::remove(cbe);
-          }
+	      cgraph_edge *cbe, *next;
+	      for (cbe = e->first_callback_target (); cbe; cbe = next)
+		{
+		  next = cbe->next_callback_target ();
+		  if (!callback_edge_useful_p (cbe))
+		    {
+		      if (dump_file)
+			fprintf (dump_file,
+				 "\t\tCallback edge %s -> %s not deemed "
+				 "useful, removing.\n",
+				 cbe->caller->name (), cbe->callee->name ());
+		      callback_remove_callback_edge (cbe);
 		    }
+		}
 	    }
 	}
     }
+
   if (dump_file)
-    fprintf(dump_file, "\n");
+    fprintf (dump_file, "\n");
 }
 
 /* The decision stage.  Iterate over the topological order of call graph nodes
@@ -6281,8 +6288,7 @@ ipcp_decision_stage (class ipa_topo_info *topo)
       if (change)
 	identify_dead_nodes (node);
     }
-  if (0)
-  purge_useless_callback_edges();
+    purge_useless_callback_edges();
 }
 
 /* Look up all VR and bits information that we have discovered and copy it
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 8c7c8e74063d..f5ac4243348c 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -3117,6 +3117,8 @@ analyze_function_body (struct cgraph_node *node, bool early)
 			continue;
 		      es2 = ipa_call_summaries->get_create (child);
 		      ipa_call_summaries->duplicate (edge, child, es, es2);
+		      es2->call_stmt_size = 0;
+		      es2->call_stmt_time = 0;
 		    }
 		}
 	    }


More information about the Gcc-cvs mailing list