Commit db66bf68 by Jan Hubicka Committed by Jan Hubicka

re PR middle-end/65743 (LTO+FDO build of Firefox crashes at startup)


	PR ipa/65743
	* ipa-inline-transform.c (speculation_removed): Remove static var.
	(check_speculations): New function.
	(clone_inlined_nodes): Do not check spculations.
	(inline_call): Call check_speculations.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Do not
	consider non-invariants.

From-SVN: r222017
parent c153ad03
2015-04-11 Jan Hubicka <hubicka@ucw.cz> 2015-04-11 Jan Hubicka <hubicka@ucw.cz>
PR ipa/65743
* ipa-inline-transform.c (speculation_removed): Remove static var.
(check_speculations): New function.
(clone_inlined_nodes): Do not check spculations.
(inline_call): Call check_speculations.
* ipa-prop.c (ipa_make_edge_direct_to_target): Do not
consider non-invariants.
2015-04-11 Jan Hubicka <hubicka@ucw.cz>
Martin Liska <mliska@suse.cz> Martin Liska <mliska@suse.cz>
PR ipa/65722 PR ipa/65722
......
...@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see
int ncalls_inlined; int ncalls_inlined;
int nfunctions_inlined; int nfunctions_inlined;
bool speculation_removed;
/* Scale frequency of NODE edges by FREQ_SCALE. */ /* Scale frequency of NODE edges by FREQ_SCALE. */
...@@ -256,12 +255,29 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, ...@@ -256,12 +255,29 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
next = e->next_callee; next = e->next_callee;
if (!e->inline_failed) if (!e->inline_failed)
clone_inlined_nodes (e, duplicate, update_original, overall_size, freq_scale); clone_inlined_nodes (e, duplicate, update_original, overall_size, freq_scale);
}
}
/* Check all speculations in N and resolve them if they seems useless. */
static bool
check_speculations (cgraph_node *n)
{
bool speculation_removed = false;
cgraph_edge *next;
for (cgraph_edge *e = n->callees; e; e = next)
{
next = e->next_callee;
if (e->speculative && !speculation_useful_p (e, true)) if (e->speculative && !speculation_useful_p (e, true))
{ {
e->resolve_speculation (NULL); e->resolve_speculation (NULL);
speculation_removed = true; speculation_removed = true;
} }
else if (!e->inline_failed)
speculation_removed |= check_speculations (e->callee);
} }
return speculation_removed;
} }
/* Mark all call graph edges coming out of NODE and all nodes that have been /* Mark all call graph edges coming out of NODE and all nodes that have been
...@@ -310,7 +326,6 @@ inline_call (struct cgraph_edge *e, bool update_original, ...@@ -310,7 +326,6 @@ inline_call (struct cgraph_edge *e, bool update_original,
bool predicated = inline_edge_summary (e)->predicate != NULL; bool predicated = inline_edge_summary (e)->predicate != NULL;
#endif #endif
speculation_removed = false;
/* Don't inline inlined edges. */ /* Don't inline inlined edges. */
gcc_assert (e->inline_failed); gcc_assert (e->inline_failed);
/* Don't even think of inlining inline clone. */ /* Don't even think of inlining inline clone. */
...@@ -360,6 +375,7 @@ inline_call (struct cgraph_edge *e, bool update_original, ...@@ -360,6 +375,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
mark_all_inlined_calls_cdtor (e->callee); mark_all_inlined_calls_cdtor (e->callee);
if (opt_for_fn (e->caller->decl, optimize)) if (opt_for_fn (e->caller->decl, optimize))
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges); new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
check_speculations (e->callee);
if (update_overall_summary) if (update_overall_summary)
inline_update_overall_summary (to); inline_update_overall_summary (to);
new_size = inline_summaries->get (to)->size; new_size = inline_summaries->get (to)->size;
......
...@@ -2626,9 +2626,29 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, ...@@ -2626,9 +2626,29 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
target = canonicalize_constructor_val (target, NULL); target = canonicalize_constructor_val (target, NULL);
if (!target || TREE_CODE (target) != FUNCTION_DECL) if (!target || TREE_CODE (target) != FUNCTION_DECL)
{ {
if (ie->indirect_info->member_ptr) /* Member pointer call that goes through a VMT lookup. */
/* Member pointer call that goes through a VMT lookup. */ if (ie->indirect_info->member_ptr
return NULL; /* Or if target is not an invariant expression and we do not
know if it will evaulate to function at runtime.
This can happen when folding through &VAR, where &VAR
is IP invariant, but VAR itself is not.
TODO: Revisit this when GCC 5 is branched. It seems that
member_ptr check is not needed and that we may try to fold
the expression and see if VAR is readonly. */
|| !is_gimple_ip_invariant (target))
{
if (dump_enabled_p ())
{
location_t loc = gimple_location_safe (ie->call_stmt);
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
"discovered direct call non-invariant "
"%s/%i\n",
ie->caller->name (), ie->caller->order);
}
return NULL;
}
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
......
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