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
This commit is contained in:
parent
1bbb87c4b2
commit
3aaf05290a
@ -1,3 +1,13 @@
|
||||
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
|
||||
|
@ -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. */
|
||||
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);
|
||||
if (!snode)
|
||||
if (!snode || !snode->definition)
|
||||
return false;
|
||||
node = dyn_cast <cgraph_node *> (snode);
|
||||
return !node || !node->global.inlined_to;
|
||||
@ -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.
|
||||
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
|
||||
|| 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
|
||||
&& symtab_get_node (from_decl)->in_other_partition))
|
||||
return true;
|
||||
@ -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. */
|
||||
if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
|
||||
return true;
|
||||
/* We are not at ltrans stage; so don't worry about WHOPR.
|
||||
Also when still gimplifying all referred comdat functions will be
|
||||
produced.
|
||||
/* We have COMDAT. We are going to check if we still have definition
|
||||
or if the definition is going to be output in other partition.
|
||||
Bypass this when gimplifying; all needed functions will be produced.
|
||||
|
||||
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
|
||||
@ -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
|
||||
it is possible that vtable was kept public while the function itself
|
||||
was privatized. */
|
||||
if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready))
|
||||
if (!cgraph_function_flags_ready)
|
||||
return true;
|
||||
|
||||
/* OK we are seeing either COMDAT or static variable. In this case we must
|
||||
check that the definition is still around so we can refer it. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
node = cgraph_get_node (decl);
|
||||
/* Check that we still have function body and that we didn't took
|
||||
the decision to eliminate offline copy of the function yet.
|
||||
The second is important when devirtualization happens during final
|
||||
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;
|
||||
snode = symtab_get_node (decl);
|
||||
if (!snode
|
||||
|| ((!snode->definition || DECL_EXTERNAL (decl))
|
||||
&& (!snode->in_other_partition
|
||||
|| (!snode->forced_by_abi && !snode->force_output))))
|
||||
return false;
|
||||
node = dyn_cast <cgraph_node *> (snode);
|
||||
return !node || !node->global.inlined_to;
|
||||
}
|
||||
|
||||
/* CVAL is value taken from DECL_INITIAL of variable. Try to transform it into
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR C++/61038
|
||||
|
@ -42,8 +42,7 @@ bar ()
|
||||
baz ();
|
||||
c + d;
|
||||
}
|
||||
/* While inlining function called once we should devirtualize a new call to fn2
|
||||
and two to fn3. While doing so the new symbol for fn2 needs to be
|
||||
introduced. */
|
||||
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */
|
||||
/* While inlining function called once we should devirtualize a new call to fn3.
|
||||
Because fn2 is already removed, we should not devirtualize. */
|
||||
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" } } */
|
||||
/* { dg-final { cleanup-ipa-dump "inline" } } */
|
||||
|
Loading…
Reference in New Issue
Block a user