gimple-fold.c (static_object_in_other_unit_p): Rename to...
* gimple-fold.c (static_object_in_other_unit_p): Rename to... (can_refer_decl_in_current_unit_p): ... this one; reverse return value; handle comdats too. (canonicalize_constructor_val): Use it; handle function_decls correctly. (gimple_fold_obj_type_ref_known_binfo): Likewise. * gimple.c (get_base_address): Accept all kinds of decls. From-SVN: r164961
This commit is contained in:
parent
fa37ed29b9
commit
b3b9f3d0a8
|
@ -1,3 +1,13 @@
|
||||||
|
2010-10-04 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* gimple-fold.c (static_object_in_other_unit_p): Rename to...
|
||||||
|
(can_refer_decl_in_current_unit_p): ... this one; reverse return
|
||||||
|
value; handle comdats too.
|
||||||
|
(canonicalize_constructor_val): Use it; handle function_decls
|
||||||
|
correctly.
|
||||||
|
(gimple_fold_obj_type_ref_known_binfo): Likewise.
|
||||||
|
* gimple.c (get_base_address): Accept all kinds of decls.
|
||||||
|
|
||||||
2010-10-04 Joseph Myers <joseph@codesourcery.com>
|
2010-10-04 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* flags.h (g_switch_value, g_switch_set): Remove.
|
* flags.h (g_switch_value, g_switch_set): Remove.
|
||||||
|
|
|
@ -31,11 +31,10 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "tree-ssa-propagate.h"
|
#include "tree-ssa-propagate.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
/* Return true when DECL is static object in other partition.
|
/* Return true when DECL can be referenced from current unit.
|
||||||
In that case we must prevent folding as we can't refer to
|
We can get declarations that are not possible to reference for
|
||||||
the symbol.
|
various reasons:
|
||||||
|
|
||||||
We can get into it in two ways:
|
|
||||||
1) When analyzing C++ virtual tables.
|
1) When analyzing C++ virtual tables.
|
||||||
C++ virtual tables do have known constructors even
|
C++ virtual tables do have known constructors even
|
||||||
when they are keyed to other compilation unit.
|
when they are keyed to other compilation unit.
|
||||||
|
@ -46,45 +45,64 @@ along with GCC; see the file COPYING3. If not see
|
||||||
to method that was partitioned elsehwere.
|
to method that was partitioned elsehwere.
|
||||||
In this case we have static VAR_DECL or FUNCTION_DECL
|
In this case we have static VAR_DECL or FUNCTION_DECL
|
||||||
that has no corresponding callgraph/varpool node
|
that has no corresponding callgraph/varpool node
|
||||||
declaring the body. */
|
declaring the body.
|
||||||
|
3) COMDAT functions referred by external vtables that
|
||||||
|
we devirtualize only during final copmilation stage.
|
||||||
|
At this time we already decided that we will not output
|
||||||
|
the function body and thus we can't reference the symbol
|
||||||
|
directly. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
static_object_in_other_unit_p (tree decl)
|
can_refer_decl_in_current_unit_p (tree decl)
|
||||||
{
|
{
|
||||||
struct varpool_node *vnode;
|
struct varpool_node *vnode;
|
||||||
struct cgraph_node *node;
|
struct cgraph_node *node;
|
||||||
|
|
||||||
if (!TREE_STATIC (decl) || DECL_COMDAT (decl))
|
if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
|
||||||
return false;
|
return true;
|
||||||
/* External flag is set, so we deal with C++ reference
|
/* External flag is set, so we deal with C++ reference
|
||||||
to static object from other file. */
|
to static object from other file. */
|
||||||
if (DECL_EXTERNAL (decl) && TREE_CODE (decl) == VAR_DECL)
|
if (DECL_EXTERNAL (decl) && TREE_STATIC (decl)
|
||||||
|
&& TREE_CODE (decl) == VAR_DECL)
|
||||||
{
|
{
|
||||||
/* Just be sure it is not big in frontend setting
|
/* Just be sure it is not big in frontend setting
|
||||||
flags incorrectly. Those variables should never
|
flags incorrectly. Those variables should never
|
||||||
be finalized. */
|
be finalized. */
|
||||||
gcc_checking_assert (!(vnode = varpool_get_node (decl))
|
gcc_checking_assert (!(vnode = varpool_get_node (decl))
|
||||||
|| !vnode->finalized);
|
|| !vnode->finalized);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if (TREE_PUBLIC (decl))
|
/* When function is public, we always can introduce new reference.
|
||||||
return false;
|
Exception are the COMDAT functions where introducing a direct
|
||||||
/* We are not at ltrans stage; so don't worry about WHOPR. */
|
reference imply need to include function body in the curren tunit. */
|
||||||
if (!flag_ltrans)
|
if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
|
||||||
return false;
|
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. */
|
||||||
|
if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready))
|
||||||
|
return true;
|
||||||
|
/* If we already output the function body, we are safe. */
|
||||||
|
if (TREE_ASM_WRITTEN (decl))
|
||||||
|
return true;
|
||||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||||
{
|
{
|
||||||
node = cgraph_get_node (decl);
|
node = cgraph_get_node (decl);
|
||||||
if (!node || !node->analyzed)
|
/* Check that we still have function body and that we didn't took
|
||||||
return true;
|
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->analyzed || node->global.inlined_to)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (decl) == VAR_DECL)
|
else if (TREE_CODE (decl) == VAR_DECL)
|
||||||
{
|
{
|
||||||
vnode = varpool_get_node (decl);
|
vnode = varpool_get_node (decl);
|
||||||
if (!vnode || !vnode->finalized)
|
if (!vnode || !vnode->finalized)
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CVAL is value taken from DECL_INITIAL of variable. Try to transorm it into
|
/* CVAL is value taken from DECL_INITIAL of variable. Try to transorm it into
|
||||||
|
@ -106,10 +124,11 @@ canonicalize_constructor_val (tree cval)
|
||||||
if (TREE_CODE (cval) == ADDR_EXPR)
|
if (TREE_CODE (cval) == ADDR_EXPR)
|
||||||
{
|
{
|
||||||
tree base = get_base_address (TREE_OPERAND (cval, 0));
|
tree base = get_base_address (TREE_OPERAND (cval, 0));
|
||||||
|
|
||||||
if (base
|
if (base
|
||||||
&& (TREE_CODE (base) == VAR_DECL
|
&& (TREE_CODE (base) == VAR_DECL
|
||||||
|| TREE_CODE (base) == FUNCTION_DECL)
|
|| TREE_CODE (base) == FUNCTION_DECL)
|
||||||
&& static_object_in_other_unit_p (base))
|
&& !can_refer_decl_in_current_unit_p (base))
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
if (base && TREE_CODE (base) == VAR_DECL)
|
if (base && TREE_CODE (base) == VAR_DECL)
|
||||||
add_referenced_var (base);
|
add_referenced_var (base);
|
||||||
|
@ -1446,7 +1465,7 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
|
||||||
devirtualize. This can happen in WHOPR when the actual method
|
devirtualize. This can happen in WHOPR when the actual method
|
||||||
ends up in other partition, because we found devirtualization
|
ends up in other partition, because we found devirtualization
|
||||||
possibility too late. */
|
possibility too late. */
|
||||||
if (static_object_in_other_unit_p (fndecl))
|
if (!can_refer_decl_in_current_unit_p (fndecl))
|
||||||
return NULL;
|
return NULL;
|
||||||
return build_fold_addr_expr (fndecl);
|
return build_fold_addr_expr (fndecl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3013,7 +3013,8 @@ get_base_address (tree t)
|
||||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
|
&& TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
|
||||||
t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
|
t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
|
||||||
|
|
||||||
if (SSA_VAR_P (t)
|
if (TREE_CODE (t) == SSA_NAME
|
||||||
|
|| DECL_P (t)
|
||||||
|| TREE_CODE (t) == STRING_CST
|
|| TREE_CODE (t) == STRING_CST
|
||||||
|| TREE_CODE (t) == CONSTRUCTOR
|
|| TREE_CODE (t) == CONSTRUCTOR
|
||||||
|| INDIRECT_REF_P (t)
|
|| INDIRECT_REF_P (t)
|
||||||
|
|
Loading…
Reference in New Issue