OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ipa.c
index 3f7dac3..8c2b3bd 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -194,14 +194,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
     if (node->analyzed && !node->global.inlined_to
        && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
            /* Keep around virtual functions for possible devirtualization.  */
-           || (before_inlining_p
-               && DECL_VIRTUAL_P (node->decl)
-               && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl)))
-           /* Also external functions with address taken are better to stay
-              for indirect inlining.  */
-           || (before_inlining_p
-               && DECL_EXTERNAL (node->decl)
-               && node->address_taken)))
+           || (before_inlining_p && DECL_VIRTUAL_P (node->decl))))
       {
         gcc_assert (!node->global.inlined_to);
        enqueue_cgraph_node (node, &first);
@@ -542,15 +535,16 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
 {
   int i;
   struct ipa_ref *ref;
-  for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
-    {
-      struct varpool_node *node;
-      if (ref->refered_type == IPA_REF_CGRAPH)
-       return true;
-      node = ipa_ref_varpool_node (ref);
-      if (!DECL_VIRTUAL_P (node->decl))
-       return true;
-    }
+  for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
+    if (ref->use == IPA_REF_ADDR)
+      {
+       struct varpool_node *node;
+       if (ref->refering_type == IPA_REF_CGRAPH)
+         return true;
+       node = ipa_ref_refering_varpool_node (ref);
+       if (!DECL_VIRTUAL_P (node->decl))
+         return true;
+      }
   return false;
 }
 
@@ -611,14 +605,6 @@ cgraph_externally_visible_p (struct cgraph_node *node,
   if (DECL_BUILT_IN (node->decl))
     return true;
 
-  /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO.
-     This is because very little of code knows that assembler name needs to
-     mangled.  Avoid touching declarations with user asm name set to mask
-     some of the problems.  */
-  if (DECL_ASSEMBLER_NAME_SET_P (node->decl)
-      && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))[0]=='*')
-    return true;
-
   /* If linker counts on us, we must preserve the function.  */
   if (cgraph_used_from_object_file_p (node))
     return true;
@@ -629,6 +615,8 @@ cgraph_externally_visible_p (struct cgraph_node *node,
   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
       && lookup_attribute ("dllexport", DECL_ATTRIBUTES (node->decl)))
     return true;
+  if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
+    return false;
   /* When doing LTO or whole program, we can bring COMDAT functoins static.
      This improves code quality and we know we will duplicate them at most twice
      (in the case that we are not using plugin and link with object file
@@ -657,10 +645,9 @@ cgraph_externally_visible_p (struct cgraph_node *node,
 
 /* Return true when variable VNODE should be considered externally visible.  */
 
-static bool
+bool
 varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
 {
-  struct varpool_node *alias;
   if (!DECL_COMDAT (vnode->decl) && !TREE_PUBLIC (vnode->decl))
     return false;
 
@@ -673,14 +660,8 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
   if (varpool_used_from_object_file_p (vnode))
     return true;
 
-  /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO.
-     This is because very little of code knows that assembler name needs to
-     mangled.  Avoid touching declarations with user asm name set to mask
-     some of the problems.  */
-  if (DECL_ASSEMBLER_NAME_SET_P (vnode->decl)
-      && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (vnode->decl))[0]=='*')
+  if (DECL_HARD_REGISTER (vnode->decl))
     return true;
-
   if (DECL_PRESERVE_P (vnode->decl))
     return true;
   if (lookup_attribute ("externally_visible",
@@ -699,10 +680,7 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
      This is needed for i.e. references from asm statements.   */
   if (varpool_used_from_object_file_p (vnode))
     return true;
-  for (alias = vnode->extra_name; alias; alias = alias->next)
-    if (alias->resolution != LDPR_PREVAILING_DEF_IRONLY)
-      break;
-  if (!alias && vnode->resolution == LDPR_PREVAILING_DEF_IRONLY)
+  if (vnode->resolution == LDPR_PREVAILING_DEF_IRONLY)
     return false;
 
   /* As a special case, the COMDAT virutal tables can be unshared.
@@ -787,13 +765,7 @@ function_and_variable_visibility (bool whole_program)
         {
          if (!node->analyzed)
            continue;
-         /* Weakrefs alias symbols from other compilation unit.  In the case
-            the destination of weakref became available because of LTO, we must
-            mark it as needed.  */
-         if (in_lto_p
-             && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
-             && !node->needed)
-           cgraph_mark_needed_node (node);
+         cgraph_mark_needed_node (node);
          gcc_assert (node->needed);
          pointer_set_insert (aliased_nodes, node);
          if (dump_file)
@@ -803,13 +775,7 @@ function_and_variable_visibility (bool whole_program)
       else if ((vnode = varpool_node_for_asm (p->target)) != NULL
               && !DECL_EXTERNAL (vnode->decl))
         {
-         /* Weakrefs alias symbols from other compilation unit.  In the case
-            the destination of weakref became available because of LTO, we must
-            mark it as needed.  */
-         if (in_lto_p
-             && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
-             && !vnode->needed)
-           varpool_mark_needed_node (vnode);
+         varpool_mark_needed_node (vnode);
          gcc_assert (vnode->needed);
          pointer_set_insert (aliased_vnodes, vnode);
          if (dump_file)
@@ -896,31 +862,14 @@ function_and_variable_visibility (bool whole_program)
          decl_node = cgraph_function_node (decl_node->callees->callee, NULL);
 
          /* Thunks have the same visibility as function they are attached to.
-            For some reason C++ frontend don't seem to care. I.e. in 
-            g++.dg/torture/pr41257-2.C the thunk is not comdat while function
-            it is attached to is.
-
-            We also need to arrange the thunk into the same comdat group as
-            the function it reffers to.  */
-         if (DECL_COMDAT (decl_node->decl))
+            Make sure the C++ front end set this up properly.  */
+         if (DECL_ONE_ONLY (decl_node->decl))
            {
-             DECL_COMDAT (node->decl) = 1;
-             DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (decl_node->decl);
-             if (DECL_ONE_ONLY (decl_node->decl) && !node->same_comdat_group)
-               {
-                 node->same_comdat_group = decl_node;
-                 if (!decl_node->same_comdat_group)
-                   decl_node->same_comdat_group = node;
-                 else
-                   {
-                     struct cgraph_node *n;
-                     for (n = decl_node->same_comdat_group;
-                          n->same_comdat_group != decl_node;
-                          n = n->same_comdat_group)
-                       ;
-                     n->same_comdat_group = node;
-                   }
-               }
+             gcc_checking_assert (DECL_COMDAT (node->decl)
+                                  == DECL_COMDAT (decl_node->decl));
+             gcc_checking_assert (DECL_COMDAT_GROUP (node->decl)
+                                  == DECL_COMDAT_GROUP (decl_node->decl));
+             gcc_checking_assert (node->same_comdat_group);
            }
          if (DECL_EXTERNAL (decl_node->decl))
            DECL_EXTERNAL (node->decl) = 1;