aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog49
-rw-r--r--gcc/Makefile.in4
-rw-r--r--gcc/cgraph.c53
-rw-r--r--gcc/cgraph.h146
-rw-r--r--gcc/cgraphunit.c29
-rw-r--r--gcc/ipa-inline.c4
-rw-r--r--gcc/ipa.c8
-rw-r--r--gcc/lto-cgraph.c10
-rw-r--r--gcc/lto-streamer-in.c4
-rw-r--r--gcc/symtab.c97
-rw-r--r--gcc/varpool.c36
11 files changed, 297 insertions, 143 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 11341910cc0..a2f6461eabb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,52 @@
+2012-04-16 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (symtab_node_base): Add next and previous pointers.
+ (cgraph_node): Remove next and preivous pointers.
+ (varpool_node): Likewise; remove next/previous GTY marker;
+ it is not type safe.
+ (symtab_node_def): Update GTY marker
+ (x_cgraph_nodes, cgraph_nodes): Remove.
+ (symtab_nodes): New function.
+ (cgraph_order): Rename to ...
+ (symtab_order): ... this one.
+ (symtab_register_node, symtab_unregister_node, symtab_remove_node):
+ Declare.
+ (x_varpool_nodes, varpool_nodes): Remove.
+ (FOR_EACH_STATIC_VARIABLE): Update.
+ (symtab_function_p, symtab_variable_p): New function.
+ (FOR_EACH_VARIABLE): Update.
+ (varpool_first_variable, varpool_next_variable): New functions.
+ (FOR_EACH_VARIABLE): Update.
+ (cgraph_first_defined_function): Update.
+ (cgraph_next_defined_function, cgraph_next_defined_function): Update.
+ (FOR_EACH_DEFINED_FUNCTION, FOR_EACH_FUNCTION): Update.
+ (cgraph_first_function, cgraph_next_function): New.
+ (FOR_EACH_FUNCTION): Update.
+ (cgraph_first_function_with_gimple_body,
+ cgraph_next_function_with_gimple_body): Update.
+ * symtab.c: New file.
+ * cgraph.c: Update copyright dates.
+ (x_cgraph_nodes, cgraph_order): Remove.
+ (NEXT_FREE_NODE): Update.
+ (SET_NEXT_FREE_NODE): New.
+ (cgraph_create_node_1): Remove common code.
+ (cgraph_create_node); Remove common code; call symtab_register_node.
+ (cgraph_remove_node): Remove common code; call symtab_unregister-node.
+ (cgraph_add_asm_node); update.
+ (cgraph_clone_node): Register new node.
+ * cgraphunit.c (process_function_and_variable_attributes): Update.
+ (cgraph_analyze_functions): Update.
+ (cgraph_analyze_functions): Update.
+ (cgraph_output_in_order): Update.
+ * lto-cgraph.c (input_node, input_varpool_node, input_cgraph_1): Update.
+ * ipa-inline.c (recursive_inlining); update.
+ * lto-streamer-in.c (lto_input_toplevel_asms); Update.
+ * ipa.c (cgraph_remove_unreachable_nodes): Update.
+ * Makefile.in: Add symtab.o
+ * varpool.c (x_varpool_nodes): Remove
+ (varpool_node): Remove common code; call symtab_register_node.
+ (varpool_remove_node); Remove common code; call symtab_unregister_node.
+
2012-04-16 Richard Guenther <rguenther@suse.de>
PR middle-end/52977
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0f87ea36a69..de8276401a2 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1173,6 +1173,7 @@ OBJS = \
cfgloopanal.o \
cfgloopmanip.o \
cfgrtl.o \
+ symtab.o \
cgraph.o \
cgraphbuild.o \
cgraphunit.o \
@@ -2909,6 +2910,9 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(RECOG_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \
$(TREE_H) $(TARGET_H)
+symtab.o : symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ langhooks.h toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
+ $(HASHTAB_H)
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 4f5a9dae52d..6a54db96301 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1,6 +1,6 @@
/* Callgraph handling code.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 2012 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
@@ -124,9 +124,6 @@ static GTY((param_is (union symtab_node_def))) htab_t cgraph_hash;
/* Hash table used to convert assembler names into nodes. */
static GTY((param_is (union symtab_node_def))) htab_t assembler_name_hash;
-/* The linked list of cgraph nodes. */
-symtab_node x_cgraph_nodes;
-
/* Queue of cgraph nodes scheduled to be lowered. */
symtab_node x_cgraph_nodes_queue;
#define cgraph_nodes_queue ((struct cgraph_node *)x_cgraph_nodes_queue)
@@ -160,11 +157,6 @@ struct cgraph_asm_node *cgraph_asm_nodes;
/* Last node in cgraph_asm_nodes. */
static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
-/* The order index of the next cgraph node to be created. This is
- used so that we can sort the cgraph nodes in order by when we saw
- them, to support -fno-toplevel-reorder. */
-int cgraph_order;
-
/* List of hooks triggered on cgraph_edge events. */
struct cgraph_edge_hook_list {
cgraph_edge_hook hook;
@@ -216,7 +208,8 @@ bool same_body_aliases_done;
/* Macros to access the next item in the list of free cgraph nodes and
edges. */
-#define NEXT_FREE_NODE(NODE) (NODE)->next
+#define NEXT_FREE_NODE(NODE) cgraph ((NODE)->symbol.next)
+#define SET_NEXT_FREE_NODE(NODE,NODE2) ((NODE))->symbol.next = (symtab_node)NODE2
#define NEXT_FREE_EDGE(EDGE) (EDGE)->prev_caller
/* Register HOOK to be called with DATA on each removed edge. */
@@ -475,15 +468,8 @@ cgraph_create_node_1 (void)
struct cgraph_node *node = cgraph_allocate_node ();
node->symbol.type = SYMTAB_FUNCTION;
- node->next = cgraph_nodes;
- node->symbol.order = cgraph_order++;
- if (cgraph_nodes)
- cgraph_nodes->previous = node;
- node->previous = NULL;
node->frequency = NODE_FREQUENCY_NORMAL;
node->count_materialization_scale = REG_BR_PROB_BASE;
- ipa_empty_ref_list (&node->symbol.ref_list);
- x_cgraph_nodes = (symtab_node)node;
cgraph_n_nodes++;
return node;
}
@@ -506,6 +492,7 @@ cgraph_create_node (tree decl)
node = cgraph_create_node_1 ();
node->symbol.decl = decl;
+ symtab_register_node ((symtab_node)node);
*slot = node;
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
{
@@ -1418,8 +1405,6 @@ cgraph_remove_node (struct cgraph_node *node)
cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->symbol.ref_list);
- ipa_remove_all_refering (&node->symbol.ref_list);
VEC_free (ipa_opt_pass, heap,
node->ipa_transforms_to_apply);
@@ -1437,14 +1422,7 @@ cgraph_remove_node (struct cgraph_node *node)
node2 = &(*node2)->next_nested;
*node2 = node->next_nested;
}
- if (node->previous)
- node->previous->next = node->next;
- else
- x_cgraph_nodes = (symtab_node)node->next;
- if (node->next)
- node->next->previous = node->previous;
- node->next = NULL;
- node->previous = NULL;
+ symtab_unregister_node ((symtab_node)node);
slot = htab_find_slot (cgraph_hash, node, NO_INSERT);
if (*slot == node)
{
@@ -1567,20 +1545,6 @@ cgraph_remove_node (struct cgraph_node *node)
}
}
- if (node->symbol.same_comdat_group)
- {
- symtab_node prev;
- for (prev = node->symbol.same_comdat_group;
- prev->symbol.same_comdat_group != (symtab_node)node;
- prev = prev->symbol.same_comdat_group)
- ;
- if (node->symbol.same_comdat_group == prev)
- prev->symbol.same_comdat_group = NULL;
- else
- prev->symbol.same_comdat_group = node->symbol.same_comdat_group;
- node->symbol.same_comdat_group = NULL;
- }
-
/* While all the clones are removed after being proceeded, the function
itself is kept in the cgraph even after it is compiled. Check whether
we are done with this body and reclaim it proactively if this is the case.
@@ -1621,7 +1585,7 @@ cgraph_remove_node (struct cgraph_node *node)
memset (node, 0, sizeof(*node));
node->symbol.type = SYMTAB_FUNCTION;
node->uid = uid;
- NEXT_FREE_NODE (node) = free_nodes;
+ SET_NEXT_FREE_NODE (node, free_nodes);
free_nodes = node;
}
@@ -2029,7 +1993,7 @@ cgraph_add_asm_node (tree asm_str)
node = ggc_alloc_cleared_cgraph_asm_node ();
node->asm_str = asm_str;
- node->order = cgraph_order++;
+ node->order = symtab_order++;
node->next = NULL;
if (cgraph_asm_nodes == NULL)
cgraph_asm_nodes = node;
@@ -2134,6 +2098,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
unsigned i;
new_node->symbol.decl = decl;
+ symtab_register_node ((symtab_node)new_node);
new_node->origin = n->origin;
if (new_node->origin)
{
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index e4c7b2a613c..e2f3b0b7f2b 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -57,6 +57,10 @@ struct GTY(()) symtab_node_base
/* File stream where this node is being written to. */
struct lto_file_decl_data * lto_file_data;
+ /* Linked list of symbol table entries starting with symtab_nodes. */
+ symtab_node next;
+ symtab_node previous;
+
PTR GTY ((skip)) aux;
/* Set when function has address taken.
@@ -190,12 +194,6 @@ struct GTY(()) cgraph_node {
struct symtab_node_base symbol;
struct cgraph_edge *callees;
struct cgraph_edge *callers;
- struct cgraph_node *
- GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
- next;
- struct cgraph_node *
- GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
- previous;
/* List of edges representing indirect calls with a yet undetermined
callee. */
struct cgraph_edge *indirect_calls;
@@ -417,17 +415,10 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
/* The varpool data structure.
Each static variable decl has assigned varpool_node. */
-struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node {
+struct GTY(()) varpool_node {
struct symtab_node_base symbol;
/* For aliases points to declaration DECL is alias of. */
tree alias_of;
- /* Pointer to the next function in varpool_nodes. */
- struct varpool_node *
- GTY ((nested_ptr (union symtab_node_def, "(struct varpool_node *)(%h)", "(symtab_node)%h")))
- next;
- struct varpool_node *
- GTY ((nested_ptr (union symtab_node_def, "(struct varpool_node *)(%h)", "(symtab_node)%h")))
- prev;
/* Pointer to the next function in varpool_nodes_queue. */
struct varpool_node *
GTY ((nested_ptr (union symtab_node_def, "(struct varpool_node *)(%h)", "(symtab_node)%h")))
@@ -467,7 +458,8 @@ struct GTY(()) cgraph_asm_node {
};
/* Symbol table entry. */
-union GTY((desc ("%h.symbol.type"))) symtab_node_def {
+union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"),
+ chain_prev ("%h.symbol.previous"))) symtab_node_def {
struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol;
/* Use cgraph (symbol) accessor to get cgraph_node. */
struct cgraph_node GTY ((tag ("SYMTAB_FUNCTION"))) x_function;
@@ -475,8 +467,7 @@ union GTY((desc ("%h.symbol.type"))) symtab_node_def {
struct varpool_node GTY ((tag ("SYMTAB_VARIABLE"))) x_variable;
};
-extern GTY(()) symtab_node x_cgraph_nodes;
-#define cgraph_nodes ((struct cgraph_node *)x_cgraph_nodes)
+extern GTY(()) symtab_node symtab_nodes;
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
extern GTY(()) int cgraph_edge_max_uid;
@@ -501,9 +492,14 @@ extern GTY(()) symtab_node x_cgraph_nodes_queue;
extern GTY(()) struct cgraph_node *cgraph_new_nodes;
extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
-extern GTY(()) int cgraph_order;
+extern GTY(()) int symtab_order;
extern bool same_body_aliases_done;
+/* In symtab.c */
+void symtab_register_node (symtab_node);
+void symtab_unregister_node (symtab_node);
+void symtab_remove_node (symtab_node);
+
/* In cgraph.c */
void dump_cgraph (FILE *);
void debug_cgraph (void);
@@ -684,9 +680,7 @@ bool cgraph_optimize_for_size_p (struct cgraph_node *);
/* In varpool.c */
extern GTY(()) symtab_node x_varpool_nodes_queue;
-extern GTY(()) symtab_node x_varpool_nodes;
#define varpool_nodes_queue ((struct varpool_node *)x_varpool_nodes_queue)
-#define varpool_nodes ((struct varpool_node *)x_varpool_nodes)
struct varpool_node *varpool_node (tree);
struct varpool_node *varpool_node_for_asm (tree asmname);
@@ -721,9 +715,19 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
void *, bool);
void varpool_add_new_variable (tree);
-/* Walk all reachable static variables. */
-#define FOR_EACH_STATIC_VARIABLE(node) \
- for ((node) = varpool_nodes_queue; (node); (node) = (node)->next_needed)
+/* Return true when NODE is function. */
+static inline bool
+symtab_function_p (symtab_node node)
+{
+ return node->symbol.type == SYMTAB_FUNCTION;
+}
+
+/* Return true when NODE is variable. */
+static inline bool
+symtab_variable_p (symtab_node node)
+{
+ return node->symbol.type == SYMTAB_VARIABLE;
+}
/* Return callgraph node for given symbol and check it is a function. */
static inline struct cgraph_node *
@@ -769,13 +773,44 @@ varpool_next_static_initializer (struct varpool_node *node)
return NULL;
}
+/* Walk all reachable static variables. */
+#define FOR_EACH_STATIC_VARIABLE(node) \
+ for ((node) = varpool_nodes_queue; (node); (node) = (node)->next_needed)
/* Walk all static variables with initializer set. */
#define FOR_EACH_STATIC_INITIALIZER(node) \
for ((node) = varpool_first_static_initializer (); (node); \
(node) = varpool_next_static_initializer (node))
+
+/* Return first variable. */
+static inline struct varpool_node *
+varpool_first_variable (void)
+{
+ symtab_node node;
+ for (node = symtab_nodes; node; node = node->symbol.next)
+ {
+ if (symtab_variable_p (node))
+ return varpool (node);
+ }
+ return NULL;
+}
+
+/* Return next variable after NODE. */
+static inline struct varpool_node *
+varpool_next_variable (struct varpool_node *node)
+{
+ symtab_node node1 = (symtab_node) node->symbol.next;
+ for (; node1; node1 = node1->symbol.next)
+ {
+ if (symtab_variable_p (node1))
+ return varpool (node1);
+ }
+ return NULL;
+}
/* Walk all variables. */
#define FOR_EACH_VARIABLE(node) \
- for ((node) = varpool_nodes; (node); (node) = (node)->next)
+ for ((node) = varpool_first_variable (); \
+ (node); \
+ (node) = varpool_next_variable ((node)))
/* Walk all variables with definitions in current unit. */
#define FOR_EACH_DEFINED_VARIABLE(node) \
for ((node) = varpool_nodes_queue; (node); (node) = (node)->next_needed)
@@ -784,11 +819,11 @@ varpool_next_static_initializer (struct varpool_node *node)
static inline struct cgraph_node *
cgraph_first_defined_function (void)
{
- struct cgraph_node *node;
- for (node = cgraph_nodes; node; node = node->next)
+ symtab_node node;
+ for (node = symtab_nodes; node; node = node->symbol.next)
{
- if (node->analyzed)
- return node;
+ if (symtab_function_p (node) && cgraph (node)->analyzed)
+ return cgraph (node);
}
return NULL;
}
@@ -797,10 +832,11 @@ cgraph_first_defined_function (void)
static inline struct cgraph_node *
cgraph_next_defined_function (struct cgraph_node *node)
{
- for (node = node->next; node; node = node->next)
+ symtab_node node1 = (symtab_node) node->symbol.next;
+ for (; node1; node1 = node1->symbol.next)
{
- if (node->analyzed)
- return node;
+ if (symtab_function_p (node1) && cgraph (node1)->analyzed)
+ return cgraph (node1);
}
return NULL;
}
@@ -808,10 +844,37 @@ cgraph_next_defined_function (struct cgraph_node *node)
/* Walk all functions with body defined. */
#define FOR_EACH_DEFINED_FUNCTION(node) \
for ((node) = cgraph_first_defined_function (); (node); \
- (node) = cgraph_next_defined_function (node))
+ (node) = cgraph_next_defined_function ((node)))
+
+/* Return first function. */
+static inline struct cgraph_node *
+cgraph_first_function (void)
+{
+ symtab_node node;
+ for (node = symtab_nodes; node; node = node->symbol.next)
+ {
+ if (symtab_function_p (node))
+ return cgraph (node);
+ }
+ return NULL;
+}
+
+/* Return next function. */
+static inline struct cgraph_node *
+cgraph_next_function (struct cgraph_node *node)
+{
+ symtab_node node1 = (symtab_node) node->symbol.next;
+ for (; node1; node1 = node1->symbol.next)
+ {
+ if (symtab_function_p (node1))
+ return cgraph (node1);
+ }
+ return NULL;
+}
/* Walk all functions. */
#define FOR_EACH_FUNCTION(node) \
- for ((node) = cgraph_nodes; (node); (node) = (node)->next)
+ for ((node) = cgraph_first_function (); (node); \
+ (node) = cgraph_next_function ((node)))
/* Return true when NODE is a function with Gimple body defined
in current unit. Functions can also be define externally or they
@@ -829,11 +892,12 @@ cgraph_function_with_gimple_body_p (struct cgraph_node *node)
static inline struct cgraph_node *
cgraph_first_function_with_gimple_body (void)
{
- struct cgraph_node *node;
- for (node = cgraph_nodes; node; node = node->next)
+ symtab_node node;
+ for (node = symtab_nodes; node; node = node->symbol.next)
{
- if (cgraph_function_with_gimple_body_p (node))
- return node;
+ if (symtab_function_p (node)
+ && cgraph_function_with_gimple_body_p (cgraph (node)))
+ return cgraph (node);
}
return NULL;
}
@@ -842,10 +906,12 @@ cgraph_first_function_with_gimple_body (void)
static inline struct cgraph_node *
cgraph_next_function_with_gimple_body (struct cgraph_node *node)
{
- for (node = node->next; node; node = node->next)
+ symtab_node node1 = node->symbol.next;
+ for (; node1; node1 = node1->symbol.next)
{
- if (cgraph_function_with_gimple_body_p (node))
- return node;
+ if (symtab_function_p (node1)
+ && cgraph_function_with_gimple_body_p (cgraph (node1)))
+ return cgraph (node1);
}
return NULL;
}
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index abe90120129..726d8839d3d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1085,7 +1085,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
struct cgraph_node *node;
struct varpool_node *vnode;
- for (node = cgraph_nodes; node != first; node = node->next)
+ for (node = cgraph_first_function (); node != first;
+ node = cgraph_next_function (node))
{
tree decl = node->symbol.decl;
if (DECL_PRESERVE_P (decl))
@@ -1126,7 +1127,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
process_common_attributes (decl);
}
- for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
+ for (vnode = varpool_first_variable (); vnode != first_var;
+ vnode = varpool_next_variable (vnode))
{
tree decl = vnode->symbol.decl;
if (DECL_PRESERVE_P (decl))
@@ -1184,13 +1186,14 @@ cgraph_analyze_functions (void)
bitmap_obstack_initialize (NULL);
process_function_and_variable_attributes (first_processed,
first_analyzed_var);
- first_processed = cgraph_nodes;
- first_analyzed_var = varpool_nodes;
+ first_processed = cgraph_first_function ();
+ first_analyzed_var = varpool_first_variable ();
varpool_analyze_pending_decls ();
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Initial entry points:");
- for (node = cgraph_nodes; node != first_analyzed; node = node->next)
+ for (node = cgraph_first_function (); node != first_analyzed;
+ node = cgraph_next_function (node))
if (node->needed)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n");
@@ -1255,8 +1258,8 @@ cgraph_analyze_functions (void)
edges. Process their attributes too. */
process_function_and_variable_attributes (first_processed,
first_analyzed_var);
- first_processed = cgraph_nodes;
- first_analyzed_var = varpool_nodes;
+ first_processed = cgraph_first_function ();
+ first_analyzed_var = varpool_first_variable ();
varpool_analyze_pending_decls ();
cgraph_process_new_functions ();
}
@@ -1265,7 +1268,8 @@ cgraph_analyze_functions (void)
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Unit entry points:");
- for (node = cgraph_nodes; node != first_analyzed; node = node->next)
+ for (node = cgraph_first_function (); node != first_analyzed;
+ node = cgraph_next_function (node))
if (node->needed)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n\nInitial ");
@@ -1276,10 +1280,11 @@ cgraph_analyze_functions (void)
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "\nReclaiming functions:");
- for (node = cgraph_nodes; node != first_analyzed; node = next)
+ for (node = cgraph_first_function (); node != first_analyzed;
+ node = next)
{
tree decl = node->symbol.decl;
- next = node->next;
+ next = cgraph_next_function (node);
if (node->local.finalized && !gimple_has_body_p (decl)
&& (!node->alias || !node->thunk.alias)
@@ -1309,7 +1314,7 @@ cgraph_analyze_functions (void)
dump_varpool (cgraph_dump_file);
}
bitmap_obstack_release (NULL);
- first_analyzed = cgraph_nodes;
+ first_analyzed = cgraph_first_function ();
ggc_collect ();
}
@@ -2076,7 +2081,7 @@ cgraph_output_in_order (void)
struct varpool_node *pv;
struct cgraph_asm_node *pa;
- max = cgraph_order;
+ max = symtab_order;
nodes = XCNEWVEC (struct cgraph_order_sort, max);
varpool_analyze_pending_decls ();
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index ebee1f97e99..8c41db8eb38 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1267,10 +1267,10 @@ recursive_inlining (struct cgraph_edge *edge,
/* Remove master clone we used for inlining. We rely that clones inlined
into master clone gets queued just before master clone so we don't
need recursion. */
- for (node = cgraph_nodes; node != master_clone;
+ for (node = cgraph_first_function (); node != master_clone;
node = next)
{
- next = node->next;
+ next = cgraph_next_function (node);
if (node->global.inlined_to == master_clone)
cgraph_remove_node (node);
}
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 7c35346fcbf..b46618809df 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -329,9 +329,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
Also we need to care functions that are unreachable but we need to keep them around
for later clonning. In this case we also turn them to unanalyzed nodes, but
keep the body around. */
- for (node = cgraph_nodes; node; node = next)
+ for (node = cgraph_first_function (); node; node = next)
{
- next = node->next;
+ next = cgraph_next_function (node);
if (node->symbol.aux && !node->reachable)
{
cgraph_node_remove_callees (node);
@@ -425,9 +425,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (file)
fprintf (file, "Reclaiming variables:");
- for (vnode = varpool_nodes; vnode; vnode = vnext)
+ for (vnode = varpool_first_variable (); vnode; vnode = vnext)
{
- vnext = vnode->next;
+ vnext = varpool_next_variable (vnode);
if (!vnode->needed)
{
if (file)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 421f62bc875..e6365b46ce8 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -998,8 +998,8 @@ input_node (struct lto_file_decl_data *file_data,
node = cgraph_get_create_node (fn_decl);
node->symbol.order = order;
- if (order >= cgraph_order)
- cgraph_order = order + 1;
+ if (order >= symtab_order)
+ symtab_order = order + 1;
node->count = streamer_read_hwi (ib);
node->count_materialization_scale = streamer_read_hwi (ib);
@@ -1069,8 +1069,8 @@ input_varpool_node (struct lto_file_decl_data *file_data,
var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
node = varpool_node (var_decl);
node->symbol.order = order;
- if (order >= cgraph_order)
- cgraph_order = order + 1;
+ if (order >= symtab_order)
+ symtab_order = order + 1;
node->symbol.lto_file_data = file_data;
bp = streamer_read_bitpack (ib);
@@ -1210,7 +1210,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
unsigned i;
tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
- order_base = cgraph_order;
+ order_base = symtab_order;
while (tag)
{
if (tag == LTO_cgraph_edge)
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 44513f758ef..1f2bfb6adc8 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1225,8 +1225,8 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
{
struct cgraph_asm_node *node = cgraph_add_asm_node (str);
node->order = streamer_read_hwi (&ib) + order_base;
- if (node->order >= cgraph_order)
- cgraph_order = node->order + 1;
+ if (node->order >= symtab_order)
+ symtab_order = node->order + 1;
}
clear_line_info (data_in);
diff --git a/gcc/symtab.c b/gcc/symtab.c
new file mode 100644
index 00000000000..c30f33d703f
--- /dev/null
+++ b/gcc/symtab.c
@@ -0,0 +1,97 @@
+/* Symbol table.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "hashtab.h"
+#include "cgraph.h"
+
+/* Linked list of symbol table nodes. */
+symtab_node symtab_nodes;
+
+/* The order index of the next symtab node to be created. This is
+ used so that we can sort the cgraph nodes in order by when we saw
+ them, to support -fno-toplevel-reorder. */
+int symtab_order;
+
+/* Add node into symbol table. This function is not used directly, but via
+ cgraph/varpool node creation routines. */
+
+void
+symtab_register_node (symtab_node node)
+{
+ node->symbol.next = symtab_nodes;
+ node->symbol.previous = NULL;
+ if (symtab_nodes)
+ symtab_nodes->symbol.previous = node;
+ symtab_nodes = node;
+
+ node->symbol.order = symtab_order++;
+
+ ipa_empty_ref_list (&node->symbol.ref_list);
+}
+
+/* Remove node from symbol table. This function is not used directly, but via
+ cgraph/varpool node removal routines. */
+
+void
+symtab_unregister_node (symtab_node node)
+{
+ ipa_remove_all_references (&node->symbol.ref_list);
+ ipa_remove_all_refering (&node->symbol.ref_list);
+
+ if (node->symbol.same_comdat_group)
+ {
+ symtab_node prev;
+ for (prev = node->symbol.same_comdat_group;
+ prev->symbol.same_comdat_group != node;
+ prev = prev->symbol.same_comdat_group)
+ ;
+ if (node->symbol.same_comdat_group == prev)
+ prev->symbol.same_comdat_group = NULL;
+ else
+ prev->symbol.same_comdat_group = node->symbol.same_comdat_group;
+ node->symbol.same_comdat_group = NULL;
+ }
+
+ if (node->symbol.previous)
+ node->symbol.previous->symbol.next = node->symbol.next;
+ else
+ symtab_nodes = node->symbol.next;
+ if (node->symbol.next)
+ node->symbol.next->symbol.previous = node->symbol.previous;
+ node->symbol.next = NULL;
+ node->symbol.previous = NULL;
+}
+
+/* Remove symtab NODE from the symbol table. */
+
+void
+symtab_remove_node (symtab_node node)
+{
+ if (symtab_function_p (node))
+ cgraph_remove_node (cgraph (node));
+ else if (symtab_variable_p (node))
+ varpool_remove_node (varpool (node));
+}
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 42acc58be60..8fd9e8ad16d 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -51,10 +51,6 @@ along with GCC; see the file COPYING3. If not see
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (union symtab_node_def))) htab_t varpool_hash;
-/* The linked list of cgraph varpool nodes.
- Linked via node->next pointer. */
-symtab_node x_varpool_nodes;
-
/* Queue of cgraph nodes scheduled to be lowered and output.
The queue is maintained via mark_needed_node, linked via node->next_needed
pointer.
@@ -146,12 +142,7 @@ varpool_node (tree decl)
node = ggc_alloc_cleared_varpool_node ();
node->symbol.type = SYMTAB_VARIABLE;
node->symbol.decl = decl;
- node->symbol.order = cgraph_order++;
- node->next = varpool_nodes;
- ipa_empty_ref_list (&node->symbol.ref_list);
- if (varpool_nodes)
- varpool (x_varpool_nodes)->prev = node;
- x_varpool_nodes = (symtab_node)node;
+ symtab_register_node ((symtab_node)node);
*slot = node;
return node;
}
@@ -165,15 +156,7 @@ varpool_remove_node (struct varpool_node *node)
gcc_assert (*slot == node);
htab_clear_slot (varpool_hash, slot);
gcc_assert (!varpool_assembled_nodes_queue);
- if (node->next)
- node->next->prev = node->prev;
- if (node->prev)
- node->prev->next = node->next;
- else
- {
- gcc_assert (varpool_nodes == node);
- x_varpool_nodes = (symtab_node)node->next;
- }
+ symtab_unregister_node ((symtab_node)node);
if (varpool_first_unanalyzed_node == node)
x_varpool_first_unanalyzed_node = (symtab_node)node->next_needed;
if (node->next_needed)
@@ -190,21 +173,6 @@ varpool_remove_node (struct varpool_node *node)
gcc_assert (varpool_nodes_queue == node);
x_varpool_nodes_queue = (symtab_node)node->next_needed;
}
- if (node->symbol.same_comdat_group)
- {
- symtab_node prev;
- for (prev = node->symbol.same_comdat_group;
- prev->symbol.same_comdat_group != (symtab_node)node;
- prev = prev->symbol.same_comdat_group)
- ;
- if (node->symbol.same_comdat_group == prev)
- prev->symbol.same_comdat_group = NULL;
- else
- prev->symbol.same_comdat_group = (symtab_node)node->symbol.same_comdat_group;
- node->symbol.same_comdat_group = NULL;
- }
- ipa_remove_all_references (&node->symbol.ref_list);
- ipa_remove_all_refering (&node->symbol.ref_list);
ggc_free (node);
}