aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraph.h
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2014-08-25 15:01:47 +0200
committerMartin Liska <marxin@gcc.gnu.org>2014-08-25 13:01:47 +0000
commit3dafb85c8e6ade82adc591fe97c116b193f8bb0d (patch)
tree6efa3ef534f8ca5761c35200d5cc61a819dde6f4 /gcc/cgraph.h
parent3749134042ab5f54d0c30af1ec336e7132ac9bc8 (diff)
downloadgcc-3dafb85c8e6ade82adc591fe97c116b193f8bb0d.zip
gcc-3dafb85c8e6ade82adc591fe97c116b193f8bb0d.tar.gz
gcc-3dafb85c8e6ade82adc591fe97c116b193f8bb0d.tar.bz2
IPA C++ refactoring 4/N
* cgraph.h (symtab_node): (bool needed_p (void)): created from decide_is_symbol_needed (bool referred_to_p (void)): created from referred_to_p (static cgraph_node *get_for_asmname (tree asmname)): created from symtab_node_for_asm * cgraph.h (cgraph_node): (void assemble_thunks_and_aliases (void)): created from assemble_thunks_and_aliases (void expand (void)): created from expand_function (static void finalize_function (tree, bool)): created from cgraph_finalize_function (static cgraph_local_info *local_info (tree decl)): created from cgraph_local_info (static cgraph_global_info *global_info (tree)): created from cgraph_global_info (static cgraph_rtl_info *rtl_info (tree)): created from cgraph_rtl_info * cgraph.h (varpool_node): (static void add (tree decl): created from varpool_add_new_variable * cgraph.h (cgraph_edge): void remove (void); (void remove_caller (void)): created from cgraph_edge_remove_caller (void remove_callee (void)): created from cgraph_edge_remove_callee (void set_call_stmt (gimple new_stmt, bool update_speculative = true)): created from cgraph_set_call_stmt (void redirect_callee (cgraph_node *n)): created from cgraph_redirect_edge_callee (cgraph_edge *make_direct (cgraph_node *callee)): created from cgraph_make_edge_direct (cgraph_edge *make_speculative (cgraph_node *n2, gcov_type direct_count, gimple redirect_call_stmt_to_callee (void)): created from cgraph_turn_edge_to_speculative (void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect, ipa_ref *&reference)): created from cgraph_speculative_call_info (cgraph_edge * clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid, gcov_type count_scale, int freq_scale, bool update_original)): created from cgraph_clone_edge (cgraph_edge *resolve_speculation (tree callee_decl)): created from cgraph_resolve_speculation (bool cannot_lead_to_return_p (void)): created from cannot_lead_to_return_p (bool recursive_p (void)): created from cgraph_edge_recursive_p (bool maybe_hot_p (void)): created from cgraph_maybe_hot_edge_p (static unsigned int rebuild_edges (void)): created from rebuild_cgraph_edges (static void rebuild_references (void)): created from cgraph_rebuild_references * cgraph.h (symbol_table): (create_reference): renamed from add_reference (maybe_create_reference): renamed from maybe_add_reference (void register_symbol (symtab_node *node)): new function (void clear_asm_symbols (void)): new function (void unregister (symtab_node *node)): new function (void release_symbol (cgraph_node *node, int uid)): new function (cgraph_node * allocate_cgraph_symbol (void)): new function (void initialize (void)): created from cgraph_init (symtab_node *first_symbol (void)):new function (asm_node *first_asm_symbol (void)):new function (symtab_node *first_defined_symbol (void)):new function (varpool_node *first_variable (void)):new function (varpool_node *next_variable (varpool_node *node)):new function (varpool_node *first_static_initializer (void)):new function (varpool_node *next_static_initializer (varpool_node *node)):new function (varpool_node *first_defined_variable (void)):new function (varpool_node *next_defined_variable (varpool_node *node)):new function (cgraph_node *first_defined_function (void)):new function (cgraph_node *next_defined_function (cgraph_node *node)):new function (cgraph_node *first_function (void)):new function (cgraph_node *next_function (cgraph_node *node)):new function (cgraph_node *first_function_with_gimple_body (void)):new function (asm_node *finalize_toplevel_asm (tree asm_str)): created from add_asm_node (bool remove_unreachable_nodes (bool before_inlining_p, FILE *file)): created from symtab_remove_unreachable_nodes (void remove_unreferenced_decls (void)): created from varpool_remove_unreferenced_decls (void process_new_functions (void)): created from cgraph_process_new_functions (void process_same_body_aliases (void)): created from cgraph_process_same_body_aliases (bool output_variables (void)): created from varpool_node::output_variables (void output_asm_statements (void)): created from output_asm_statements (void finalize_compilation_unit (void)): created from finalize_compilation_unit (void compile (void)): created from compile (void output_weakrefs (void)): created from output_weakrefs (cgraph_node *create_empty (void)): created from cgraph_node::create_empty (cgraph_edge *create_edge (cgraph_node *caller, cgraph_node *callee, gimple call_stmt, gcov_type count, int freq, bool indir_unknown_callee)): created from cgraph_node::create_edge (void free_edge (cgraph_edge *e)): created from cgraph_free_edge (cgraph_node *next_function_with_gimple_body (cgraph_node *node)): created from cgraph_next_function_with_gimple_body (void remove_edge_removal_hook (cgraph_edge_hook_list *)): created from cgraph_remove_edge_removal_hook (cgraph_node_hook_list *add_cgraph_removal_hook (cgraph_node_hook, void *)): created from cgraph_add_node_removal_hook (void remove_cgraph_removal_hook (cgraph_node_hook_list *)): created from cgraph_remove_node_removal_hook (varpool_node_hook_list *add_varpool_removal_hook (varpool_node_hook, void *)): created from varpool_add_node_removal_hook (void remove_varpool_removal_hook (varpool_node_hook_list *)): created from varpool_remove_node_removal_hook (cgraph_node_hook_list *add_cgraph_insertion_hook (cgraph_node_hook, void *)): created from cgraph_add_function_insertion_hook (void remove_cgraph_insertion_hook (cgraph_node_hook_list *)): created from cgraph_remove_function_insertion_hook (varpool_node_hook_list *add_varpool_insertion_hook (varpool_node_hook, void *)): created from varpool_add_variable_insertion_hook (void remove_varpool_insertion_hook (varpool_node_hook_list *)): created from varpool_remove_variable_insertion_hook (cgraph_2edge_hook_list *add_edge_duplication_hook (cgraph_2edge_hook, void *)): created from cgraph_add_edge_duplication_hook (void remove_edge_duplication_hook (cgraph_2edge_hook_list *)): created from cgraph_remove_edge_duplication_hook (cgraph_2node_hook_list *add_cgraph_duplication_hook (cgraph_2node_hook, void *)): created from cgraph_add_node_duplication_hook (void remove_cgraph_duplication_hook (cgraph_2node_hook_list *)): created from cgraph_remove_node_duplication_hook (void call_edge_removal_hooks (cgraph_edge *e)): created from cgraph_call_edge_removal_hooks (void call_cgraph_insertion_hooks (cgraph_node *node)): created from call_function_insertion_hooks (void call_cgraph_removal_hooks (cgraph_node *node)): created from cgraph_call_node_removal_hooks (void call_cgraph_duplication_hooks (cgraph_node *node, cgraph_node *node2)): created from cgraph_node::call_duplication_hooks (void call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)): created from cgraph_call_edge_duplication_hooks (void call_varpool_removal_hooks (varpool_node *node)): created from varpool_call_node_removal_hooks (void call_varpool_insertion_hooks (varpool_node *node)): created from varpool_call_variable_insertion_hooks (void insert_to_assembler_name_hash (symtab_node *node, bool with_clones)): created from insert_to_assembler_name_hash (void unlink_from_assembler_name_hash (symtab_node *node, bool with_clones)): created from unlink_from_assembler_name_hash (void symtab_prevail_in_asm_name_hash (symtab_node *node)): created from symtab_prevail_in_asm_name_hash (void symtab_initialize_asm_name_hash (void)): created from symtab_initialize_asm_name_hash (void change_decl_assembler_name (tree decl, tree name)): created from change_decl_assembler_name (void materialize_all_clones (void)): created from cgraph_materialize_all_clones (static hashval_t decl_assembler_name_hash (const_tree asmname)): created from decl_assembler_name_hash (static bool decl_assembler_name_equal (tree decl, const_tree asmname)): created from decl_assembler_name_equal (static hashval_t hash_node_by_assembler_name (const void *p)): created from hash_node_by_assembler_name (static int eq_assembler_name (const void *p1, const void *p2)): created from eq_assembler_name From-SVN: r214422
Diffstat (limited to 'gcc/cgraph.h')
-rw-r--r--gcc/cgraph.h905
1 files changed, 675 insertions, 230 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 2594ae5..879899c 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "function.h"
#include "ipa-ref.h"
+#include "dumpfile.h"
/* Symbol table consists of functions and variables.
TODO: add labels and CONST_DECLs. */
@@ -117,21 +118,21 @@ public:
/* Return ipa reference from this symtab_node to
REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
of the use and STMT the statement (if it exists). */
- struct ipa_ref *add_reference (symtab_node *referred_node,
- enum ipa_ref_use use_type);
+ ipa_ref *create_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type);
/* Return ipa reference from this symtab_node to
REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
of the use and STMT the statement (if it exists). */
- struct ipa_ref *add_reference (symtab_node *referred_node,
- enum ipa_ref_use use_type, gimple stmt);
+ ipa_ref *create_reference (symtab_node *referred_node,
+ enum ipa_ref_use use_type, gimple stmt);
/* If VAL is a reference to a function or a variable, add a reference from
this symtab_node to the corresponding symbol table node. USE_TYPE specify
type of the use and STMT the statement (if it exists). Return the new
reference or NULL if none was created. */
- struct ipa_ref *maybe_add_reference (tree val, enum ipa_ref_use use_type,
- gimple stmt);
+ ipa_ref *maybe_create_reference (tree val, enum ipa_ref_use use_type,
+ gimple stmt);
/* Clone all references from symtab NODE to this symtab_node. */
void clone_references (symtab_node *node);
@@ -143,12 +144,12 @@ public:
void clone_referring (symtab_node *node);
/* Clone reference REF to this symtab_node and set its stmt to STMT. */
- struct ipa_ref *clone_reference (struct ipa_ref *ref, gimple stmt);
+ ipa_ref *clone_reference (ipa_ref *ref, gimple stmt);
/* Find the structure describing a reference to REFERRED_NODE
and associated with statement STMT. */
- struct ipa_ref *find_reference (symtab_node *referred_node, gimple stmt,
- unsigned int lto_stmt_uid);
+ ipa_ref *find_reference (symtab_node *referred_node, gimple stmt,
+ unsigned int lto_stmt_uid);
/* Remove all references that are associated with statement STMT. */
void remove_stmt_references (gimple stmt);
@@ -172,13 +173,13 @@ public:
void dump_referring (FILE *);
/* Iterates I-th reference in the list, REF is also set. */
- struct ipa_ref *iterate_reference (unsigned i, struct ipa_ref *&ref);
+ ipa_ref *iterate_reference (unsigned i, ipa_ref *&ref);
/* Iterates I-th referring item in the list, REF is also set. */
- struct ipa_ref *iterate_referring (unsigned i, struct ipa_ref *&ref);
+ ipa_ref *iterate_referring (unsigned i, ipa_ref *&ref);
/* Iterates I-th referring alias item in the list, REF is also set. */
- struct ipa_ref *iterate_direct_aliases (unsigned i, struct ipa_ref *&ref);
+ ipa_ref *iterate_direct_aliases (unsigned i, ipa_ref *&ref);
/* Return true if symtab node and TARGET represents
semantically equivalent symbols. */
@@ -289,6 +290,14 @@ public:
or abstract function kept for debug info purposes only. */
bool real_symbol_p (void);
+ /* Determine if symbol declaration is needed. That is, visible to something
+ either outside this translation unit, something magic in the system
+ configury. This function is used just during symbol creation. */
+ bool needed_p (void);
+
+ /* Return true when there are references to the node. */
+ bool referred_to_p (void);
+
/* Return true if NODE can be discarded by linker from the binary. */
inline bool
can_be_discarded_p (void)
@@ -337,6 +346,10 @@ public:
return decl->decl_with_vis.symtab_node;
}
+ /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
+ Return NULL if there's no such node. */
+ static symtab_node *get_for_asmname (const_tree asmname);
+
/* Dump symbol table to F. */
static void dump_table (FILE *);
@@ -362,7 +375,7 @@ public:
/*** Flags representing the symbol type. ***/
/* True when symbol corresponds to a definition in current unit.
- set via cgraph_finalize_function or varpool_finalize_decl */
+ set via finalize_function or finalize_decl */
unsigned definition : 1;
/* True when symbol is an alias.
Set by ssemble_alias. */
@@ -450,7 +463,7 @@ public:
symtab_node *same_comdat_group;
/* Vectors of referring and referenced entities. */
- struct ipa_ref_list ref_list;
+ ipa_ref_list ref_list;
/* Alias target. May be either DECL pointer or ASSEMBLER_NAME pointer
depending to what was known to frontend on the creation time.
@@ -679,7 +692,7 @@ struct GTY(()) cgraph_simd_clone {
cgraph_node *origin;
/* Annotated function arguments for the original function. */
- struct cgraph_simd_clone_arg GTY((length ("%h.nargs"))) args[1];
+ cgraph_simd_clone_arg GTY((length ("%h.nargs"))) args[1];
};
/* Function Multiversioning info. */
@@ -689,11 +702,11 @@ struct GTY(()) cgraph_function_version_info {
/* Chains all the semantically identical function versions. The
first function in this chain is the version_info node of the
default function. */
- struct cgraph_function_version_info *prev;
+ cgraph_function_version_info *prev;
/* If this version node corresponds to a dispatcher for function
versions, this points to the version info node of the default
function, the first node in the chain. */
- struct cgraph_function_version_info *next;
+ cgraph_function_version_info *next;
/* If this node corresponds to a function version, this points
to the dispatcher function decl, which is the function that must
be called to execute the right function version at run-time.
@@ -769,7 +782,7 @@ public:
bool update_original,
vec<cgraph_edge *> redirect_callers,
bool call_duplication_hook,
- struct cgraph_node *new_inlined_to,
+ cgraph_node *new_inlined_to,
bitmap args_to_skip);
/* Create callgraph node clone with new declaration. The actual body will
@@ -823,10 +836,10 @@ public:
/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
corresponding to cgraph_node. */
- struct cgraph_function_version_info *insert_new_function_version (void);
+ cgraph_function_version_info *insert_new_function_version (void);
/* Get the cgraph_function_version_info node corresponding to node. */
- struct cgraph_function_version_info *function_version (void);
+ cgraph_function_version_info *function_version (void);
/* Discover all functions and variables that are trivially needed, analyze
them as well as all functions and variables referred by them */
@@ -858,6 +871,12 @@ public:
thunks that are not lowered. */
bool expand_thunk (bool output_asm_thunks, bool force_gimple_thunk);
+ /* Assemble thunks and aliases associated to node. */
+ void assemble_thunks_and_aliases (void);
+
+ /* Expand function specified by node. */
+ void expand (void);
+
/* As an GCC extension we allow redefinition of the function. The
semantics when both copies of bodies differ is not well defined.
We replace the old body with new body so in unit at a time mode
@@ -908,20 +927,21 @@ public:
priority_type get_fini_priority (void);
/* Create edge from a given function to CALLEE in the cgraph. */
- struct cgraph_edge *create_edge (cgraph_node *callee,
- gimple call_stmt, gcov_type count,
- int freq);
+ cgraph_edge *create_edge (cgraph_node *callee,
+ gimple call_stmt, gcov_type count,
+ int freq);
+
/* Create an indirect edge with a yet-undetermined callee where the call
statement destination is a formal parameter of the caller with index
PARAM_INDEX. */
- struct cgraph_edge *create_indirect_edge (gimple call_stmt, int ecf_flags,
- gcov_type count, int freq,
- bool compute_indirect_info = true);
+ cgraph_edge *create_indirect_edge (gimple call_stmt, int ecf_flags,
+ gcov_type count, int freq,
+ bool compute_indirect_info = true);
/* Like cgraph_create_edge walk the clone tree and update all clones sharing
same function body. If clones already have edge for OLD_STMT; only
update the edge same way as cgraph_set_call_stmt_including_clones does. */
- void create_edge_including_clones (struct cgraph_node *callee,
+ void create_edge_including_clones (cgraph_node *callee,
gimple old_stmt, gimple stmt,
gcov_type count,
int freq,
@@ -957,9 +977,6 @@ public:
if any to PURE. */
void set_pure_flag (bool pure, bool looping);
- /* Call all node duplication hooks. */
- void call_duplication_hooks (cgraph_node *node2);
-
/* Call calback on function and aliases associated to the function.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */
@@ -976,9 +993,6 @@ public:
void *data,
bool include_overwritable);
- /* Call all node insertion hooks. */
- void call_function_insertion_hooks (void);
-
/* Likewise indicate that a node is needed, i.e. reachable via some
external means. */
inline void mark_force_output (void);
@@ -1044,7 +1058,8 @@ public:
static void dump_cgraph (FILE *f);
/* Dump the call graph to stderr. */
- static inline void debug_cgraph (void)
+ static inline
+ void debug_cgraph (void)
{
dump_cgraph (stderr);
}
@@ -1058,7 +1073,7 @@ public:
static void delete_function_version (tree decl);
/* Add the function FNDECL to the call graph.
- Unlike cgraph_finalize_function, this function is intended to be used
+ Unlike finalize_function, this function is intended to be used
by middle end and allows insertion of new function at arbitrary point
of compilation. The function can be either in high, low or SSA form
GIMPLE.
@@ -1077,16 +1092,28 @@ public:
return dyn_cast <cgraph_node *> (symtab_node::get (decl));
}
+ /* DECL has been parsed. Take it, queue it, compile it at the whim of the
+ logic in effect. If NO_COLLECT is true, then our caller cannot stand to
+ have the garbage collector run at the moment. We would need to either
+ create a new GC context, or just not compile right now. */
+ static void finalize_function (tree, bool);
+
/* Return cgraph node assigned to DECL. Create new one when needed. */
static cgraph_node * create (tree decl);
- /* Allocate new callgraph node and insert it into basic data structures. */
- static cgraph_node * create_empty (void);
-
/* Try to find a call graph node for declaration DECL and if it does not
exist or if it corresponds to an inline clone, create a new one. */
static cgraph_node * get_create (tree);
+ /* Return local info for the compiled function. */
+ static cgraph_local_info *local_info (tree decl);
+
+ /* Return global info for the compiled function. */
+ static cgraph_global_info *global_info (tree);
+
+ /* Return local info for the compiled function. */
+ static cgraph_rtl_info *rtl_info (tree);
+
/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
Return NULL if there's no such node. */
static cgraph_node *get_for_asmname (tree asmname);
@@ -1119,16 +1146,11 @@ public:
with (not necessarily cgraph_node (DECL). */
static cgraph_node *create_alias (tree alias, tree target);
- static cgraph_edge * create_edge (cgraph_node *caller, cgraph_node *callee,
- gimple call_stmt, gcov_type count,
- int freq,
- bool indir_unknown_callee);
-
- struct cgraph_edge *callees;
- struct cgraph_edge *callers;
+ cgraph_edge *callees;
+ cgraph_edge *callers;
/* List of edges representing indirect calls with a yet undetermined
callee. */
- struct cgraph_edge *indirect_calls;
+ cgraph_edge *indirect_calls;
/* For nested functions points to function the node is nested in. */
cgraph_node *origin;
/* Points to first nested function, if any. */
@@ -1142,13 +1164,13 @@ public:
cgraph_node *clone_of;
/* 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;
+ htab_t GTY((param_is (cgraph_edge))) call_site_hash;
/* Declaration node used to be clone of. */
tree former_clone_of;
/* If this is a SIMD clone, this points to the SIMD specific
information for it. */
- struct cgraph_simd_clone *simdclone;
+ cgraph_simd_clone *simdclone;
/* If this function has SIMD clones, this points to the first clone. */
cgraph_node *simd_clones;
@@ -1157,11 +1179,11 @@ public:
per-function in order to allow IPA passes to introduce new functions. */
vec<ipa_opt_pass> GTY((skip)) ipa_transforms_to_apply;
- struct cgraph_local_info local;
- struct cgraph_global_info global;
- struct cgraph_rtl_info rtl;
- struct cgraph_clone_info clone;
- struct cgraph_thunk_info thunk;
+ cgraph_local_info local;
+ cgraph_global_info global;
+ cgraph_rtl_info rtl;
+ cgraph_clone_info clone;
+ cgraph_thunk_info thunk;
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@@ -1276,18 +1298,81 @@ struct GTY(()) cgraph_indirect_call_info
};
struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
+ friend class cgraph_node;
+
+ /* Remove the edge in the cgraph. */
+ void remove (void);
+
+ /* Change field call_stmt of edge to NEW_STMT.
+ If UPDATE_SPECULATIVE and E is any component of speculative
+ edge, then update all components. */
+ void set_call_stmt (gimple new_stmt, bool update_speculative = true);
+
+ /* Redirect callee of the edge to N. The function does not update underlying
+ call expression. */
+ void redirect_callee (cgraph_node *n);
+
+ /* Make an indirect edge with an unknown callee an ordinary edge leading to
+ CALLEE. DELTA is an integer constant that is to be added to the this
+ pointer (first parameter) to compensate for skipping
+ a thunk adjustment. */
+ cgraph_edge *make_direct (cgraph_node *callee);
+
+ /* Turn edge into speculative call calling N2. Update
+ the profile so the direct call is taken COUNT times
+ with FREQUENCY. */
+ cgraph_edge *make_speculative (cgraph_node *n2, gcov_type direct_count,
+ int direct_frequency);
+
+ /* Given speculative call edge, return all three components. */
+ void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect,
+ ipa_ref *&reference);
+
+ /* Speculative call edge turned out to be direct call to CALLE_DECL.
+ Remove the speculative call sequence and return edge representing the call.
+ It is up to caller to redirect the call as appropriate. */
+ cgraph_edge *resolve_speculation (tree callee_decl = NULL);
+
+ /* If necessary, change the function declaration in the call statement
+ associated with the edge so that it corresponds to the edge callee. */
+ gimple redirect_call_stmt_to_callee (void);
+
+ /* Create clone of edge in the node N represented
+ by CALL_EXPR the callgraph. */
+ cgraph_edge * clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
+ gcov_type count_scale, int freq_scale, bool update_original);
+
+ /* Return true when call of edge can not lead to return from caller
+ and thus it is safe to ignore its side effects for IPA analysis
+ when computing side effects of the caller. */
+ bool cannot_lead_to_return_p (void);
+
+ /* Return true when the edge represents a direct recursion. */
+ bool recursive_p (void);
+
+ /* Return true if the call can be hot. */
+ bool maybe_hot_p (void);
+
+ /* Rebuild cgraph edges for current function node. This needs to be run after
+ passes that don't update the cgraph. */
+ static unsigned int rebuild_edges (void);
+
+ /* Rebuild cgraph references for current function node. This needs to be run
+ after passes that don't update the cgraph. */
+ static void rebuild_references (void);
+
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
cgraph_node *caller;
cgraph_node *callee;
- struct cgraph_edge *prev_caller;
- struct cgraph_edge *next_caller;
- struct cgraph_edge *prev_callee;
- struct cgraph_edge *next_callee;
+ cgraph_edge *prev_caller;
+ cgraph_edge *next_caller;
+ cgraph_edge *prev_callee;
+ cgraph_edge *next_callee;
gimple call_stmt;
/* Additional information about an indirect call. Not cleared when an edge
becomes direct. */
- struct cgraph_indirect_call_info *indirect_info;
+ cgraph_indirect_call_info *indirect_info;
PTR GTY ((skip (""))) aux;
/* When equal to CIF_OK, inline this call. Otherwise, points to the
explanation why function was not inlined. */
@@ -1329,6 +1414,13 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
Optimizers may later redirect direct call to clone, so 1) and 3)
do not need to necesarily agree with destination. */
unsigned int speculative : 1;
+
+private:
+ /* Remove the edge from the list of the callers of the callee. */
+ void remove_caller (void);
+
+ /* Remove the edge from the list of the callees of the caller. */
+ void remove_callee (void);
};
#define CGRAPH_FREQ_BASE 1000
@@ -1402,6 +1494,12 @@ public:
if all direct calls are eliminated. */
inline bool can_remove_if_no_refs_p (void);
+ /* Add the variable DECL to the varpool.
+ Unlike finalize_decl function is intended to be used
+ by middle end and allows insertion of new variable at arbitrary point
+ of compilation. */
+ static void add (tree decl);
+
/* Return varpool node for given symbol and check it is a function. */
static inline varpool_node *get (const_tree decl);
@@ -1410,9 +1508,6 @@ public:
visible. */
static void finalize_decl (tree decl);
- /* Output all variables enqueued to be assembled. */
- static bool output_variables (void);
-
/* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
Extra name aliases are output whenever DECL is output. */
static varpool_node * create_extra_name_alias (tree alias, tree decl);
@@ -1459,8 +1554,10 @@ private:
/* Every top level asm statement is put into a asm_node. */
struct GTY(()) asm_node {
+
+
/* Next asm node. */
- struct asm_node *next;
+ asm_node *next;
/* String for this asm node. */
tree asm_str;
/* Ordering of all cgraph nodes. */
@@ -1487,151 +1584,385 @@ is_a_helper <varpool_node *>::test (symtab_node *p)
return p && p->type == SYMTAB_VARIABLE;
}
-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;
-extern bool cgraph_global_info_ready;
-enum cgraph_state
+/* Macros to access the next item in the list of free cgraph nodes and
+ edges. */
+#define NEXT_FREE_NODE(NODE) dyn_cast<cgraph_node *> ((NODE)->next)
+#define SET_NEXT_FREE_NODE(NODE,NODE2) ((NODE))->next = NODE2
+#define NEXT_FREE_EDGE(EDGE) (EDGE)->prev_caller
+
+typedef void (*cgraph_edge_hook)(cgraph_edge *, void *);
+typedef void (*cgraph_node_hook)(cgraph_node *, void *);
+typedef void (*varpool_node_hook)(varpool_node *, void *);
+typedef void (*cgraph_2edge_hook)(cgraph_edge *, cgraph_edge *, void *);
+typedef void (*cgraph_2node_hook)(cgraph_node *, cgraph_node *, void *);
+
+struct cgraph_edge_hook_list;
+struct cgraph_node_hook_list;
+struct varpool_node_hook_list;
+struct cgraph_2edge_hook_list;
+struct cgraph_2node_hook_list;
+
+/* Map from a symbol to initialization/finalization priorities. */
+struct GTY(()) symbol_priority_map {
+ symtab_node *symbol;
+ priority_type init;
+ priority_type fini;
+};
+
+enum symtab_state
{
/* Frontend is parsing and finalizing functions. */
- CGRAPH_STATE_PARSING,
+ PARSING,
/* Callgraph is being constructed. It is safe to add new functions. */
- CGRAPH_STATE_CONSTRUCTION,
+ CONSTRUCTION,
/* Callgraph is being at LTO time. */
- CGRAPH_LTO_STREAMING,
+ LTO_STREAMING,
/* Callgraph is built and IPA passes are being run. */
- CGRAPH_STATE_IPA,
+ IPA,
/* Callgraph is built and all functions are transformed to SSA form. */
- CGRAPH_STATE_IPA_SSA,
+ IPA_SSA,
/* Functions are now ordered and being passed to RTL expanders. */
- CGRAPH_STATE_EXPANSION,
+ EXPANSION,
/* All cgraph expansion is done. */
- CGRAPH_STATE_FINISHED
+ FINISHED
};
-extern enum cgraph_state cgraph_state;
-extern bool cgraph_function_flags_ready;
-extern vec<cgraph_node *> cgraph_new_nodes;
-extern GTY(()) struct asm_node *asm_nodes;
-extern GTY(()) int symtab_order;
-extern bool cpp_implicit_aliases_done;
+class GTY((tag ("SYMTAB"))) symbol_table
+{
+public:
+ friend class symtab_node;
+ friend class cgraph_node;
+ friend class cgraph_edge;
+
+ /* Initialize callgraph dump file. */
+ inline void
+ initialize (void)
+ {
+ if (!dump_file)
+ dump_file = dump_begin (TDI_cgraph, NULL);
+ }
+
+ /* Register a top-level asm statement ASM_STR. */
+ inline asm_node *finalize_toplevel_asm (tree asm_str);
+
+ /* Analyze the whole compilation unit once it is parsed completely. */
+ void finalize_compilation_unit (void);
+
+ /* C++ frontend produce same body aliases all over the place, even before PCH
+ gets streamed out. It relies on us linking the aliases with their function
+ in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we
+ first produce aliases without links, but once C++ FE is sure he won't sream
+ PCH we build the links via this function. */
+ void process_same_body_aliases (void);
+
+ /* Perform simple optimizations based on callgraph. */
+ void compile (void);
+
+ /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
+ functions into callgraph in a way so they look like ordinary reachable
+ functions inserted into callgraph already at construction time. */
+ void process_new_functions (void);
+
+ /* Once all functions from compilation unit are in memory, produce all clones
+ and update all calls. We might also do this on demand if we don't want to
+ bring all functions to memory prior compilation, but current WHOPR
+ implementation does that and it is is bit easier to keep everything right
+ in this order. */
+ void materialize_all_clones (void);
+
+ /* Register a symbol NODE. */
+ inline void register_symbol (symtab_node *node);
+
+ inline void
+ clear_asm_symbols (void)
+ {
+ asmnodes = NULL;
+ asm_last_node = NULL;
+ }
+
+ /* Perform reachability analysis and reclaim all unreachable nodes. */
+ bool remove_unreachable_nodes (bool before_inlining_p, FILE *file);
+
+ /* Optimization of function bodies might've rendered some variables as
+ unnecessary so we want to avoid these from being compiled. Re-do
+ reachability starting from variables that are either externally visible
+ or was referred from the asm output routines. */
+ void remove_unreferenced_decls (void);
+
+ /* Unregister a symbol NODE. */
+ inline void unregister (symtab_node *node);
+
+ /* Allocate new callgraph node and insert it into basic data structures. */
+ cgraph_node *create_empty (void);
+
+ /* Release a callgraph NODE with UID and put in to the list
+ of free nodes. */
+ void release_symbol (cgraph_node *node, int uid);
+
+ /* Output all variables enqueued to be assembled. */
+ bool output_variables (void);
+
+ /* Output all asm statements we have stored up to be output. */
+ void output_asm_statements (void);
+
+ /* Weakrefs may be associated to external decls and thus not output
+ at expansion time. Emit all necessary aliases. */
+ void output_weakrefs (void);
+
+ /* Return first static symbol with definition. */
+ inline symtab_node *first_symbol (void);
+
+ /* Return first assembler symbol. */
+ inline asm_node *
+ first_asm_symbol (void)
+ {
+ return asmnodes;
+ }
+
+ /* Return first static symbol with definition. */
+ inline symtab_node *first_defined_symbol (void);
+
+ /* Return first variable. */
+ inline varpool_node *first_variable (void);
+
+ /* Return next variable after NODE. */
+ inline varpool_node *next_variable (varpool_node *node);
+
+ /* Return first static variable with initializer. */
+ inline varpool_node *first_static_initializer (void);
+
+ /* Return next static variable with initializer after NODE. */
+ inline varpool_node *next_static_initializer (varpool_node *node);
+
+ /* Return first static variable with definition. */
+ inline varpool_node *first_defined_variable (void);
+
+ /* Return next static variable with definition after NODE. */
+ inline varpool_node *next_defined_variable (varpool_node *node);
+
+ /* Return first function with body defined. */
+ inline cgraph_node *first_defined_function (void);
+
+ /* Return next function with body defined after NODE. */
+ inline cgraph_node *next_defined_function (cgraph_node *node);
+
+ /* Return first function. */
+ inline cgraph_node *first_function (void);
+
+ /* Return next function. */
+ inline cgraph_node *next_function (cgraph_node *node);
+
+ /* Return first function with body defined. */
+ cgraph_node *first_function_with_gimple_body (void);
+
+ /* Return next reachable static variable with initializer after NODE. */
+ inline cgraph_node *next_function_with_gimple_body (cgraph_node *node);
+
+ /* Register HOOK to be called with DATA on each removed edge. */
+ cgraph_edge_hook_list *add_edge_removal_hook (cgraph_edge_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on removing edges. */
+ void remove_edge_removal_hook (cgraph_edge_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each removed node. */
+ cgraph_node_hook_list *add_cgraph_removal_hook (cgraph_node_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on removing nodes. */
+ void remove_cgraph_removal_hook (cgraph_node_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each removed node. */
+ varpool_node_hook_list *add_varpool_removal_hook (varpool_node_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on removing nodes. */
+ void remove_varpool_removal_hook (varpool_node_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each inserted node. */
+ cgraph_node_hook_list *add_cgraph_insertion_hook (cgraph_node_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on inserted nodes. */
+ void remove_cgraph_insertion_hook (cgraph_node_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each inserted node. */
+ varpool_node_hook_list *add_varpool_insertion_hook (varpool_node_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on inserted nodes. */
+ void remove_varpool_insertion_hook (varpool_node_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each duplicated edge. */
+ cgraph_2edge_hook_list *add_edge_duplication_hook (cgraph_2edge_hook hook,
+ void *data);
+ /* Remove ENTRY from the list of hooks called on duplicating edges. */
+ void remove_edge_duplication_hook (cgraph_2edge_hook_list *entry);
+
+ /* Register HOOK to be called with DATA on each duplicated node. */
+ cgraph_2node_hook_list *add_cgraph_duplication_hook (cgraph_2node_hook hook,
+ void *data);
+
+ /* Remove ENTRY from the list of hooks called on duplicating nodes. */
+ void remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry);
+
+ /* Call all edge removal hooks. */
+ void call_edge_removal_hooks (cgraph_edge *e);
+
+ /* Call all node insertion hooks. */
+ void call_cgraph_insertion_hooks (cgraph_node *node);
+
+ /* Call all node removal hooks. */
+ void call_cgraph_removal_hooks (cgraph_node *node);
+
+ /* Call all node duplication hooks. */
+ void call_cgraph_duplication_hooks (cgraph_node *node, cgraph_node *node2);
+
+ /* Call all edge duplication hooks. */
+ void call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2);
+
+ /* Call all node removal hooks. */
+ void call_varpool_removal_hooks (varpool_node *node);
+
+ /* Call all node insertion hooks. */
+ void call_varpool_insertion_hooks (varpool_node *node);
+
+ /* Arrange node to be first in its entry of assembler_name_hash. */
+ void symtab_prevail_in_asm_name_hash (symtab_node *node);
+
+ /* Initalize asm name hash unless. */
+ void symtab_initialize_asm_name_hash (void);
+
+ /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables. */
+ void change_decl_assembler_name (tree decl, tree name);
-/* In symtab.c */
-symtab_node *symtab_node_for_asm (const_tree asmname);
+ int cgraph_count;
+ int cgraph_max_uid;
+
+ int edges_count;
+ int edges_max_uid;
+
+ symtab_node* GTY(()) nodes;
+ asm_node* GTY(()) asmnodes;
+ asm_node* GTY(()) asm_last_node;
+ cgraph_node* GTY(()) free_nodes;
+
+ /* Head of a linked list of unused (freed) call graph edges.
+ Do not GTY((delete)) this list so UIDs gets reliably recycled. */
+ cgraph_edge * GTY(()) free_edges;
+
+ /* 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 order;
+
+ /* Set when whole unit has been analyzed so we can access global info. */
+ bool global_info_ready;
+ /* What state callgraph is in right now. */
+ enum symtab_state state;
+ /* Set when the cgraph is fully build and the basic flags are computed. */
+ bool function_flags_ready;
+
+ bool cpp_implicit_aliases_done;
+
+ /* Hash table used to hold sectoons. */
+ htab_t GTY((param_is (section_hash_entry))) section_hash;
+
+ /* Hash table used to convert assembler names into nodes. */
+ htab_t GTY((param_is (symtab_node))) assembler_name_hash;
+
+ /* Hash table used to hold init priorities. */
+ htab_t GTY ((param_is (symbol_priority_map))) init_priority_hash;
+
+ FILE* GTY ((skip)) dump_file;
+
+private:
+ /* Allocate new callgraph node. */
+ inline cgraph_node * allocate_cgraph_symbol (void);
+
+ /* Allocate a cgraph_edge structure and fill it with data according to the
+ parameters of which only CALLEE can be NULL (when creating an indirect call
+ edge). */
+ cgraph_edge *create_edge (cgraph_node *caller, cgraph_node *callee,
+ gimple call_stmt, gcov_type count, int freq,
+ bool indir_unknown_callee);
+
+ /* Put the edge onto the free list. */
+ void free_edge (cgraph_edge *e);
+
+ /* Insert NODE to assembler name hash. */
+ void insert_to_assembler_name_hash (symtab_node *node, bool with_clones);
+
+ /* Remove NODE from assembler name hash. */
+ void unlink_from_assembler_name_hash (symtab_node *node, bool with_clones);
+
+ /* Hash asmnames ignoring the user specified marks. */
+ static hashval_t decl_assembler_name_hash (const_tree asmname);
+
+ /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
+ static bool decl_assembler_name_equal (tree decl, const_tree asmname);
+
+ /* Returns a hash code for P. */
+ static hashval_t hash_node_by_assembler_name (const void *p);
+
+ /* Returns nonzero if P1 and P2 are equal. */
+ static int eq_assembler_name (const void *p1, const void *p2);
+
+ /* List of hooks triggered when an edge is removed. */
+ cgraph_edge_hook_list * GTY((skip)) m_first_edge_removal_hook;
+ /* List of hooks triggem_red when a cgraph node is removed. */
+ cgraph_node_hook_list * GTY((skip)) m_first_cgraph_removal_hook;
+ /* List of hooks triggered when an edge is duplicated. */
+ cgraph_2edge_hook_list * GTY((skip)) m_first_edge_duplicated_hook;
+ /* List of hooks triggered when a node is duplicated. */
+ cgraph_2node_hook_list * GTY((skip)) m_first_cgraph_duplicated_hook;
+ /* List of hooks triggered when an function is inserted. */
+ cgraph_node_hook_list * GTY((skip)) m_first_cgraph_insertion_hook;
+ /* List of hooks triggered when an variable is inserted. */
+ varpool_node_hook_list * GTY((skip)) m_first_varpool_insertion_hook;
+ /* List of hooks triggered when a node is removed. */
+ varpool_node_hook_list * GTY((skip)) m_first_varpool_removal_hook;
+};
+
+extern GTY(()) symbol_table *symtab;
+
+extern vec<cgraph_node *> cgraph_new_nodes;
/* In cgraph.c */
void release_function_body (tree);
-struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
-void cgraph_remove_edge (struct cgraph_edge *);
+cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
-void cgraph_set_call_stmt (struct cgraph_edge *, gimple, bool update_speculative = true);
void cgraph_update_edges_for_call_stmt (gimple, tree, gimple);
-struct cgraph_local_info *cgraph_local_info (tree);
-struct cgraph_global_info *cgraph_global_info (tree);
-struct cgraph_rtl_info *cgraph_rtl_info (tree);
-void cgraph_call_edge_duplication_hooks (struct cgraph_edge *,
- struct cgraph_edge *);
-
bool cgraph_function_possibly_inlined_p (tree);
-bool cgraph_edge_cannot_lead_to_return (struct cgraph_edge *);
-void cgraph_redirect_edge_callee (struct cgraph_edge *, cgraph_node *);
-struct cgraph_edge *cgraph_make_edge_direct (struct cgraph_edge *,
- cgraph_node *);
const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
-typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
-typedef void (*cgraph_node_hook)(cgraph_node *, void *);
-typedef void (*varpool_node_hook)(varpool_node *, void *);
-typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
- void *);
-typedef void (*cgraph_2node_hook)(cgraph_node *, cgraph_node *,
- void *);
-struct cgraph_edge_hook_list;
-struct cgraph_node_hook_list;
-struct varpool_node_hook_list;
-struct cgraph_2edge_hook_list;
-struct cgraph_2node_hook_list;
-struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
-void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
-cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
- void *);
-void cgraph_remove_node_removal_hook (cgraph_node_hook_list *);
-struct varpool_node_hook_list *varpool_add_node_removal_hook (varpool_node_hook,
- void *);
-void varpool_remove_node_removal_hook (struct varpool_node_hook_list *);
-cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook,
- void *);
-void cgraph_remove_function_insertion_hook (cgraph_node_hook_list *);
-struct varpool_node_hook_list *varpool_add_variable_insertion_hook (varpool_node_hook,
- void *);
-void varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *);
-struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
-void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
-struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
-void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
-gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
-struct cgraph_edge *
-cgraph_turn_edge_to_speculative (struct cgraph_edge *,
- cgraph_node *,
- gcov_type, int);
-void cgraph_speculative_call_info (struct cgraph_edge *,
- struct cgraph_edge *&,
- struct cgraph_edge *&,
- struct ipa_ref *&);
extern bool gimple_check_call_matching_types (gimple, tree, bool);
/* In cgraphunit.c */
-struct asm_node *add_asm_node (tree);
-extern FILE *cgraph_dump_file;
-void cgraph_finalize_function (tree, bool);
-void finalize_compilation_unit (void);
-void compile (void);
-void init_cgraph (void);
-void cgraph_process_new_functions (void);
-void cgraph_process_same_body_aliases (void);
/* Initialize datastructures so DECL is a function in lowered gimple form.
IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool);
/* In cgraphclones.c */
-struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
- cgraph_node *, gimple,
- unsigned, gcov_type, int, bool);
tree clone_function_name (tree decl, const char *);
-void cgraph_materialize_all_clones (void);
void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
bool, bitmap, bool, bitmap, basic_block);
-struct cgraph_edge *cgraph_resolve_speculation (struct cgraph_edge *, tree);
/* In cgraphbuild.c */
-unsigned int rebuild_cgraph_edges (void);
-void cgraph_rebuild_references (void);
int compute_call_stmt_bb_frequency (tree, basic_block bb);
void record_references_in_initializer (tree, bool);
/* In ipa.c */
-bool symtab_remove_unreachable_nodes (bool, FILE *);
void cgraph_build_static_cdtor (char which, tree body, int priority);
void ipa_discover_readonly_nonaddressable_vars (void);
-/* In predict.c */
-bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
-
/* In varpool.c */
-void varpool_reset_queue (void);
tree ctor_for_folding (tree);
-void varpool_add_new_variable (tree);
-void symtab_initialize_asm_name_hash (void);
-void symtab_prevail_in_asm_name_hash (symtab_node *node);
-
-/* In cgraph.c */
-extern void change_decl_assembler_name (tree, tree);
/* Return true when the symbol is real symbol, i.e. it is not inline clone
or abstract function kept for debug info purposes only. */
@@ -1685,7 +2016,7 @@ symtab_node::in_same_comdat_group_p (symtab_node *target)
inline symtab_node *
symtab_node::get_alias_target (void)
{
- struct ipa_ref *ref = NULL;
+ ipa_ref *ref = NULL;
iterate_reference (0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
return ref->referred;
@@ -1705,6 +2036,7 @@ symtab_node::next_defined_symbol (void)
}
/* Return varpool node for given symbol and check it is a function. */
+
inline varpool_node *
varpool_node::get (const_tree decl)
{
@@ -1712,17 +2044,129 @@ varpool_node::get (const_tree decl)
return dyn_cast<varpool_node *> (symtab_node::get (decl));
}
+/* Register a symbol NODE. */
+
+inline void
+symbol_table::register_symbol (symtab_node *node)
+{
+ node->next = nodes;
+ node->previous = NULL;
+
+ if (nodes)
+ nodes->previous = node;
+ nodes = node;
+
+ node->order = order++;
+}
+
+/* Register a top-level asm statement ASM_STR. */
+
+asm_node *
+symbol_table::finalize_toplevel_asm (tree asm_str)
+{
+ asm_node *node;
+
+ node = ggc_cleared_alloc<asm_node> ();
+ node->asm_str = asm_str;
+ node->order = order++;
+ node->next = NULL;
+
+ if (asmnodes == NULL)
+ asmnodes = node;
+ else
+ asm_last_node->next = node;
+
+ asm_last_node = node;
+ return node;
+}
+
+/* Unregister a symbol NODE. */
+inline void
+symbol_table::unregister (symtab_node *node)
+{
+ if (node->previous)
+ node->previous->next = node->next;
+ else
+ nodes = node->next;
+
+ if (node->next)
+ node->next->previous = node->previous;
+
+ node->next = NULL;
+ node->previous = NULL;
+}
+
+/* Allocate new callgraph node and insert it into basic data structures. */
+
+inline cgraph_node *
+symbol_table::create_empty (void)
+{
+ cgraph_node *node = allocate_cgraph_symbol ();
+
+ node->type = SYMTAB_FUNCTION;
+ node->frequency = NODE_FREQUENCY_NORMAL;
+ node->count_materialization_scale = REG_BR_PROB_BASE;
+ cgraph_count++;
+
+ return node;
+}
+
+/* Release a callgraph NODE with UID and put in to the list of free nodes. */
+
+inline void
+symbol_table::release_symbol (cgraph_node *node, int uid)
+{
+ cgraph_count--;
+
+ /* Clear out the node to NULL all pointers and add the node to the free
+ list. */
+ memset (node, 0, sizeof (*node));
+ node->type = SYMTAB_FUNCTION;
+ node->uid = uid;
+ SET_NEXT_FREE_NODE (node, free_nodes);
+ free_nodes = node;
+}
+
+/* Allocate new callgraph node. */
+
+inline cgraph_node *
+symbol_table::allocate_cgraph_symbol (void)
+{
+ cgraph_node *node;
+
+ if (free_nodes)
+ {
+ node = free_nodes;
+ free_nodes = NEXT_FREE_NODE (node);
+ }
+ else
+ {
+ node = ggc_cleared_alloc<cgraph_node> ();
+ node->uid = cgraph_max_uid++;
+ }
+
+ return node;
+}
+
+
+/* Return first static symbol with definition. */
+inline symtab_node *
+symbol_table::first_symbol (void)
+{
+ return nodes;
+}
+
/* Walk all symbols. */
#define FOR_EACH_SYMBOL(node) \
- for ((node) = symtab_nodes; (node); (node) = (node)->next)
+ for ((node) = symtab->first_symbol (); (node); (node) = (node)->next)
/* Return first static symbol with definition. */
-static inline symtab_node *
-symtab_first_defined_symbol (void)
+inline symtab_node *
+symbol_table::first_defined_symbol (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
if (node->definition)
return node;
@@ -1731,23 +2175,23 @@ symtab_first_defined_symbol (void)
/* Walk all symbols with definitions in current unit. */
#define FOR_EACH_DEFINED_SYMBOL(node) \
- for ((node) = symtab_first_defined_symbol (); (node); \
+ for ((node) = symtab->first_defined_symbol (); (node); \
(node) = node->next_defined_symbol ())
/* Return first variable. */
-static inline varpool_node *
-varpool_first_variable (void)
+inline varpool_node *
+symbol_table::first_variable (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
return vnode;
return NULL;
}
/* Return next variable after NODE. */
-static inline varpool_node *
-varpool_next_variable (varpool_node *node)
+inline varpool_node *
+symbol_table::next_variable (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1757,16 +2201,16 @@ varpool_next_variable (varpool_node *node)
}
/* Walk all variables. */
#define FOR_EACH_VARIABLE(node) \
- for ((node) = varpool_first_variable (); \
+ for ((node) = symtab->first_variable (); \
(node); \
- (node) = varpool_next_variable ((node)))
+ (node) = symtab->next_variable ((node)))
/* Return first static variable with initializer. */
-static inline varpool_node *
-varpool_first_static_initializer (void)
+inline varpool_node *
+symbol_table::first_static_initializer (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
{
varpool_node *vnode = dyn_cast <varpool_node *> (node);
if (vnode && DECL_INITIAL (node->decl))
@@ -1776,8 +2220,8 @@ varpool_first_static_initializer (void)
}
/* Return next static variable with initializer after NODE. */
-static inline varpool_node *
-varpool_next_static_initializer (varpool_node *node)
+inline varpool_node *
+symbol_table::next_static_initializer (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1791,15 +2235,15 @@ varpool_next_static_initializer (varpool_node *node)
/* 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))
+ for ((node) = symtab->first_static_initializer (); (node); \
+ (node) = symtab->next_static_initializer (node))
/* Return first static variable with definition. */
-static inline varpool_node *
-varpool_first_defined_variable (void)
+inline varpool_node *
+symbol_table::first_defined_variable (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
{
varpool_node *vnode = dyn_cast <varpool_node *> (node);
if (vnode && vnode->definition)
@@ -1809,8 +2253,8 @@ varpool_first_defined_variable (void)
}
/* Return next static variable with definition after NODE. */
-static inline varpool_node *
-varpool_next_defined_variable (varpool_node *node)
+inline varpool_node *
+symbol_table::next_defined_variable (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1823,15 +2267,15 @@ varpool_next_defined_variable (varpool_node *node)
}
/* Walk all variables with definitions in current unit. */
#define FOR_EACH_DEFINED_VARIABLE(node) \
- for ((node) = varpool_first_defined_variable (); (node); \
- (node) = varpool_next_defined_variable (node))
+ for ((node) = symtab->first_defined_variable (); (node); \
+ (node) = symtab->next_defined_variable (node))
/* Return first function with body defined. */
-static inline cgraph_node *
-cgraph_first_defined_function (void)
+inline cgraph_node *
+symbol_table::first_defined_function (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
{
cgraph_node *cn = dyn_cast <cgraph_node *> (node);
if (cn && cn->definition)
@@ -1841,8 +2285,8 @@ cgraph_first_defined_function (void)
}
/* Return next function with body defined after NODE. */
-static inline cgraph_node *
-cgraph_next_defined_function (cgraph_node *node)
+inline cgraph_node *
+symbol_table::next_defined_function (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1856,23 +2300,23 @@ cgraph_next_defined_function (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)))
+ for ((node) = symtab->first_defined_function (); (node); \
+ (node) = symtab->next_defined_function ((node)))
/* Return first function. */
-static inline cgraph_node *
-cgraph_first_function (void)
+inline cgraph_node *
+symbol_table::first_function (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
if (cgraph_node *cn = dyn_cast <cgraph_node *> (node))
return cn;
return NULL;
}
/* Return next function. */
-static inline cgraph_node *
-cgraph_next_function (cgraph_node *node)
+inline cgraph_node *
+symbol_table::next_function (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1880,29 +2324,13 @@ cgraph_next_function (cgraph_node *node)
return cn1;
return NULL;
}
-/* Walk all functions. */
-#define FOR_EACH_FUNCTION(node) \
- for ((node) = cgraph_first_function (); (node); \
- (node) = cgraph_next_function ((node)))
-
-/* Return true when callgraph node is a function with Gimple body defined
- in current unit. Functions can also be define externally or they
- can be thunks with no Gimple representation.
-
- Note that at WPA stage, the function body may not be present in memory. */
-
-inline bool
-cgraph_node::has_gimple_body_p (void)
-{
- return definition && !thunk.thunk_p && !alias;
-}
/* Return first function with body defined. */
-static inline cgraph_node *
-cgraph_first_function_with_gimple_body (void)
+inline cgraph_node *
+symbol_table::first_function_with_gimple_body (void)
{
symtab_node *node;
- for (node = symtab_nodes; node; node = node->next)
+ for (node = nodes; node; node = node->next)
{
cgraph_node *cn = dyn_cast <cgraph_node *> (node);
if (cn && cn->has_gimple_body_p ())
@@ -1912,8 +2340,8 @@ cgraph_first_function_with_gimple_body (void)
}
/* Return next reachable static variable with initializer after NODE. */
-static inline cgraph_node *
-cgraph_next_function_with_gimple_body (cgraph_node *node)
+inline cgraph_node *
+symbol_table::next_function_with_gimple_body (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
@@ -1925,10 +2353,27 @@ cgraph_next_function_with_gimple_body (cgraph_node *node)
return NULL;
}
+/* Walk all functions. */
+#define FOR_EACH_FUNCTION(node) \
+ for ((node) = symtab->first_function (); (node); \
+ (node) = symtab->next_function ((node)))
+
+/* Return true when callgraph node is a function with Gimple body defined
+ in current unit. Functions can also be define externally or they
+ can be thunks with no Gimple representation.
+
+ Note that at WPA stage, the function body may not be present in memory. */
+
+inline bool
+cgraph_node::has_gimple_body_p (void)
+{
+ return definition && !thunk.thunk_p && !alias;
+}
+
/* Walk all functions with body defined. */
#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
- for ((node) = cgraph_first_function_with_gimple_body (); (node); \
- (node) = cgraph_next_function_with_gimple_body (node))
+ for ((node) = symtab->first_function_with_gimple_body (); (node); \
+ (node) = symtab->next_function_with_gimple_body (node))
/* Create a new static variable of type TYPE. */
tree add_new_static_var (tree type);
@@ -2044,15 +2489,15 @@ varpool_node::ultimate_alias_target (availability *availability)
return n;
}
-/* Return true when the edge E represents a direct recursion. */
-static inline bool
-cgraph_edge_recursive_p (struct cgraph_edge *e)
+/* Return true when the edge represents a direct recursion. */
+inline bool
+cgraph_edge::recursive_p (void)
{
- cgraph_node *callee = e->callee->ultimate_alias_target ();
- if (e->caller->global.inlined_to)
- return e->caller->global.inlined_to->decl == callee->decl;
+ cgraph_node *c = callee->ultimate_alias_target ();
+ if (caller->global.inlined_to)
+ return caller->global.inlined_to->decl == c->decl;
else
- return e->caller->decl == callee->decl;
+ return caller->decl == c->decl;
}
/* Return true if the TM_CLONE bit is set for a given FNDECL. */