diff options
author | Jan Hubicka <jh@suse.cz> | 2010-10-04 22:59:07 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-10-04 20:59:07 +0000 |
commit | b3b9f3d0a808a2e0773e90d70dff2048270cc359 (patch) | |
tree | 1d98e516244d02c9fedbab147a5e449884c9d35c | |
parent | fa37ed29b9a77b698c67548a82484c5fab584b07 (diff) | |
download | gcc-b3b9f3d0a808a2e0773e90d70dff2048270cc359.zip gcc-b3b9f3d0a808a2e0773e90d70dff2048270cc359.tar.gz gcc-b3b9f3d0a808a2e0773e90d70dff2048270cc359.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 63 | ||||
-rw-r--r-- | gcc/gimple.c | 3 |
3 files changed, 53 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01e3381..4511232 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> * flags.h (g_switch_value, g_switch_set): Remove. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index b8c0fd4..0a6c746 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -31,11 +31,10 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "target.h" -/* Return true when DECL is static object in other partition. - In that case we must prevent folding as we can't refer to - the symbol. +/* Return true when DECL can be referenced from current unit. + We can get declarations that are not possible to reference for + various reasons: - We can get into it in two ways: 1) When analyzing C++ virtual tables. C++ virtual tables do have known constructors even 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. In this case we have static VAR_DECL or FUNCTION_DECL 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_object_in_other_unit_p (tree decl) +can_refer_decl_in_current_unit_p (tree decl) { struct varpool_node *vnode; struct cgraph_node *node; - if (!TREE_STATIC (decl) || DECL_COMDAT (decl)) - return false; + if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) + return true; /* External flag is set, so we deal with C++ reference 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 flags incorrectly. Those variables should never be finalized. */ gcc_checking_assert (!(vnode = varpool_get_node (decl)) || !vnode->finalized); - return true; + return false; } - if (TREE_PUBLIC (decl)) - return false; - /* We are not at ltrans stage; so don't worry about WHOPR. */ - if (!flag_ltrans) - return false; + /* When function is public, we always can introduce new reference. + Exception are the COMDAT functions where introducing a direct + 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. */ + 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) { node = cgraph_get_node (decl); - if (!node || !node->analyzed) - return true; + /* 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->analyzed || node->global.inlined_to) + return false; } else if (TREE_CODE (decl) == VAR_DECL) { vnode = varpool_get_node (decl); 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 @@ -106,10 +124,11 @@ canonicalize_constructor_val (tree cval) if (TREE_CODE (cval) == ADDR_EXPR) { tree base = get_base_address (TREE_OPERAND (cval, 0)); + if (base && (TREE_CODE (base) == VAR_DECL || TREE_CODE (base) == FUNCTION_DECL) - && static_object_in_other_unit_p (base)) + && !can_refer_decl_in_current_unit_p (base)) return NULL_TREE; if (base && TREE_CODE (base) == VAR_DECL) 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 ends up in other partition, because we found devirtualization possibility too late. */ - if (static_object_in_other_unit_p (fndecl)) + if (!can_refer_decl_in_current_unit_p (fndecl)) return NULL; return build_fold_addr_expr (fndecl); } diff --git a/gcc/gimple.c b/gcc/gimple.c index fa8acd0..54e6857 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3013,7 +3013,8 @@ get_base_address (tree t) && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) 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) == CONSTRUCTOR || INDIRECT_REF_P (t) |