On 10/18/25 19:03, Josef Melcr wrote:
This function is used to determine whether a callback edge should be kept or not. It was supposed to capture the idea that a callback edge has been redirected at some point, however, it only considered redirecting to some clone. However, an edge may not always be redirected to a clone. For example, common function bodies produced by icf are not clones. This version of the function captures this idea better. If you know of a better way, please let me know.gcc/ChangeLog: * attr-callback.cc (callback_edge_useful_p): Rewrite the heuristic, now consider icf bodies and not yet redirected edges. Signed-off-by: Josef Melcr <[email protected]> --- gcc/attr-callback.cc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/gcc/attr-callback.cc b/gcc/attr-callback.cc index 83d27544150..4c4b695f5c7 100644 --- a/gcc/attr-callback.cc +++ b/gcc/attr-callback.cc @@ -344,11 +344,22 @@ bool callback_edge_useful_p (cgraph_edge *e) { gcc_checking_assert (e->callback); - /* If the edge is not pointing towards a clone, it is no longer useful as its - entire purpose is to produce clones of callbacks. */ - if (!e->callee->clone_of) - return false; - return true; + /* 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; + + /* If the decl in the call stmt doesn't match, the edge has been redirected + and thus is useful. */ + if (e->call_stmt + && gimple_call_arg (e->call_stmt, e->callback_id) != e->callee->decl) + return true;
Following Andrew's replies, I did some digging and found out that comparing decl pointers is rather unreliable. In the committed version, I'd swap it for DECL_UID comparisons, unless someone suggests something even better. I didn't know about DECL_UID when I was working on this patch, sorry about that.
Best regards, Josef
