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>
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>
PR ipa/65722
......
......@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see
int ncalls_inlined;
int nfunctions_inlined;
bool speculation_removed;
/* Scale frequency of NODE edges by FREQ_SCALE. */
......@@ -256,12 +255,29 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
next = e->next_callee;
if (!e->inline_failed)
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))
{
e->resolve_speculation (NULL);
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
......@@ -310,7 +326,6 @@ inline_call (struct cgraph_edge *e, bool update_original,
bool predicated = inline_edge_summary (e)->predicate != NULL;
#endif
speculation_removed = false;
/* Don't inline inlined edges. */
gcc_assert (e->inline_failed);
/* Don't even think of inlining inline clone. */
......@@ -360,6 +375,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
mark_all_inlined_calls_cdtor (e->callee);
if (opt_for_fn (e->caller->decl, optimize))
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
check_speculations (e->callee);
if (update_overall_summary)
inline_update_overall_summary (to);
new_size = inline_summaries->get (to)->size;
......
......@@ -2626,9 +2626,29 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
target = canonicalize_constructor_val (target, NULL);
if (!target || TREE_CODE (target) != FUNCTION_DECL)
{
if (ie->indirect_info->member_ptr)
/* Member pointer call that goes through a VMT lookup. */
if (ie->indirect_info->member_ptr
/* 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 ())
{
......
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