cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
authorJan Hubicka <jh@suse.cz>
Thu, 1 Aug 2013 13:24:49 +0000 (15:24 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 1 Aug 2013 13:24:49 +0000 (13:24 +0000)
* cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
(cgraph_release_function_body): Likewise.
(cgraph_can_remove_if_no_direct_calls_p): Likewise.
* cgraph.h (cgrpah_node): Rename abstract_and_needed
to used_as_abstract_origin.
* tree-inline-transfrom.c (can_remove_node_now_p_1): Do not remove
symbols used as abstract origins.
* cgraphunit.c (analyze_functions): Update.
* ipa.c (symtab_remove_unreachable_nodes): Recompute used_as_abstract_origin.
* tree-inline.c (tree_function_versioning): Update
used_as_abstract_origin; be ready for DECL_RESULT and DECL_ARGUMENTS to be
NULL.

* lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes for abstract functions.
* cgraph.h (symtab_real_symbol_p): Abstract declarations are not real symbols.

From-SVN: r201408

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/ipa-inline-transform.c
gcc/ipa.c
gcc/lto-cgraph.c
gcc/lto-symtab.c
gcc/tree-inline.c

index cae1be0b0555a55baf29fcc6c8c2058acf3d5cb2..19959d6f99a7ce1682d8bcf6e6cb93f3792c8a79 100644 (file)
@@ -1,3 +1,21 @@
+2013-08-01  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
+       (cgraph_release_function_body): Likewise.
+       (cgraph_can_remove_if_no_direct_calls_p): Likewise.
+       * cgraph.h (cgrpah_node): Rename abstract_and_needed
+       to used_as_abstract_origin.
+       * tree-inline-transfrom.c (can_remove_node_now_p_1): Do not remove
+       symbols used as abstract origins.
+       * cgraphunit.c (analyze_functions): Update.
+       * ipa.c (symtab_remove_unreachable_nodes): Recompute used_as_abstract_origin.
+       * tree-inline.c (tree_function_versioning): Update
+       used_as_abstract_origin; be ready for DECL_RESULT and DECL_ARGUMENTS to be
+       NULL.
+
+       * lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes for abstract functions.
+       * cgraph.h (symtab_real_symbol_p): Abstract declarations are not real symbols.
+
 2013-08-01  Jan Hubicka  <jh@suse.cz>
 
        * profile.c (compute_value_histograms): Fix thinko.
index be3411d6a0797c5e3fe751898ca2e4f634ddcc2c..5b3fb5abf908ad684662db8d5669a20048699e2b 100644 (file)
@@ -1316,7 +1316,7 @@ void
 cgraph_release_function_body (struct cgraph_node *node)
 {
   node->ipa_transforms_to_apply.release ();
-  if (!node->abstract_and_needed && cgraph_state != CGRAPH_STATE_PARSING)
+  if (!node->used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
     {
       DECL_RESULT (node->symbol.decl) = NULL;
       DECL_ARGUMENTS (node->symbol.decl) = NULL;
@@ -1324,7 +1324,7 @@ cgraph_release_function_body (struct cgraph_node *node)
   /* If the node is abstract and needed, then do not clear DECL_INITIAL
      of its associated function function declaration because it's
      needed to emit debug info later.  */
-  if (!node->abstract_and_needed && DECL_INITIAL (node->symbol.decl))
+  if (!node->used_as_abstract_origin && DECL_INITIAL (node->symbol.decl))
     DECL_INITIAL (node->symbol.decl) = error_mark_node;
   release_function_body (node->symbol.decl);
 }
index 3d6f3876f9cd6e5746935caaa80a60be7a1412ad..99acb62984c5ce78032a624460e1db33fec57a0d 100644 (file)
@@ -303,7 +303,7 @@ struct GTY(()) cgraph_node {
 
   /* Set when decl is an abstract function pointed to by the
      ABSTRACT_DECL_ORIGIN of a reachable function.  */
-  unsigned abstract_and_needed : 1;
+  unsigned used_as_abstract_origin : 1;
   /* Set once the function is lowered (i.e. its CFG is built).  */
   unsigned lowered : 1;
   /* Set once the function has been instantiated and its callee
@@ -1347,13 +1347,13 @@ symtab_real_symbol_p (symtab_node node)
 {
   struct cgraph_node *cnode;
 
+  if (DECL_ABSTRACT (node->symbol.decl))
+    return false;
   if (!is_a <cgraph_node> (node))
     return true;
   cnode = cgraph (node);
   if (cnode->global.inlined_to)
     return false;
-  if (cnode->abstract_and_needed)
-    return false;
   return true;
 }
 #endif  /* GCC_CGRAPH_H  */
index ca36937a8194733e7a49e031d7a8515be8203c6d..de7bb93d2c37b2b535963935f290365e780b9a73 100644 (file)
@@ -928,7 +928,7 @@ analyze_functions (void)
                {
                  struct cgraph_node *origin_node
                  = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
-                 origin_node->abstract_and_needed = true;
+                 origin_node->used_as_abstract_origin = true;
                }
            }
          else
index d421c87c2228a39489c51134f57fd4190c9a9adc..5e666aee3871c7c4c7efc9e9fc1c68e212031cdf 100644 (file)
@@ -87,6 +87,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node)
      the callgraph so references can point to it.  */
   return (!node->symbol.address_taken
          && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
+         && !node->used_as_abstract_origin
          && cgraph_can_remove_if_no_direct_calls_p (node)
          /* Inlining might enable more devirtualizing, so we want to remove
             those only after all devirtualizable virtual calls are processed.
index e20e561a2a043525996bc72ccbed11d539435f1b..243bf205e026c29e01d6b44f784a17564570e72b 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -234,20 +234,23 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
      This is mostly when they can be referenced externally.  Inline clones
      are special since their declarations are shared with master clone and thus
      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
-               && DECL_VIRTUAL_P (node->symbol.decl))))
-      {
-        gcc_assert (!node->global.inlined_to);
-       pointer_set_insert (reachable, node);
-       enqueue_node ((symtab_node)node, &first, reachable);
-      }
-    else
-      gcc_assert (!node->symbol.aux);
+  FOR_EACH_FUNCTION (node)
+    {
+      node->used_as_abstract_origin = false;
+      if (node->symbol.definition
+         && !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->symbol.decl))))
+       {
+         gcc_assert (!node->global.inlined_to);
+         pointer_set_insert (reachable, node);
+         enqueue_node ((symtab_node)node, &first, reachable);
+       }
+      else
+       gcc_assert (!node->symbol.aux);
+     }
 
   /* Mark variables that are obviously needed.  */
   FOR_EACH_DEFINED_VARIABLE (vnode)
@@ -272,6 +275,13 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
        node->symbol.aux = (void *)2;
       else
        {
+         if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
+           {
+             struct cgraph_node *origin_node
+             = cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+             origin_node->used_as_abstract_origin = true;
+             enqueue_node ((symtab_node) origin_node, &first, reachable);
+           }
          /* If any symbol in a comdat group is reachable, force
             all other in the same comdat group to be also reachable.  */
          if (node->symbol.same_comdat_group)
index 19a5de828b86922614bb34e2d380957097ddd623..3f9c56de7334268e2291bdaeb3751b051e24a213 100644 (file)
@@ -474,7 +474,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
   bp_pack_value (&bp, node->symbol.unique_name, 1);
   bp_pack_value (&bp, node->symbol.address_taken, 1);
-  bp_pack_value (&bp, node->abstract_and_needed, 1);
   bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
                 && !DECL_EXTERNAL (node->symbol.decl)
                 && !DECL_COMDAT (node->symbol.decl)
@@ -889,7 +888,6 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
   node->symbol.forced_by_abi = bp_unpack_value (bp, 1);
   node->symbol.unique_name = bp_unpack_value (bp, 1);
   node->symbol.address_taken = bp_unpack_value (bp, 1);
-  node->abstract_and_needed = bp_unpack_value (bp, 1);
   node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
   node->lowered = bp_unpack_value (bp, 1);
   node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
index f9bf37c7005bead7f3be0f121c7d1ffd58c59756..9bebd09c832da50e19f04304821b0aaac55612e0 100644 (file)
@@ -599,6 +599,13 @@ lto_symtab_merge_symbols (void)
                  && (cnode2 = cgraph_get_node (node->symbol.decl))
                  && cnode2 != cnode)
                lto_cgraph_replace_node (cnode2, cnode);
+
+             /* Abstract functions may have duplicated cgraph nodes attached;
+                remove them.  */
+             else if (cnode && DECL_ABSTRACT (cnode->symbol.decl)
+                      && (cnode2 = cgraph_get_node (node->symbol.decl))
+                      && cnode2 != cnode)
+               cgraph_remove_node (cnode2);
              symtab_insert_node_to_hashtable ((symtab_node)node);
            }
        }
index 9b2c815de2119e086df1e2aa915c4871bbab212f..be3917a32e3b68cb39c1d092f4a1976838bf3749 100644 (file)
@@ -5085,6 +5085,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
 
   DECL_ARTIFICIAL (new_decl) = 1;
   DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
+  if (DECL_ORIGIN (old_decl) == old_decl)
+    old_version_node->used_as_abstract_origin = true;
   DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
 
   /* Prepare the data structures for the tree copy.  */
@@ -5122,6 +5124,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
 
   old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
     (DECL_STRUCT_FUNCTION (old_decl));
+  DECL_RESULT (new_decl) = DECL_RESULT (old_decl);
+  DECL_ARGUMENTS (new_decl) = DECL_ARGUMENTS (old_decl);
   initialize_cfun (new_decl, old_decl,
                   old_entry_block->count);
   DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta