* 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
+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>,
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)
{
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. */
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);
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;
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;
{
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);
}
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;
if (!info->descriptors.exists ())
{
int param_count;
+ gcc_assert (!node->clone_of);
param_count = count_formal_params (node->symbol.decl);
if (param_count)
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);
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,