summaryrefslogtreecommitdiff
path: root/gcc/cgraph.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraph.h')
-rw-r--r--gcc/cgraph.h188
1 files changed, 104 insertions, 84 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 8c0c882ac8b..d5d9eb07ad3 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1,6 +1,6 @@
/* Callgraph handling code.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- 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.
@@ -33,16 +33,43 @@ along with GCC; see the file COPYING3. If not see
TODO: add labels, constant pool and aliases. */
enum symtab_type
{
+ SYMTAB_SYMBOL,
SYMTAB_FUNCTION,
SYMTAB_VARIABLE
};
+union symtab_node_def;
+typedef union symtab_node_def *symtab_node;
+
/* Base of all entries in the symbol table.
The symtab_node is inherited by cgraph and varpol nodes. */
-struct GTY(()) symtab_node
+struct GTY(()) symtab_node_base
{
/* Type of the symbol. */
enum symtab_type type;
+ tree decl;
+ struct ipa_ref_list ref_list;
+ /* Circular list of nodes in the same comdat group if non-NULL. */
+ symtab_node same_comdat_group;
+ /* Ordering of all symtab entries. */
+ int order;
+ enum ld_plugin_symbol_resolution resolution;
+ /* File stream where this node is being written to. */
+ struct lto_file_decl_data * lto_file_data;
+
+ PTR GTY ((skip)) aux;
+
+ /* Set when function has address taken.
+ In current implementation it imply needed flag. */
+ unsigned address_taken : 1;
+ /* Set when variable is used from other LTRANS partition. */
+ unsigned used_from_other_partition : 1;
+ /* Set when function is available in the other LTRANS partition.
+ During WPA output it is used to mark nodes that are present in
+ multiple partitions. */
+ unsigned in_other_partition : 1;
+ /* Set when function is visible by other units. */
+ unsigned externally_visible : 1;
};
enum availability
@@ -91,16 +118,10 @@ struct GTY(()) cgraph_thunk_info {
Available after function is analyzed. */
struct GTY(()) cgraph_local_info {
- /* File stream where this node is being written to. */
- struct lto_file_decl_data * lto_file_data;
-
/* Set when function function is visible in current compilation unit only
and its address is never taken. */
unsigned local : 1;
- /* Set when function is visible by other units. */
- unsigned externally_visible : 1;
-
/* Set once it has been finalized so we consider it to be output. */
unsigned finalized : 1;
@@ -165,45 +186,51 @@ struct GTY(()) cgraph_clone_info
/* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */
-struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
- struct symtab_node symbol;
- tree decl;
+struct GTY(()) cgraph_node {
+ struct symtab_node_base symbol;
struct cgraph_edge *callees;
struct cgraph_edge *callers;
- struct cgraph_node *next;
- struct cgraph_node *previous;
+ 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;
/* For nested functions points to function the node is nested in. */
- struct cgraph_node *origin;
+ struct cgraph_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
+ origin;
/* Points to first nested function, if any. */
- struct cgraph_node *nested;
+ struct cgraph_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
+ nested;
/* Pointer to the next function with same origin, if any. */
- struct cgraph_node *next_nested;
+ struct cgraph_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
+ next_nested;
/* Pointer to the next function in cgraph_nodes_queue. */
- struct cgraph_node *next_needed;
+ struct cgraph_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h")))
+ next_needed;
/* Pointer to the next clone. */
struct cgraph_node *next_sibling_clone;
struct cgraph_node *prev_sibling_clone;
struct cgraph_node *clones;
struct cgraph_node *clone_of;
- /* Circular list of nodes in the same comdat group if non-NULL. */
- struct cgraph_node *same_comdat_group;
/* For functions with many calls sites it holds map from call expression
to the edge to speed up cgraph_edge function. */
htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
/* Declaration node used to be clone of. */
tree former_clone_of;
- PTR GTY ((skip)) aux;
-
/* Interprocedural passes scheduled to have their transform functions
applied next time we execute local pass on them. We maintain it
per-function in order to allow IPA passes to introduce new functions. */
VEC(ipa_opt_pass,heap) * GTY((skip)) ipa_transforms_to_apply;
- struct ipa_ref_list ref_list;
struct cgraph_local_info local;
struct cgraph_global_info global;
struct cgraph_rtl_info rtl;
@@ -217,10 +244,6 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
int count_materialization_scale;
/* Unique id of the node. */
int uid;
- /* Ordering of all cgraph nodes. */
- int order;
-
- enum ld_plugin_symbol_resolution resolution;
/* Set when function must be output for some reason. The primary
use of this flag is to mark functions needed to be output for
@@ -228,9 +251,6 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
or reachable from functions needed to be output are marked
by specialized flags. */
unsigned needed : 1;
- /* Set when function has address taken.
- In current implementation it imply needed flag. */
- unsigned address_taken : 1;
/* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */
unsigned abstract_and_needed : 1;
@@ -241,17 +261,11 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
cgraph_remove_unreachable_nodes cgraph still can contain unreachable
nodes when they are needed for virtual clone instantiation. */
unsigned reachable : 1;
- /* Set when function is reachable by call from other LTRANS partition. */
- unsigned reachable_from_other_partition : 1;
/* Set once the function is lowered (i.e. its CFG is built). */
unsigned lowered : 1;
/* Set once the function has been instantiated and its callee
lists created. */
unsigned analyzed : 1;
- /* Set when function is available in the other LTRANS partition.
- During WPA output it is used to mark nodes that are present in
- multiple partitions. */
- unsigned in_other_partition : 1;
/* Set when function is scheduled to be processed by local passes. */
unsigned process : 1;
/* Set for aliases once they got through assemble_alias. */
@@ -404,23 +418,23 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
Each static variable decl has assigned varpool_node. */
struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node {
- struct symtab_node symbol;
- tree decl;
+ 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 *next, *prev;
+ 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 *next_needed, *prev_needed;
- /* Circular list of nodes in the same comdat group if non-NULL. */
- struct varpool_node *same_comdat_group;
- struct ipa_ref_list ref_list;
- /* File stream where this node is being written to. */
- struct lto_file_decl_data * lto_file_data;
- PTR GTY ((skip)) aux;
- /* Ordering of all cgraph nodes. */
- int order;
- enum ld_plugin_symbol_resolution resolution;
+ struct varpool_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct varpool_node *)(%h)", "(symtab_node)%h")))
+ next_needed;
+ struct varpool_node *
+ GTY ((nested_ptr (union symtab_node_def, "(struct varpool_node *)(%h)", "(symtab_node)%h")))
+ prev_needed;
/* Set when function must be output - it is externally visible
or its address is taken. */
@@ -435,18 +449,10 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node {
unsigned finalized : 1;
/* Set when variable is scheduled to be assembled. */
unsigned output : 1;
- /* Set when function is visible by other units. */
- unsigned externally_visible : 1;
/* Set for aliases once they got through assemble_alias. Also set for
extra name aliases in varpool_extra_name_alias. */
unsigned alias : 1;
unsigned extra_name_alias : 1;
- /* Set when variable is used from other LTRANS partition. */
- unsigned used_from_other_partition : 1;
- /* Set when variable is available in the other LTRANS partition.
- During WPA output it is used to mark nodes that are present in
- multiple partitions. */
- unsigned in_other_partition : 1;
};
/* Every top level asm statement is put into a cgraph_asm_node. */
@@ -460,7 +466,17 @@ struct GTY(()) cgraph_asm_node {
int order;
};
-extern GTY(()) struct cgraph_node *cgraph_nodes;
+/* Symbol table entry. */
+union GTY((desc ("%h.symbol.type"))) 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;
+ /* Use varpool (symbol) accessor to get varpool_node. */
+ 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(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
extern GTY(()) int cgraph_edge_max_uid;
@@ -480,7 +496,8 @@ enum cgraph_state
};
extern enum cgraph_state cgraph_state;
extern bool cgraph_function_flags_ready;
-extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
+extern GTY(()) symtab_node x_cgraph_nodes_queue;
+#define cgraph_nodes_queue ((struct cgraph_node *)x_cgraph_nodes_queue)
extern GTY(()) struct cgraph_node *cgraph_new_nodes;
extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
@@ -666,8 +683,10 @@ bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
bool cgraph_optimize_for_size_p (struct cgraph_node *);
/* In varpool.c */
-extern GTY(()) struct varpool_node *varpool_nodes_queue;
-extern GTY(()) struct varpool_node *varpool_nodes;
+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);
@@ -708,18 +727,18 @@ void varpool_add_new_variable (tree);
/* Return callgraph node for given symbol and check it is a function. */
static inline struct cgraph_node *
-cgraph (struct symtab_node *node)
+cgraph (symtab_node node)
{
- gcc_checking_assert (node->type == SYMTAB_FUNCTION);
- return (struct cgraph_node *)node;
+ gcc_checking_assert (!node || node->symbol.type == SYMTAB_FUNCTION);
+ return &node->x_function;
}
/* Return varpool node for given symbol and check it is a variable. */
static inline struct varpool_node *
-varpool (struct symtab_node *node)
+varpool (symtab_node node)
{
- gcc_checking_assert (node->type == SYMTAB_FUNCTION);
- return (struct varpool_node *)node;
+ gcc_checking_assert (!node || node->symbol.type == SYMTAB_VARIABLE);
+ return &node->x_variable;
}
@@ -730,8 +749,8 @@ varpool_first_static_initializer (void)
struct varpool_node *node;
for (node = varpool_nodes_queue; node; node = node->next_needed)
{
- gcc_checking_assert (TREE_CODE (node->decl) == VAR_DECL);
- if (DECL_INITIAL (node->decl))
+ gcc_checking_assert (TREE_CODE (node->symbol.decl) == VAR_DECL);
+ if (DECL_INITIAL (node->symbol.decl))
return node;
}
return NULL;
@@ -743,8 +762,8 @@ varpool_next_static_initializer (struct varpool_node *node)
{
for (node = node->next_needed; node; node = node->next_needed)
{
- gcc_checking_assert (TREE_CODE (node->decl) == VAR_DECL);
- if (DECL_INITIAL (node->decl))
+ gcc_checking_assert (TREE_CODE (node->symbol.decl) == VAR_DECL);
+ if (DECL_INITIAL (node->symbol.decl))
return node;
}
return NULL;
@@ -966,11 +985,11 @@ static inline bool
cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node)
{
gcc_assert (!node->global.inlined_to);
- return (!node->needed && !node->address_taken
- && !node->reachable_from_other_partition
- && !DECL_STATIC_CONSTRUCTOR (node->decl)
- && !DECL_STATIC_DESTRUCTOR (node->decl)
- && !node->local.externally_visible);
+ return (!node->needed && !node->symbol.address_taken
+ && !node->symbol.used_from_other_partition
+ && !DECL_STATIC_CONSTRUCTOR (node->symbol.decl)
+ && !DECL_STATIC_DESTRUCTOR (node->symbol.decl)
+ && !node->symbol.externally_visible);
}
/* Return true when function NODE can be removed from callgraph
@@ -979,8 +998,9 @@ cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node)
static inline bool
varpool_can_remove_if_no_refs (struct varpool_node *node)
{
- return (!node->force_output && !node->used_from_other_partition
- && (DECL_COMDAT (node->decl) || !node->externally_visible));
+ return (!node->force_output && !node->symbol.used_from_other_partition
+ && (DECL_COMDAT (node->symbol.decl)
+ || !node->symbol.externally_visible));
}
/* Return true when all references to VNODE must be visible in ipa_ref_list.
@@ -992,8 +1012,8 @@ static inline bool
varpool_all_refs_explicit_p (struct varpool_node *vnode)
{
return (vnode->analyzed
- && !vnode->externally_visible
- && !vnode->used_from_other_partition
+ && !vnode->symbol.externally_visible
+ && !vnode->symbol.used_from_other_partition
&& !vnode->force_output);
}
@@ -1010,7 +1030,7 @@ cgraph_alias_aliased_node (struct cgraph_node *n)
{
struct ipa_ref *ref;
- ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
+ ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
if (ref->refered_type == IPA_REF_CGRAPH)
return ipa_ref_node (ref);
@@ -1024,7 +1044,7 @@ varpool_alias_aliased_node (struct varpool_node *n)
{
struct ipa_ref *ref;
- ipa_ref_list_reference_iterate (&n->ref_list, 0, ref);
+ ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
if (ref->refered_type == IPA_REF_VARPOOL)
return ipa_ref_varpool_node (ref);
@@ -1123,9 +1143,9 @@ cgraph_edge_recursive_p (struct cgraph_edge *e)
{
struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
if (e->caller->global.inlined_to)
- return e->caller->global.inlined_to->decl == callee->decl;
+ return e->caller->global.inlined_to->symbol.decl == callee->symbol.decl;
else
- return e->caller->decl == callee->decl;
+ return e->caller->symbol.decl == callee->symbol.decl;
}
/* Return true if the TM_CLONE bit is set for a given FNDECL. */