Commit a21065ca by Jan Hubicka Committed by Jan Hubicka

ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for edge to change…

ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for edge to change by speculation resolution or redirection.


	* ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for
	edge to change by speculation resolution or redirection.
	(edge_set_predicate): Likewise.
	(inline_summary_t::duplicate): Likewise.
	(remap_edge_summaries): Likewise.
	* gcc.c-torture/compile/20150327.c: New testcase.

From-SVN: r221718
parent e59887e7
2015-03-26 Jan Hubicka <hubicka@ucw.cz> 2015-03-26 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline-analysis.c (redirect_to_unreachable): Be prepared for
edge to change by speculation resolution or redirection.
(edge_set_predicate): Likewise.
(inline_summary_t::duplicate): Likewise.
(remap_edge_summaries): Likewise.
2015-03-26 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline.c (check_maybe_up, check_maybe_down, check_match): * ipa-inline.c (check_maybe_up, check_maybe_down, check_match):
New macros. New macros.
(can_inline_edge_p): Relax option matching for always inline functions. (can_inline_edge_p): Relax option matching for always inline functions.
......
...@@ -762,20 +762,20 @@ account_size_time (struct inline_summary *summary, int size, int time, ...@@ -762,20 +762,20 @@ account_size_time (struct inline_summary *summary, int size, int time,
/* We proved E to be unreachable, redirect it to __bultin_unreachable. */ /* We proved E to be unreachable, redirect it to __bultin_unreachable. */
static void static struct cgraph_edge *
redirect_to_unreachable (struct cgraph_edge *e) redirect_to_unreachable (struct cgraph_edge *e)
{ {
struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL; struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
struct inline_edge_summary *es = inline_edge_summary (e);
if (e->speculative) if (e->speculative)
e->resolve_speculation (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); e = e->resolve_speculation (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
if (!e->callee) else if (!e->callee)
e->make_direct (cgraph_node::get_create e->make_direct (cgraph_node::get_create
(builtin_decl_implicit (BUILT_IN_UNREACHABLE))); (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
else else
e->redirect_callee (cgraph_node::get_create e->redirect_callee (cgraph_node::get_create
(builtin_decl_implicit (BUILT_IN_UNREACHABLE))); (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
struct inline_edge_summary *es = inline_edge_summary (e);
e->inline_failed = CIF_UNREACHABLE; e->inline_failed = CIF_UNREACHABLE;
e->frequency = 0; e->frequency = 0;
e->count = 0; e->count = 0;
...@@ -783,6 +783,7 @@ redirect_to_unreachable (struct cgraph_edge *e) ...@@ -783,6 +783,7 @@ redirect_to_unreachable (struct cgraph_edge *e)
es->call_stmt_time = 0; es->call_stmt_time = 0;
if (callee) if (callee)
callee->remove_symbol_and_inline_clones (); callee->remove_symbol_and_inline_clones ();
return e;
} }
/* Set predicate for edge E. */ /* Set predicate for edge E. */
...@@ -790,12 +791,12 @@ redirect_to_unreachable (struct cgraph_edge *e) ...@@ -790,12 +791,12 @@ redirect_to_unreachable (struct cgraph_edge *e)
static void static void
edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate) edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
{ {
struct inline_edge_summary *es = inline_edge_summary (e);
/* If the edge is determined to be never executed, redirect it /* If the edge is determined to be never executed, redirect it
to BUILTIN_UNREACHABLE to save inliner from inlining into it. */ to BUILTIN_UNREACHABLE to save inliner from inlining into it. */
if (predicate && false_predicate_p (predicate)) if (predicate && false_predicate_p (predicate))
redirect_to_unreachable (e); e = redirect_to_unreachable (e);
struct inline_edge_summary *es = inline_edge_summary (e);
if (predicate && !true_predicate_p (predicate)) if (predicate && !true_predicate_p (predicate))
{ {
if (!es->predicate) if (!es->predicate)
...@@ -1184,7 +1185,7 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -1184,7 +1185,7 @@ inline_summary_t::duplicate (cgraph_node *src,
size_time_entry *e; size_time_entry *e;
int optimized_out_size = 0; int optimized_out_size = 0;
bool inlined_to_p = false; bool inlined_to_p = false;
struct cgraph_edge *edge; struct cgraph_edge *edge, *next;
info->entry = 0; info->entry = 0;
known_vals.safe_grow_cleared (count); known_vals.safe_grow_cleared (count);
...@@ -1229,10 +1230,11 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -1229,10 +1230,11 @@ inline_summary_t::duplicate (cgraph_node *src,
/* Remap edge predicates with the same simplification as above. /* Remap edge predicates with the same simplification as above.
Also copy constantness arrays. */ Also copy constantness arrays. */
for (edge = dst->callees; edge; edge = edge->next_callee) for (edge = dst->callees; edge; edge = next)
{ {
struct predicate new_predicate; struct predicate new_predicate;
struct inline_edge_summary *es = inline_edge_summary (edge); struct inline_edge_summary *es = inline_edge_summary (edge);
next = edge->next_callee;
if (!edge->inline_failed) if (!edge->inline_failed)
inlined_to_p = true; inlined_to_p = true;
...@@ -1249,10 +1251,11 @@ inline_summary_t::duplicate (cgraph_node *src, ...@@ -1249,10 +1251,11 @@ inline_summary_t::duplicate (cgraph_node *src,
/* Remap indirect edge predicates with the same simplificaiton as above. /* Remap indirect edge predicates with the same simplificaiton as above.
Also copy constantness arrays. */ Also copy constantness arrays. */
for (edge = dst->indirect_calls; edge; edge = edge->next_callee) for (edge = dst->indirect_calls; edge; edge = next)
{ {
struct predicate new_predicate; struct predicate new_predicate;
struct inline_edge_summary *es = inline_edge_summary (edge); struct inline_edge_summary *es = inline_edge_summary (edge);
next = edge->next_callee;
gcc_checking_assert (edge->inline_failed); gcc_checking_assert (edge->inline_failed);
if (!es->predicate) if (!es->predicate)
...@@ -3484,11 +3487,12 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, ...@@ -3484,11 +3487,12 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
clause_t possible_truths, clause_t possible_truths,
struct predicate *toplev_predicate) struct predicate *toplev_predicate)
{ {
struct cgraph_edge *e; struct cgraph_edge *e, *next;
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = next)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct inline_edge_summary *es = inline_edge_summary (e);
struct predicate p; struct predicate p;
next = e->next_callee;
if (e->inline_failed) if (e->inline_failed)
{ {
...@@ -3509,10 +3513,11 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, ...@@ -3509,10 +3513,11 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
operand_map, offset_map, possible_truths, operand_map, offset_map, possible_truths,
toplev_predicate); toplev_predicate);
} }
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = next)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct inline_edge_summary *es = inline_edge_summary (e);
struct predicate p; struct predicate p;
next = e->next_callee;
remap_edge_change_prob (inlined_edge, e); remap_edge_change_prob (inlined_edge, e);
if (es->predicate) if (es->predicate)
......
2015-03-26 Jan Hubicka <hubicka@ucw.cz>
* gcc.c-torture/compile/20150327.c: New testcase.
2015-03-26 Richard Biener <rguenther@suse.de> 2015-03-26 Richard Biener <rguenther@suse.de>
PR middle-end/65555 PR middle-end/65555
......
int a;
int (*b)(), (*c)();
int fn1(int p1) {
if (a)
return 0;
if (p1) {
c();
b();
}
}
void fn2() { fn1(0); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment