diff options
author | Jan Hubicka <jh@suse.cz> | 2020-10-22 06:33:34 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-10-22 06:33:34 +0200 |
commit | 89576d863a879c4986867f991a6ac493106a9879 (patch) | |
tree | 507d7d68dfee1f4104d461f63007a79d5f2123d2 /gcc/tree-nested.c | |
parent | 52e7f09698ecb5ba6d9e921ffe912d1f66158e9e (diff) | |
download | gcc-89576d863a879c4986867f991a6ac493106a9879.zip gcc-89576d863a879c4986867f991a6ac493106a9879.tar.gz gcc-89576d863a879c4986867f991a6ac493106a9879.tar.bz2 |
Move nested function info out of cgraph_node
this patch moves nested function information out of symbol table (to a summary).
This saves memory (especially at WPA time) and also makes nested function
support more contained.
gcc/ChangeLog:
2020-10-22 Jan Hubicka <hubicka@ucw.cz>
* cgraph.c: Include tree-nested.h
(cgraph_node::create): Call maybe_record_nested_function.
(cgraph_node::remove): Do not remove function from nested function
infos.
(cgraph_node::dump): Update.
(cgraph_node::unnest): Move to tree-nested.c
(cgraph_node::verify_node): Update.
(cgraph_c_finalize): Call nested_function_info::release.
* cgraph.h (struct symtab_node): Remove nested function info.
* cgraphclones.c (cgraph_node::create_clone): Do not clone nested
function info.
* cgraphunit.c (cgraph_node::analyze): Update.
(cgraph_node::expand): Do not worry about nested functions; they are
lowered.
(symbol_table::finalize_compilation_unit): Call
nested_function_info::release.
* gimplify.c: Include tree-nested.h
(unshare_body): Update.
(unvisit_body): Update.
* omp-offload.c (omp_discover_implicit_declare_target): Update.
* tree-nested.c: Include alloc-pool.h, tree-nested.h, symbol-summary.h
(nested_function_sum): New static variable.
(nested_function_info::get): New member function.
(nested_function_info::get_create): New member function.
(unnest_function): New function.
(nested_function_info::~nested_function_info): New member function.
(nested_function_info::release): New function.
(maybe_record_nested_function): New function.
(lookup_element_for_decl): Update.
(check_for_nested_with_variably_modified): Update.
(create_nesting_tree): Update.
(unnest_nesting_tree_1): Update.
(gimplify_all_functions): Update.
(lower_nested_functions): Update.
* tree-nested.h (class nested_function_info): New class.
(maybe_record_nested_function): Declare.
(unnest_function): Declare.
(first_nested_function): New inline function.
(next_nested_function): New inline function.
(nested_function_origin): New inline function.
gcc/ada/ChangeLog:
2020-10-22 Jan Hubicka <hubicka@ucw.cz>
* gcc-interface/trans.c: Include tree-nested.h
(walk_nesting_tree): Update for new nested function info.
gcc/c-family/ChangeLog:
2020-10-22 Jan Hubicka <hubicka@ucw.cz>
* c-gimplify.c: Include tree-nested.h
(c_genericize): Update for new nested function info.
gcc/d/ChangeLog:
2020-10-22 Jan Hubicka <hubicka@ucw.cz>
* decl.cc: Include tree-nested.h
(get_symbol_decl): Update for new nested function info.
Diffstat (limited to 'gcc/tree-nested.c')
-rw-r--r-- | gcc/tree-nested.c | 110 |
1 files changed, 103 insertions, 7 deletions
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index f74a727..433f37f 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -42,7 +42,100 @@ #include "gimple-low.h" #include "gomp-constants.h" #include "diagnostic.h" +#include "alloc-pool.h" +#include "tree-nested.h" +#include "symbol-summary.h" +/* Summary of nested functions. */ +static function_summary <nested_function_info *> + *nested_function_sum = NULL; + +/* Return nested_function_info, if available. */ +nested_function_info * +nested_function_info::get (cgraph_node *node) +{ + if (!nested_function_sum) + return NULL; + return nested_function_sum->get (node); +} + +/* Return nested_function_info possibly creating new one. */ +nested_function_info * +nested_function_info::get_create (cgraph_node *node) +{ + if (!nested_function_sum) + nested_function_sum = new function_summary <nested_function_info *> + (symtab); + return nested_function_sum->get_create (node); +} + +/* cgraph_node is no longer nested function; update cgraph accordingly. */ +void +unnest_function (cgraph_node *node) +{ + nested_function_info *info = nested_function_info::get (node); + cgraph_node **node2 = &nested_function_info::get + (nested_function_origin (node))->nested; + + gcc_checking_assert (info->origin); + while (*node2 != node) + node2 = &nested_function_info::get (*node2)->next_nested; + *node2 = info->next_nested; + info->next_nested = NULL; + info->origin = NULL; + nested_function_sum->remove (node); +} + +/* Destructor: unlink function from nested function lists. */ +nested_function_info::~nested_function_info () +{ + cgraph_node *next; + for (cgraph_node *n = nested; n; n = next) + { + nested_function_info *info = nested_function_info::get (n); + next = info->next_nested; + info->origin = NULL; + info->next_nested = NULL; + } + nested = NULL; + if (origin) + { + cgraph_node **node2 + = &nested_function_info::get (origin)->nested; + + nested_function_info *info; + while ((info = nested_function_info::get (*node2)) != this && info) + node2 = &info->next_nested; + *node2 = next_nested; + } +} + +/* Free nested function info summaries. */ +void +nested_function_info::release () +{ + if (nested_function_sum) + delete (nested_function_sum); + nested_function_sum = NULL; +} + +/* If NODE is nested function, record it. */ +void +maybe_record_nested_function (cgraph_node *node) +{ + if (DECL_CONTEXT (node->decl) + && TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL) + { + cgraph_node *origin = cgraph_node::get_create (DECL_CONTEXT (node->decl)); + nested_function_info *info = nested_function_info::get_create (node); + nested_function_info *origin_info + = nested_function_info::get_create (origin); + + info->origin = origin; + info->next_nested = origin_info->nested; + origin_info->nested = node; + } +} /* The object of this pass is to lower the representation of a set of nested functions in order to expose all of the gory details of the various @@ -586,7 +679,7 @@ lookup_element_for_decl (struct nesting_info *info, tree decl, *slot = build_tree_list (NULL_TREE, NULL_TREE); return (tree) *slot; -} +} /* Given DECL, a nested function, create a field in the non-local frame structure for this function. */ @@ -817,7 +910,8 @@ check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl) struct cgraph_node *cgn = cgraph_node::get (fndecl); tree arg; - for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) + for (cgn = first_nested_function (cgn); cgn; + cgn = next_nested_function (cgn)) { for (arg = DECL_ARGUMENTS (cgn->decl); arg; arg = DECL_CHAIN (arg)) if (variably_modified_type_p (TREE_TYPE (arg), orig_fndecl)) @@ -845,7 +939,8 @@ create_nesting_tree (struct cgraph_node *cgn) info->context = cgn->decl; info->thunk_p = cgn->thunk.thunk_p; - for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) + for (cgn = first_nested_function (cgn); cgn; + cgn = next_nested_function (cgn)) { struct nesting_info *sub = create_nesting_tree (cgn); sub->outer = info; @@ -3498,9 +3593,9 @@ unnest_nesting_tree_1 (struct nesting_info *root) /* For nested functions update the cgraph to reflect unnesting. We also delay finalizing of these functions up to this point. */ - if (node->origin) + if (nested_function_info::get (node)->origin) { - node->unnest (); + unnest_function (node); if (!root->thunk_p) cgraph_node::finalize_function (root->context, true); } @@ -3541,7 +3636,8 @@ gimplify_all_functions (struct cgraph_node *root) struct cgraph_node *iter; if (!gimple_body (root->decl)) gimplify_function_tree (root->decl); - for (iter = root->nested; iter; iter = iter->next_nested) + for (iter = first_nested_function (root); iter; + iter = next_nested_function (iter)) if (!iter->thunk.thunk_p) gimplify_all_functions (iter); } @@ -3557,7 +3653,7 @@ lower_nested_functions (tree fndecl) /* If there are no nested functions, there's nothing to do. */ cgn = cgraph_node::get (fndecl); - if (!cgn->nested) + if (!first_nested_function (cgn)) return; gimplify_all_functions (cgn); |