Commit 3aaf0529 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/60899 (undef reference generated with -fdevirtualize-speculatively)


	PR tree-optimization/60899
	* gimple-fold.c (can_refer_decl_in_current_unit_p): Cleanup;
	assume all static symbols will have definition wile parsing and
	check the do have definition later in compilation; check that
	variable referring symbol will be output before concluding that
	reference is safe; be conservative for referring local statics;
	be more precise about when comdat is output in other partition.

	g++.dg/ipa/devirt-11.C: Update template.

From-SVN: r210676
parent 1bbb87c4
2014-05-20 Jan Hubicka <hubicka@ucw.cz> 2014-05-20 Jan Hubicka <hubicka@ucw.cz>
PR tree-optimization/60899
* gimple-fold.c (can_refer_decl_in_current_unit_p): Cleanup;
assume all static symbols will have definition wile parsing and
check the do have definition later in compilation; check that
variable referring symbol will be output before concluding that
reference is safe; be conservative for referring local statics;
be more precise about when comdat is output in other partition.
2014-05-20 Jan Hubicka <hubicka@ucw.cz>
PR bootstrap/60984 PR bootstrap/60984
* ipa-inline-transform.c (inline_call): Use add CALLEE_REMOVED parameter. * ipa-inline-transform.c (inline_call): Use add CALLEE_REMOVED parameter.
* ipa-inline.c (inline_to_all_callers): If callee was removed; return. * ipa-inline.c (inline_to_all_callers): If callee was removed; return.
......
...@@ -94,8 +94,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) ...@@ -94,8 +94,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
/* Static objects can be referred only if they was not optimized out yet. */ /* Static objects can be referred only if they was not optimized out yet. */
if (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) if (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
{ {
/* Before we start optimizing unreachable code we can be sure all
static objects are defined. */
if (cgraph_function_flags_ready)
return true;
snode = symtab_get_node (decl); snode = symtab_get_node (decl);
if (!snode) if (!snode || !snode->definition)
return false; return false;
node = dyn_cast <cgraph_node *> (snode); node = dyn_cast <cgraph_node *> (snode);
return !node || !node->global.inlined_to; return !node || !node->global.inlined_to;
...@@ -103,10 +107,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) ...@@ -103,10 +107,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
/* We will later output the initializer, so we can refer to it. /* We will later output the initializer, so we can refer to it.
So we are concerned only when DECL comes from initializer of So we are concerned only when DECL comes from initializer of
external var. */ external var or var that has been optimized out. */
if (!from_decl if (!from_decl
|| TREE_CODE (from_decl) != VAR_DECL || TREE_CODE (from_decl) != VAR_DECL
|| !DECL_EXTERNAL (from_decl) || (!DECL_EXTERNAL (from_decl)
&& (vnode = varpool_get_node (from_decl)) != NULL
&& vnode->definition)
|| (flag_ltrans || (flag_ltrans
&& symtab_get_node (from_decl)->in_other_partition)) && symtab_get_node (from_decl)->in_other_partition))
return true; return true;
...@@ -123,9 +129,9 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) ...@@ -123,9 +129,9 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
reference imply need to include function body in the curren tunit. */ reference imply need to include function body in the curren tunit. */
if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
return true; return true;
/* We are not at ltrans stage; so don't worry about WHOPR. /* We have COMDAT. We are going to check if we still have definition
Also when still gimplifying all referred comdat functions will be or if the definition is going to be output in other partition.
produced. Bypass this when gimplifying; all needed functions will be produced.
As observed in PR20991 for already optimized out comdat virtual functions As observed in PR20991 for already optimized out comdat virtual functions
it may be tempting to not necessarily give up because the copy will be it may be tempting to not necessarily give up because the copy will be
...@@ -134,35 +140,17 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) ...@@ -134,35 +140,17 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
units where they are used and when the other unit was compiled with LTO units where they are used and when the other unit was compiled with LTO
it is possible that vtable was kept public while the function itself it is possible that vtable was kept public while the function itself
was privatized. */ was privatized. */
if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready)) if (!cgraph_function_flags_ready)
return true; return true;
/* OK we are seeing either COMDAT or static variable. In this case we must snode = symtab_get_node (decl);
check that the definition is still around so we can refer it. */ if (!snode
if (TREE_CODE (decl) == FUNCTION_DECL) || ((!snode->definition || DECL_EXTERNAL (decl))
{ && (!snode->in_other_partition
node = cgraph_get_node (decl); || (!snode->forced_by_abi && !snode->force_output))))
/* Check that we still have function body and that we didn't took return false;
the decision to eliminate offline copy of the function yet. node = dyn_cast <cgraph_node *> (snode);
The second is important when devirtualization happens during final return !node || !node->global.inlined_to;
compilation stage when making a new reference no longer makes callee
to be compiled. */
if (!node || !node->definition || node->global.inlined_to)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
}
}
else if (TREE_CODE (decl) == VAR_DECL)
{
vnode = varpool_get_node (decl);
if (!vnode || !vnode->definition)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
}
}
return true;
} }
/* CVAL is value taken from DECL_INITIAL of variable. Try to transform it into /* CVAL is value taken from DECL_INITIAL of variable. Try to transform it into
......
2014-05-20 Jan Hubicka <hubicka@ucw.cz>
PR tree-optimization/60899
g++.dg/ipa/devirt-11.C: Update template.
2014-05-20 Edward Smith-Rowland <3dw4rd@verizon.net> 2014-05-20 Edward Smith-Rowland <3dw4rd@verizon.net>
PR C++/61038 PR C++/61038
......
...@@ -42,8 +42,7 @@ bar () ...@@ -42,8 +42,7 @@ bar ()
baz (); baz ();
c + d; c + d;
} }
/* While inlining function called once we should devirtualize a new call to fn2 /* While inlining function called once we should devirtualize a new call to fn3.
and two to fn3. While doing so the new symbol for fn2 needs to be Because fn2 is already removed, we should not devirtualize. */
introduced. */ /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" } } */
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */ /* { dg-final { cleanup-ipa-dump "inline" } } */
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