cgraph.c (release_function_body): Break out from ...
authorJan Hubicka <jh@suse.cz>
Thu, 25 Jul 2013 17:10:21 +0000 (19:10 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 25 Jul 2013 17:10:21 +0000 (17:10 +0000)
* cgraph.c (release_function_body): Break out from ...
(cgraph_release_function_body): ... this one; also release DECL_RESULT
and DECL_ARGUMENTS.
* ipa-cp.c (get_replacement_map): Add parm_num argument; do not set
old_tree in the map.
(create_specialized_node): Update.
* lto-cgraph.c (output_node_opt_summary): Do not translate old_tree
into index.
* cgraphclones.c (cgraph_create_virtual_clone): Do not copy DECL_ARGUMENTS,
DECL_INITIAL and DECL_RESULT.
* ipa-prop.c (ipa_populate_param_decls): Look for origin of clones.
* tree-inline.c (initialize_cfun): Initialize DECL_ARGUMENTS and
DECL_RESULT.

From-SVN: r201251

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraphclones.c
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/lto-cgraph.c
gcc/tree-inline.c

index 53dc68c..b406b15 100644 (file)
@@ -1,3 +1,19 @@
+2013-07-25  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.c (release_function_body): Break out from ...
+       (cgraph_release_function_body): ... this one; also release DECL_RESULT
+       and DECL_ARGUMENTS.
+       * ipa-cp.c (get_replacement_map): Add parm_num argument; do not set
+       old_tree in the map.
+       (create_specialized_node): Update.
+       * lto-cgraph.c (output_node_opt_summary): Do not translate old_tree
+       into index.
+       * cgraphclones.c (cgraph_create_virtual_clone): Do not copy DECL_ARGUMENTS,
+       DECL_INITIAL and DECL_RESULT.
+       * ipa-prop.c (ipa_populate_param_decls): Look for origin of clones.
+       * tree-inline.c (initialize_cfun): Initialize DECL_ARGUMENTS and
+       DECL_RESULT.
+
 2013-07-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm.md (arm_addsi3, addsi3_carryin_<optab>,
index c6ade31..be3411d 100644 (file)
@@ -1266,17 +1266,16 @@ cgraph_node_remove_callers (struct cgraph_node *node)
   node->callers = NULL;
 }
 
-/* Release memory used to represent body of function NODE.
-   Use this only for functions that are released before being translated to
-   target code (i.e. RTL).  Functions that are compiled to RTL and beyond
-   are free'd in final.c via free_after_compilation().  */
+/* Helper function for cgraph_release_function_body and free_lang_data.
+   It releases body from function DECL without having to inspect its
+   possibly non-existent symtab node.  */
 
 void
-cgraph_release_function_body (struct cgraph_node *node)
+release_function_body (tree decl)
 {
-  if (DECL_STRUCT_FUNCTION (node->symbol.decl))
+  if (DECL_STRUCT_FUNCTION (decl))
     {
-      push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
+      push_cfun (DECL_STRUCT_FUNCTION (decl));
       if (cfun->cfg
          && current_loops)
        {
@@ -1299,19 +1298,35 @@ cgraph_release_function_body (struct cgraph_node *node)
       if (cfun->value_histograms)
        free_histograms ();
       pop_cfun();
-      gimple_set_body (node->symbol.decl, NULL);
-      node->ipa_transforms_to_apply.release ();
+      gimple_set_body (decl, NULL);
       /* Struct function hangs a lot of data that would leak if we didn't
          removed all pointers to it.   */
-      ggc_free (DECL_STRUCT_FUNCTION (node->symbol.decl));
-      DECL_STRUCT_FUNCTION (node->symbol.decl) = NULL;
+      ggc_free (DECL_STRUCT_FUNCTION (decl));
+      DECL_STRUCT_FUNCTION (decl) = NULL;
+    }
+  DECL_SAVED_TREE (decl) = NULL;
+}
+
+/* Release memory used to represent body of function NODE.
+   Use this only for functions that are released before being translated to
+   target code (i.e. RTL).  Functions that are compiled to RTL and beyond
+   are free'd in final.c via free_after_compilation().  */
+
+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)
+    {
+      DECL_RESULT (node->symbol.decl) = NULL;
+      DECL_ARGUMENTS (node->symbol.decl) = NULL;
     }
-  DECL_SAVED_TREE (node->symbol.decl) = NULL;
   /* 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))
     DECL_INITIAL (node->symbol.decl) = error_mark_node;
+  release_function_body (node->symbol.decl);
 }
 
 /* Remove the node from cgraph.  */
index 5c328b7..04cb990 100644 (file)
@@ -305,7 +305,16 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
     new_decl = copy_node (old_decl);
   else
     new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false);
+
+  /* These pointers represent function body and will be populated only when clone
+     is materialized.  */
+  gcc_assert (new_decl != old_decl);
   DECL_STRUCT_FUNCTION (new_decl) = NULL;
+  DECL_ARGUMENTS (new_decl) = NULL;
+  DECL_INITIAL (new_decl) = NULL;
+  DECL_RESULT (new_decl) = NULL; 
+  /* We can not do DECL_RESULT (new_decl) = NULL; here because of LTO partitioning
+     sometimes storing only clone decl instead of original.  */
 
   /* Generate a new name for the new version. */
   DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
index 05c6e74..73f9d6e 100644 (file)
@@ -2480,7 +2480,7 @@ gather_edges_for_value (struct ipcp_value *val, int caller_count)
    Return it or NULL if for some reason it cannot be created.  */
 
 static struct ipa_replace_map *
-get_replacement_map (tree value, tree parm)
+get_replacement_map (tree value, tree parm, int parm_num)
 {
   tree req_type = TREE_TYPE (parm);
   struct ipa_replace_map *replace_map;
@@ -2514,7 +2514,8 @@ get_replacement_map (tree value, tree parm)
       print_generic_expr (dump_file, value, 0);
       fprintf (dump_file, "\n");
     }
-  replace_map->old_tree = parm;
+  replace_map->old_tree = NULL;
+  replace_map->parm_num = parm_num;
   replace_map->new_tree = value;
   replace_map->replace_p = true;
   replace_map->ref_p = false;
@@ -2696,7 +2697,7 @@ create_specialized_node (struct cgraph_node *node,
        {
          struct ipa_replace_map *replace_map;
 
-         replace_map = get_replacement_map (t, ipa_get_param (info, i));
+         replace_map = get_replacement_map (t, ipa_get_param (info, i), i);
          if (replace_map)
            vec_safe_push (replace_trees, replace_map);
        }
index 84aeb45..bf9e903 100644 (file)
@@ -130,6 +130,10 @@ ipa_populate_param_decls (struct cgraph_node *node,
   tree parm;
   int param_num;
 
+  /* We do not copy DECL_ARGUMENTS to virtual clones.  */
+  while (node->clone_of)
+    node = node->clone_of;
+
   fndecl = node->symbol.decl;
   fnargs = DECL_ARGUMENTS (fndecl);
   param_num = 0;
@@ -166,6 +170,7 @@ ipa_initialize_node_params (struct cgraph_node *node)
   if (!info->descriptors.exists ())
     {
       int param_count;
+      gcc_assert (!node->clone_of);
 
       param_count = count_formal_params (node->symbol.decl);
       if (param_count)
index 4a287f6..d60213a 100644 (file)
@@ -1549,17 +1549,10 @@ output_node_opt_summary (struct output_block *ob,
   streamer_write_uhwi (ob, vec_safe_length (node->clone.tree_map));
   FOR_EACH_VEC_SAFE_ELT (node->clone.tree_map, i, map)
     {
-      int parm_num;
-      tree parm;
-
-      for (parm_num = 0, parm = DECL_ARGUMENTS (node->symbol.decl); parm;
-          parm = DECL_CHAIN (parm), parm_num++)
-       if (map->old_tree == parm)
-         break;
       /* At the moment we assume all old trees to be PARM_DECLs, because we have no
          mechanism to store function local declarations into summaries.  */
-      gcc_assert (parm);
-      streamer_write_uhwi (ob, parm_num);
+      gcc_assert (!map->old_tree);
+      streamer_write_uhwi (ob, map->parm_num);
       gcc_assert (EXPR_LOCATION (map->new_tree) == UNKNOWN_LOCATION);
       stream_write_tree (ob, map->new_tree, true);
       bp = bitpack_create (ob->main_stream);
index cac868a..9b2c815 100644 (file)
@@ -2057,6 +2057,11 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
   struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
   gcov_type count_scale;
 
+  if (!DECL_ARGUMENTS (new_fndecl))
+    DECL_ARGUMENTS (new_fndecl) = DECL_ARGUMENTS (callee_fndecl);
+  if (!DECL_RESULT (new_fndecl))
+    DECL_RESULT (new_fndecl) = DECL_RESULT (callee_fndecl);
+
   if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
     count_scale
         = GCOV_COMPUTE_SCALE (count,