From: Jan Hubicka Date: Thu, 25 Jul 2013 17:10:21 +0000 (+0200) Subject: cgraph.c (release_function_body): Break out from ... X-Git-Tag: upstream/12.2.0~68643 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=49bde17554926a2352b7f1df98d4e02becc1e065;p=platform%2Fupstream%2Fgcc.git cgraph.c (release_function_body): Break out from ... * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53dc68c..b406b15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-07-25 Jan Hubicka + + * 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 * config/arm/arm.md (arm_addsi3, addsi3_carryin_, diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c6ade31..be3411d 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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. */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 5c328b7..04cb990 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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); diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 05c6e74..73f9d6e 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -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); } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 84aeb45..bf9e903 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -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) diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 4a287f6..d60213a 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index cac868a..9b2c815 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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,