lto-symtab.c (lto_cgraph_replace_node): Release function body.
authorJan Hubicka <jh@suse.cz>
Thu, 25 Jul 2013 13:24:58 +0000 (15:24 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 25 Jul 2013 13:24:58 +0000 (13:24 +0000)
* lto-symtab.c (lto_cgraph_replace_node): Release function body.
* cgraph.c (cgraph_remove_node): Do not release function body
when in cgraph streaming.
* ipa.c (process_references, symtab_remove_unreachable_nodes): Objects
in other partitions are not considered reachable; fix handling of clones.

From-SVN: r201242

gcc/ChangeLog
gcc/cgraph.c
gcc/ipa.c
gcc/lto-symtab.c

index 6f0c1bc..0561d81 100644 (file)
@@ -1,3 +1,11 @@
+2013-07-25  Jan Hubicka  <jh@suse.cz>
+
+       * lto-symtab.c (lto_cgraph_replace_node): Release function body.
+       * cgraph.c (cgraph_remove_node): Do not release function body
+       when in cgraph streaming.
+       * ipa.c (process_references, symtab_remove_unreachable_nodes): Objects
+       in other partitions are not considered reachable; fix handling of clones.
+
 2013-07-25  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        * config/arm/arm.md (*sibcall_insn): Remove unnecessary space.
index a2ec602..c6ade31 100644 (file)
@@ -1384,15 +1384,18 @@ cgraph_remove_node (struct cgraph_node *node)
      itself is kept in the cgraph even after it is compiled.  Check whether
      we are done with this body and reclaim it proactively if this is the case.
      */
-  n = cgraph_get_node (node->symbol.decl);
-  if (!n
-      || (!n->clones && !n->clone_of && !n->global.inlined_to
-         && (cgraph_global_info_ready
-             && (TREE_ASM_WRITTEN (n->symbol.decl)
-                 || DECL_EXTERNAL (n->symbol.decl)
-                 || !n->symbol.analyzed
-                 || n->symbol.in_other_partition))))
-    cgraph_release_function_body (node);
+  if (cgraph_state != CGRAPH_LTO_STREAMING)
+    {
+      n = cgraph_get_node (node->symbol.decl);
+      if (!n
+         || (!n->clones && !n->clone_of && !n->global.inlined_to
+             && (cgraph_global_info_ready
+                 && (TREE_ASM_WRITTEN (n->symbol.decl)
+                     || DECL_EXTERNAL (n->symbol.decl)
+                     || !n->symbol.analyzed
+                     || (!flag_wpa && n->symbol.in_other_partition)))))
+       cgraph_release_function_body (node);
+    }
 
   node->symbol.decl = NULL;
   if (node->call_site_hash)
index 4fc720c..e20e561 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -138,7 +138,7 @@ process_references (struct ipa_ref_list *list,
     {
       symtab_node node = ref->referred;
 
-      if (node->symbol.definition
+      if (node->symbol.definition && !node->symbol.in_other_partition
          && ((!DECL_EXTERNAL (node->symbol.decl) || node->symbol.alias)
              || (before_inlining_p
                  /* We use variable constructors during late complation for
@@ -236,6 +236,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
      cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them.  */
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->global.inlined_to
+       && !node->symbol.in_other_partition
        && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
            /* Keep around virtual functions for possible devirtualization.  */
            || (before_inlining_p
@@ -250,7 +251,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
 
   /* Mark variables that are obviously needed.  */
   FOR_EACH_DEFINED_VARIABLE (vnode)
-    if (!varpool_can_remove_if_no_refs (vnode))
+    if (!varpool_can_remove_if_no_refs (vnode)
+       && !vnode->symbol.in_other_partition)
       {
        pointer_set_insert (reachable, vnode);
        enqueue_node ((symtab_node)vnode, &first, reachable);
@@ -296,6 +298,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
              for (e = cnode->callees; e; e = e->next_callee)
                {
                  if (e->callee->symbol.definition
+                     && !e->callee->symbol.in_other_partition
                      && (!e->inline_failed
                          || !DECL_EXTERNAL (e->callee->symbol.decl)
                          || e->callee->symbol.alias
@@ -306,22 +309,20 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
 
              /* When inline clone exists, mark body to be preserved so when removing
                 offline copy of the function we don't kill it.  */
-             if (!cnode->symbol.alias && cnode->global.inlined_to)
+             if (cnode->global.inlined_to)
                pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
-           }
 
-         /* For non-inline clones, force their origins to the boundary and ensure
-            that body is not removed.  */
-         while (cnode->clone_of
-                && !gimple_has_body_p (cnode->symbol.decl))
-           {
-             bool noninline = cnode->clone_of->symbol.decl != cnode->symbol.decl;
-             cnode = cnode->clone_of;
-             if (noninline)
-               {
-                 pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
-                 enqueue_node ((symtab_node)cnode, &first, reachable);
-                 break;
+             /* For non-inline clones, force their origins to the boundary and ensure
+                that body is not removed.  */
+             while (cnode->clone_of)
+               {
+                 bool noninline = cnode->clone_of->symbol.decl != cnode->symbol.decl;
+                 cnode = cnode->clone_of;
+                 if (noninline)
+                   {
+                     pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
+                     enqueue_node ((symtab_node)cnode, &first, reachable);
+                   }
                }
            }
        }
@@ -358,6 +359,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
         {
          if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
            cgraph_release_function_body (node);
+         else if (!node->clone_of)
+           gcc_assert (DECL_RESULT (node->symbol.decl));
          if (node->symbol.definition)
            {
              if (file)
@@ -366,6 +369,9 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
              changed = true;
            }
        }
+      else
+       gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
+                   || DECL_RESULT (node->symbol.decl));
     }
 
   /* Inline clones might be kept around so their materializing allows further
index 1b447cf..f9bf37c 100644 (file)
@@ -80,6 +80,9 @@ lto_cgraph_replace_node (struct cgraph_node *node,
   /* Redirect incomming references.  */
   ipa_clone_referring ((symtab_node)prevailing_node, &node->symbol.ref_list);
 
+  if (node->symbol.decl != prevailing_node->symbol.decl)
+    cgraph_release_function_body (node);
+
   /* Finally remove the replaced node.  */
   cgraph_remove_node (node);
 }