aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-nested.c
diff options
context:
space:
mode:
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);