mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
[PATCH] [AutoFDO/devirt] Fix ICE with duplicate speculative ID
This happens due to autoprofile pass makes edge make_speculative. Then ipa-devirt does the same with the same speculative_id which reults in duplicate speculative_id and ICE. during IPA pass: cp test.i:31:1: internal compiler error: verify_cgraph_node failed 0x39bfa6b internal_error(char const*, ...) ../../gcc/gcc/diagnostic-global-context.cc:787 0x13914eb cgraph_node::verify_node() ../../gcc/gcc/cgraph.cc:4454 0x13738ab symtab_node::verify() ../../gcc/gcc/symtab.cc:1377 0x1373d1b symtab_node::verify_symtab_nodes() ../../gcc/gcc/symtab.cc:1499 0x13a3653 symtab_node::checking_verify_symtab_nodes() ../../gcc/gcc/cgraph.h:718 0x182d267 symbol_table::remove_unreachable_nodes(_IO_FILE*) ../../gcc/gcc/ipa.cc:688 0x19f8c33 execute_todo ../../gcc/gcc/passes.cc:2163 We may also have to check if the speculative edge is present before making speculative. gcc/ChangeLog: 2025-12-22 Kugan Vivekanandarajah <kvivekananda@nvidia.com> * cgraph.cc (cgraph_edge::get_next_speculative_id): New. * cgraph.h (cgraph_edge::get_next_speculative_id): New. * ipa-devirt.cc (ipa_devirt): Use get_next_speculative_id in make_speculative. Signed-off-by: Kugan Vivekanandarajah <kvivekananda@nvidia.com>
This commit is contained in:
@@ -1265,6 +1265,32 @@ cgraph_edge::remove (cgraph_edge *edge)
|
||||
symtab->free_edge (edge);
|
||||
}
|
||||
|
||||
/* Returns the next speculative_id based on currently in use
|
||||
for the given statement for the edge.
|
||||
Returns 0 if no speculative edges exist for this statement. */
|
||||
|
||||
int
|
||||
cgraph_edge::get_next_speculative_id ()
|
||||
{
|
||||
int max_id = -1;
|
||||
cgraph_edge *e;
|
||||
|
||||
/* Iterate through all edges leaving this caller */
|
||||
for (e = caller->callees; e; e = e->next_callee)
|
||||
{
|
||||
/* Match the specific GIMPLE statement and check the
|
||||
speculative flag */
|
||||
if (e->call_stmt == call_stmt && e->speculative)
|
||||
{
|
||||
if (e->speculative_id > max_id)
|
||||
max_id = e->speculative_id;
|
||||
}
|
||||
}
|
||||
|
||||
return max_id + 1;
|
||||
}
|
||||
|
||||
|
||||
/* Turn edge into speculative call calling N2. Update
|
||||
the profile so the direct call is taken COUNT times
|
||||
with FREQUENCY.
|
||||
|
||||
@@ -1894,6 +1894,11 @@ public:
|
||||
call. */
|
||||
static cgraph_edge *make_direct (cgraph_edge *edge, cgraph_node *callee);
|
||||
|
||||
/* Returns the next speculative_id based on currently in use
|
||||
for the given statement for the edge.
|
||||
Returns 0 if no speculative edges exist for this statement. */
|
||||
int get_next_speculative_id ();
|
||||
|
||||
/* Turn edge into speculative call calling N2. Update
|
||||
the profile so the direct call is taken COUNT times
|
||||
with FREQUENCY. speculative_id is used to link direct calls with their
|
||||
|
||||
@@ -3865,7 +3865,7 @@ ipa_devirt (void)
|
||||
continue;
|
||||
}
|
||||
bool first = true;
|
||||
unsigned speculative_id = 0;
|
||||
unsigned speculative_id = e->get_next_speculative_id ();
|
||||
for (cgraph_node * likely_target: likely_targets)
|
||||
{
|
||||
if (!devirt_target_ok_p (likely_target, &stats))
|
||||
@@ -3940,7 +3940,8 @@ ipa_devirt (void)
|
||||
|
||||
update = true;
|
||||
e->make_speculative (likely_tgt_node,
|
||||
e->count.apply_scale (8, 10));
|
||||
e->count.apply_scale (8, 10),
|
||||
e->get_next_speculative_id ());
|
||||
}
|
||||
}
|
||||
if (update)
|
||||
|
||||
Reference in New Issue
Block a user