>
> When creating speculative edges, ensure they remain adjacent in the callees
> list to satisfy verification requirements. The create_edge() function always
> inserts new edges at the head of the list, which can break adjacency when
> multiple speculative edges exist for the same call statement.
>
> gcc/ChangeLog:
>
> * cgraph.cc (cgraph_edge::make_speculative): Find the last existing
> speculative edge for the same call_stmt and insert the new edge
> adjacent to it, maintaining the verification invariant.
+
+ /* Find the first and last speculative edges for this call_stmt to maintain
+ adjacency. All speculative edges for the same call statement must be
+ adjacent in the callees list to satisfy verification requirements.
+ Additionally, the call-site hash must point to the first speculative edge
+ in list order. */
+ cgraph_edge *first_spec = NULL;
+ cgraph_edge *last_spec = NULL;
+ if (speculative)
+ {
+ for (cgraph_edge *e = n->callees; e; e = e->next_callee)
+ if (e->call_stmt == call_stmt
+ && e->lto_stmt_uid == lto_stmt_uid
+ && e->speculative)
+ {
+ if (!first_spec)
+ first_spec = e;
+ last_spec = e;
+ }
+ else if (first_spec)
+ break; /* Stop after the adjacent speculative sequence. */
+ }
+
This loop is quadratic in number of edges which may be high. Number of
speculative edges is low. I think you can simply check if the last call
already is proper speculative edge (in most cases it will).
If not you can use first_speculative_call_target and
next_speculative_call_target
to find one which is quadratic only in number of speculative edges for
one call which should be bounded by --param constat.
Can you, please, update the patch and test that it works and that the
only place that triggers this code path are calls from
ipa_merge_profiles? I checked the profile updating and it should just
work since it sums the counts, but we should be sure that there are no
other bugs similar to one in simple-call in ipa-devirt.
I am sorry for taking so long - I was kind of confused how this happens.
Honza