aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-nested.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-10-22 06:33:34 +0200
committerJan Hubicka <jh@suse.cz>2020-10-22 06:33:34 +0200
commit89576d863a879c4986867f991a6ac493106a9879 (patch)
tree507d7d68dfee1f4104d461f63007a79d5f2123d2 /gcc/tree-nested.c
parent52e7f09698ecb5ba6d9e921ffe912d1f66158e9e (diff)
downloadgcc-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.c110
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);