]> gcc.gnu.org Git - gcc.git/commitdiff
gimple-fold.c (static_object_in_other_unit_p): Rename to...
authorJan Hubicka <jh@suse.cz>
Mon, 4 Oct 2010 20:59:07 +0000 (22:59 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 4 Oct 2010 20:59:07 +0000 (20:59 +0000)
* 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

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple.c

index 01e33810f0d987264c3dac0057faa8c71c605fb6..4511232acf237b0e413a241aff51bd75d6d38bab 100644 (file)
@@ -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.
index b8c0fd4ec91c4ec796f1f6d5b8d0c376520be636..0a6c746d380b4b6de90556fdcaf1f6b4d885d789 100644 (file)
@@ -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);
 }
index fa8acd08e945ab415a5c2fdc51a444544a5bde56..54e68571c7a3f5406c329127fad58ace3343526e 100644 (file)
@@ -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)
This page took 0.105325 seconds and 5 git commands to generate.