summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c16
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);