diff options
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index a9d885fe34d..5d998870f34 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -766,15 +766,15 @@ static struct cgraph_edge * redirect_to_unreachable (struct cgraph_edge *e) { struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL; + struct cgraph_node *target = cgraph_node::get_create + (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); if (e->speculative) - e = e->resolve_speculation (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); + e = e->resolve_speculation (target->decl); else if (!e->callee) - e->make_direct (cgraph_node::get_create - (builtin_decl_implicit (BUILT_IN_UNREACHABLE))); + e->make_direct (target); else - e->redirect_callee (cgraph_node::get_create - (builtin_decl_implicit (BUILT_IN_UNREACHABLE))); + e->redirect_callee (target); struct inline_edge_summary *es = inline_edge_summary (e); e->inline_failed = CIF_UNREACHABLE; e->frequency = 0; @@ -793,7 +793,11 @@ edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate) { /* If the edge is determined to be never executed, redirect it to BUILTIN_UNREACHABLE to save inliner from inlining into it. */ - if (predicate && false_predicate_p (predicate)) + if (predicate && false_predicate_p (predicate) + /* When handling speculative edges, we need to do the redirection + just once. Do it always on the direct edge, so we do not + attempt to resolve speculation while duplicating the edge. */ + && (!e->speculative || e->callee)) e = redirect_to_unreachable (e); struct inline_edge_summary *es = inline_edge_summary (e); |