[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