diff mbox

[RFC,4/n] IPA C++ refactoring

Message ID 53FAF9FD.5050507@suse.cz
State New
Headers show

Commit Message

Martin Liška Aug. 25, 2014, 8:55 a.m. UTC
On 08/22/2014 04:45 PM, Jan Hubicka wrote:
>> On 08/21/2014 04:31 PM, Jan Hubicka wrote:
>>>> Hello,
>>>>     following patch introduces a new symbol_table class, encapsulating functions related to symbol table management. Apart from that, cgraph_edge related functions become members of the class. Finally, a portion of clean-up has been applied to cgraph.h.
>>>>
>>>> Bootstrapped on x86_64-pc-linux-gnu and majority of BEs have been tested for C and C++, no regression observed.
>>>>
>>>> Thank you,
>>>> Martin
>>>>
>>>> -  if (!used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
>>>> +  if (!used_as_abstract_origin && symtab->state != CGRAPH_STATE_PARSING)
>>> I would probably rename this CGRAPH_ enum into SYMTAB.  Given it is a symtab state now ;)
>> Good observation, what about renaming enum values to: PARSING, CONSTRUCTION,...
>> I think CGRAPH_ prefix is superfluous.
> Yep, I just wanted to use cgraph_ consistently for callgarph to avoid namespace polution back in 2002 ;)
> I suppose we can make it symtab::PARSING....
I would really like to put the enum within the class, but:
../../gcc/cgraph.h:1631: parse error: enum definitions not supported in structures marked with automatic GTY markers.  Use GTY((user)) to mark this structure.

Thus, I will let the enum outside the symbol_table class.
>> +  /* Determine if symbol declaration is needed.  That is, visible to something
>> +     either outside this translation unit, something magic in the system
>> +     configury */
>> +  bool needed_p (void);
> Add comment that this is used only during symtab construction.
Done.
>>   
>>     /* 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);
> We have add_reference and others are create_*.  I guess we ought rename add_reference
> to create_reference by followup patch?
create_ prefix would be better.
>
> An alternative would be to consistently use constructors here...
>> +
>> +  /* 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);
> process_same_body_aliases followed by compile should be here.
>> +
>> +  /* 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);
>> +
>> +  /* 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);
>> +
>> +  /* 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);
>> +
>> +  /* Perform simple optimizations based on callgraph.  */
>> +  void compile (void);
>> +
>> +  /* Register a symbol NODE.  */
>> +  inline void register_symbol (symtab_node *node);
>> +
>> +  inline void
>> +  clear_asm_symbols (void)
> OK with these changes.
>
> Honza
Latest version of the patch attached, will be committed today.

Thank you,
Martin
2014-08-25  Martin Liska  <mliska@suse.cz>

	* 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
diff mbox

Patch

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 9f81eae..266a942 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3156,7 +3156,7 @@  rest_of_subprog_body_compilation (tree subprog_decl)
   dump_function (TDI_original, subprog_decl);
 
   if (!decl_function_context (subprog_decl))
-    cgraph_finalize_function (subprog_decl, false);
+    cgraph_node::finalize_function (subprog_decl, false);
   else
     /* Register this function with cgraph just far enough to get it
        added to our parent's nested function list.  */
@@ -5187,7 +5187,7 @@  gnat_write_global_declarations (void)
       debug_hooks->global_decl (iter);
 
   /* Proceed to optimize and emit assembly. */
-  finalize_compilation_unit ();
+  symtab->finalize_compilation_unit ();
 
   /* After cgraph has had a chance to emit everything that's going to
      be emitted, output debug information for the rest of globals.  */
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index 5e57de3..804f37c 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -25,7 +25,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "varasm.h"
-#include "gcc-symtab.h"
 #include "function.h"		/* For cfun.  FIXME: Does the parser know
 				   when it is inside a function, so that
 				   we don't have to look at cfun?  */
@@ -329,7 +328,7 @@  maybe_apply_pending_pragma_weaks (void)
       if (id == NULL)
 	continue;
 
-      target = symtab_node_for_asm (id);
+      target = symtab_node::get_for_asmname (id);
       decl = build_decl (UNKNOWN_LOCATION,
 			 target ? TREE_CODE (target->decl) : FUNCTION_DECL,
 			 alias_id, default_function_type);
@@ -479,7 +478,7 @@  handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
 			 "conflict with previous rename");
 	    }
 	  else
-	    change_decl_assembler_name (decl, newname);
+	    symtab->change_decl_assembler_name (decl, newname);
 	}
     }
 
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index ec0d0ef..b4995a6 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -8665,12 +8665,12 @@  finish_function (void)
 
 	  /* ??? Objc emits functions after finalizing the compilation unit.
 	     This should be cleaned up later and this conditional removed.  */
-	  if (cgraph_global_info_ready)
+	  if (symtab->global_info_ready)
 	    {
 	      cgraph_node::add_new_function (fndecl, false);
 	      return;
 	    }
-	  cgraph_finalize_function (fndecl, false);
+	  cgraph_node::finalize_function (fndecl, false);
 	}
       else
 	{
@@ -10428,7 +10428,7 @@  c_write_global_declarations (void)
 
   /* We're done parsing; proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
-  finalize_compilation_unit ();
+  symtab->finalize_compilation_unit ();
 
   timevar_stop (TV_PHASE_OPT_GEN);
   timevar_start (TV_PHASE_DBGINFO);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index d634bb1..34f1e47 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1980,7 +1980,7 @@  c_parser_asm_definition (c_parser *parser)
 {
   tree asm_str = c_parser_simple_asm_expr (parser);
   if (asm_str)
-    add_asm_node (asm_str);
+    symtab->finalize_toplevel_asm (asm_str);
   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 }
 
diff --git a/gcc/calls.c b/gcc/calls.c
index 9144653..10f52bb 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2406,7 +2406,7 @@  expand_call (tree exp, rtx target, int ignore)
   preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
   if (fndecl)
     {
-      struct cgraph_rtl_info *i = cgraph_rtl_info (fndecl);
+      struct cgraph_rtl_info *i = cgraph_node::rtl_info (fndecl);
       /* Without automatic stack alignment, we can't increase preferred
 	 stack boundary.  With automatic stack alignment, it is
 	 unnecessary since unless we can guarantee that all callers will
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index cb49cdc..99e0076 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -68,30 +68,12 @@  along with GCC; see the file COPYING3.  If not see
 /* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this.  */
 #include "tree-pass.h"
 
-static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
-static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
-
 /* 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)
-
-/* Number of nodes in existence.  */
-int cgraph_n_nodes;
-
-/* Maximal uid used in cgraph nodes.  */
-int cgraph_max_uid;
-
-/* Maximal uid used in cgraph edges.  */
-int cgraph_edge_max_uid;
-
-/* Set when whole unit has been analyzed so we can access global info.  */
-bool cgraph_global_info_ready = false;
-
-/* What state callgraph is in right now.  */
-enum cgraph_state cgraph_state = CGRAPH_STATE_PARSING;
+#define cgraph_nodes_queue ((cgraph_node *)x_cgraph_nodes_queue)
 
-/* Set when the cgraph is fully build and the basic flags are computed.  */
-bool cgraph_function_flags_ready = false;
+/* Symbol table global context.  */
+symbol_table *symtab;
 
 /* List of hooks triggered on cgraph_edge events.  */
 struct cgraph_edge_hook_list {
@@ -121,39 +103,18 @@  struct cgraph_2node_hook_list {
   struct cgraph_2node_hook_list *next;
 };
 
-/* List of hooks triggered when an edge is removed.  */
-struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook;
-/* List of hooks triggered when a node is removed.  */
-struct cgraph_node_hook_list *first_cgraph_node_removal_hook;
-/* List of hooks triggered when an edge is duplicated.  */
-struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook;
-/* List of hooks triggered when a node is duplicated.  */
-struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook;
-/* List of hooks triggered when an function is inserted.  */
-struct cgraph_node_hook_list *first_cgraph_function_insertion_hook;
-
-/* Head of a linked list of unused (freed) call graph nodes.
-   Do not GTY((delete)) this list so UIDs gets reliably recycled.  */
-static GTY(()) struct cgraph_node *free_nodes;
-/* Head of a linked list of unused (freed) call graph edges.
-   Do not GTY((delete)) this list so UIDs gets reliably recycled.  */
-static GTY(()) struct cgraph_edge *free_edges;
-
-/* Did procss_same_body_aliases run?  */
-bool cpp_implicit_aliases_done;
-
 /* Map a cgraph_node to cgraph_function_version_info using this htab.
    The cgraph_function_version_info has a THIS_NODE field that is the
    corresponding cgraph_node..  */
 
-static GTY((param_is (struct cgraph_function_version_info))) htab_t
+static GTY((param_is (cgraph_function_version_info))) htab_t
   cgraph_fnver_htab = NULL;
 
 /* Hash function for cgraph_fnver_htab.  */
 static hashval_t
 cgraph_fnver_htab_hash (const void *ptr)
 {
-  int uid = ((const struct cgraph_function_version_info *)ptr)->this_node->uid;
+  int uid = ((const cgraph_function_version_info *)ptr)->this_node->uid;
   return (hashval_t)(uid);
 }
 
@@ -161,10 +122,10 @@  cgraph_fnver_htab_hash (const void *ptr)
 static int
 cgraph_fnver_htab_eq (const void *p1, const void *p2)
 {
-  const struct cgraph_function_version_info *n1
-    = (const struct cgraph_function_version_info *)p1;
-  const struct cgraph_function_version_info *n2
-    = (const struct cgraph_function_version_info *)p2;
+  const cgraph_function_version_info *n1
+    = (const cgraph_function_version_info *)p1;
+  const cgraph_function_version_info *n2
+    = (const cgraph_function_version_info *)p2;
 
   return n1->this_node->uid == n2->this_node->uid;
 }
@@ -174,17 +135,17 @@  static GTY(()) struct cgraph_function_version_info *
   version_info_node = NULL;
 
 /* Get the cgraph_function_version_info node corresponding to node.  */
-struct cgraph_function_version_info *
+cgraph_function_version_info *
 cgraph_node::function_version (void)
 {
-  struct cgraph_function_version_info *ret;
-  struct cgraph_function_version_info key;
+  cgraph_function_version_info *ret;
+  cgraph_function_version_info key;
   key.this_node = this;
 
   if (cgraph_fnver_htab == NULL)
     return NULL;
 
-  ret = (struct cgraph_function_version_info *)
+  ret = (cgraph_function_version_info *)
     htab_find (cgraph_fnver_htab, &key);
 
   return ret;
@@ -192,7 +153,7 @@  cgraph_node::function_version (void)
 
 /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
    corresponding to cgraph_node NODE.  */
-struct cgraph_function_version_info *
+cgraph_function_version_info *
 cgraph_node::insert_new_function_version (void)
 {
   void **slot;
@@ -216,8 +177,8 @@  cgraph_node::insert_new_function_version (void)
 void
 cgraph_node::delete_function_version (tree decl)
 {
-  struct cgraph_node *decl_node = cgraph_node::get (decl);
-  struct cgraph_function_version_info *decl_v = NULL;
+  cgraph_node *decl_node = cgraph_node::get (decl);
+  cgraph_function_version_info *decl_v = NULL;
 
   if (decl_node == NULL)
     return;
@@ -244,12 +205,12 @@  cgraph_node::delete_function_version (tree decl)
 void
 cgraph_node::record_function_versions (tree decl1, tree decl2)
 {
-  struct cgraph_node *decl1_node = cgraph_node::get_create (decl1);
-  struct cgraph_node *decl2_node = cgraph_node::get_create (decl2);
-  struct cgraph_function_version_info *decl1_v = NULL;
-  struct cgraph_function_version_info *decl2_v = NULL;
-  struct cgraph_function_version_info *before;
-  struct cgraph_function_version_info *after;
+  cgraph_node *decl1_node = cgraph_node::get_create (decl1);
+  cgraph_node *decl2_node = cgraph_node::get_create (decl2);
+  cgraph_function_version_info *decl1_v = NULL;
+  cgraph_function_version_info *decl2_v = NULL;
+  cgraph_function_version_info *before;
+  cgraph_function_version_info *after;
 
   gcc_assert (decl1_node != NULL && decl2_node != NULL);
   decl1_v = decl1_node->function_version ();
@@ -280,20 +241,14 @@  cgraph_node::record_function_versions (tree decl1, tree decl2)
   after->prev = before;
 }
 
-/* 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
-
 /* Register HOOK to be called with DATA on each removed edge.  */
-struct cgraph_edge_hook_list *
-cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
+cgraph_edge_hook_list *
+symbol_table::add_edge_removal_hook (cgraph_edge_hook hook, void *data)
 {
-  struct cgraph_edge_hook_list *entry;
-  struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+  cgraph_edge_hook_list *entry;
+  cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
 
-  entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
+  entry = (cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -305,9 +260,9 @@  cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on removing edges.  */
 void
-cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
+symbol_table::remove_edge_removal_hook (cgraph_edge_hook_list *entry)
 {
-  struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+  cgraph_edge_hook_list **ptr = &m_first_edge_removal_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -316,10 +271,10 @@  cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
 }
 
 /* Call all edge removal hooks.  */
-static void
-cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
+void
+symbol_table::call_edge_removal_hooks (cgraph_edge *e)
 {
-  struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook;
+  cgraph_edge_hook_list *entry = m_first_edge_removal_hook;
   while (entry)
   {
     entry->hook (e, entry->data);
@@ -328,13 +283,13 @@  cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
 }
 
 /* Register HOOK to be called with DATA on each removed node.  */
-struct cgraph_node_hook_list *
-cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
+cgraph_node_hook_list *
+symbol_table::add_cgraph_removal_hook (cgraph_node_hook hook, void *data)
 {
-  struct cgraph_node_hook_list *entry;
-  struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+  cgraph_node_hook_list *entry;
+  cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
 
-  entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
+  entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -346,9 +301,9 @@  cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on removing nodes.  */
 void
-cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
+symbol_table::remove_cgraph_removal_hook (cgraph_node_hook_list *entry)
 {
-  struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+  cgraph_node_hook_list **ptr = &m_first_cgraph_removal_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -357,10 +312,10 @@  cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
 }
 
 /* Call all node removal hooks.  */
-static void
-cgraph_call_node_removal_hooks (struct cgraph_node *node)
+void
+symbol_table::call_cgraph_removal_hooks (cgraph_node *node)
 {
-  struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook;
+  cgraph_node_hook_list *entry = m_first_cgraph_removal_hook;
   while (entry)
   {
     entry->hook (node, entry->data);
@@ -368,14 +323,27 @@  cgraph_call_node_removal_hooks (struct cgraph_node *node)
   }
 }
 
+/* Call all node removal hooks.  */
+void
+symbol_table::call_cgraph_insertion_hooks (cgraph_node *node)
+{
+  cgraph_node_hook_list *entry = m_first_cgraph_insertion_hook;
+  while (entry)
+  {
+    entry->hook (node, entry->data);
+    entry = entry->next;
+  }
+}
+
+
 /* Register HOOK to be called with DATA on each inserted node.  */
-struct cgraph_node_hook_list *
-cgraph_add_function_insertion_hook (cgraph_node_hook hook, void *data)
+cgraph_node_hook_list *
+symbol_table::add_cgraph_insertion_hook (cgraph_node_hook hook, void *data)
 {
-  struct cgraph_node_hook_list *entry;
-  struct cgraph_node_hook_list **ptr = &first_cgraph_function_insertion_hook;
+  cgraph_node_hook_list *entry;
+  cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
 
-  entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
+  entry = (cgraph_node_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -387,9 +355,9 @@  cgraph_add_function_insertion_hook (cgraph_node_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on inserted nodes.  */
 void
-cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *entry)
+symbol_table::remove_cgraph_insertion_hook (cgraph_node_hook_list *entry)
 {
-  struct cgraph_node_hook_list **ptr = &first_cgraph_function_insertion_hook;
+  cgraph_node_hook_list **ptr = &m_first_cgraph_insertion_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -397,26 +365,14 @@  cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *entry)
   free (entry);
 }
 
-/* Call all node insertion hooks.  */
-void
-cgraph_node::call_function_insertion_hooks (void)
-{
-  struct cgraph_node_hook_list *entry = first_cgraph_function_insertion_hook;
-  while (entry)
-  {
-    entry->hook (this, entry->data);
-    entry = entry->next;
-  }
-}
-
 /* Register HOOK to be called with DATA on each duplicated edge.  */
-struct cgraph_2edge_hook_list *
-cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
+cgraph_2edge_hook_list *
+symbol_table::add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
 {
-  struct cgraph_2edge_hook_list *entry;
-  struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+  cgraph_2edge_hook_list *entry;
+  cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
 
-  entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
+  entry = (cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -428,9 +384,9 @@  cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on duplicating edges.  */
 void
-cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
+symbol_table::remove_edge_duplication_hook (cgraph_2edge_hook_list *entry)
 {
-  struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+  cgraph_2edge_hook_list **ptr = &m_first_edge_duplicated_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -440,10 +396,9 @@  cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
 
 /* Call all edge duplication hooks.  */
 void
-cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
-				    struct cgraph_edge *cs2)
+symbol_table::call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2)
 {
-  struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook;
+  cgraph_2edge_hook_list *entry = m_first_edge_duplicated_hook;
   while (entry)
   {
     entry->hook (cs1, cs2, entry->data);
@@ -452,13 +407,13 @@  cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
 }
 
 /* Register HOOK to be called with DATA on each duplicated node.  */
-struct cgraph_2node_hook_list *
-cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
+cgraph_2node_hook_list *
+symbol_table::add_cgraph_duplication_hook (cgraph_2node_hook hook, void *data)
 {
-  struct cgraph_2node_hook_list *entry;
-  struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+  cgraph_2node_hook_list *entry;
+  cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
 
-  entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
+  entry = (cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -470,9 +425,9 @@  cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on duplicating nodes.  */
 void
-cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
+symbol_table::remove_cgraph_duplication_hook (cgraph_2node_hook_list *entry)
 {
-  struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+  cgraph_2node_hook_list **ptr = &m_first_cgraph_duplicated_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -482,57 +437,23 @@  cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
 
 /* Call all node duplication hooks.  */
 void
-cgraph_node::call_duplication_hooks (struct cgraph_node *node2)
+symbol_table::call_cgraph_duplication_hooks (cgraph_node *node,
+					     cgraph_node *node2)
 {
-  struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook;
+  cgraph_2node_hook_list *entry = m_first_cgraph_duplicated_hook;
   while (entry)
   {
-    entry->hook (this, node2, entry->data);
+    entry->hook (node, node2, entry->data);
     entry = entry->next;
   }
 }
 
-/* Allocate new callgraph node.  */
-
-static inline struct cgraph_node *
-cgraph_allocate_node (void)
-{
-  struct 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;
-}
-
-/* Allocate new callgraph node and insert it into basic data structures.  */
-
-cgraph_node *
-cgraph_node::create_empty (void)
-{
-  struct cgraph_node *node = cgraph_allocate_node ();
-
-  node->type = SYMTAB_FUNCTION;
-  node->frequency = NODE_FREQUENCY_NORMAL;
-  node->count_materialization_scale = REG_BR_PROB_BASE;
-  cgraph_n_nodes++;
-  return node;
-}
-
 /* Return cgraph node assigned to DECL.  Create new one when needed.  */
 
 cgraph_node *
 cgraph_node::create (tree decl)
 {
-  struct cgraph_node *node = cgraph_node::create_empty ();
+  cgraph_node *node = symtab->create_empty ();
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
 
   node->decl = decl;
@@ -553,17 +474,17 @@  cgraph_node::create (tree decl)
 cgraph_node *
 cgraph_node::get_create (tree decl)
 {
-  struct cgraph_node *first_clone = cgraph_node::get (decl);
+  cgraph_node *first_clone = cgraph_node::get (decl);
 
   if (first_clone && !first_clone->global.inlined_to)
     return first_clone;
 
-  struct cgraph_node *node = cgraph_node::create (decl);
+  cgraph_node *node = cgraph_node::create (decl);
   if (first_clone)
     {
       first_clone->clone_of = node;
       node->clones = first_clone;
-      symtab_prevail_in_asm_name_hash (node);
+      symtab->symtab_prevail_in_asm_name_hash (node);
       node->decl->decl_with_vis.symtab_node = node;
       if (dump_file)
 	fprintf (dump_file, "Introduced new external node "
@@ -604,22 +525,22 @@  cgraph_node::create_alias (tree alias, tree target)
    and cgraph_node::get (ALIAS) transparently returns
    cgraph_node::get (DECL).  */
 
-struct cgraph_node *
+cgraph_node *
 cgraph_node::create_same_body_alias (tree alias, tree decl)
 {
-  struct cgraph_node *n;
+  cgraph_node *n;
 #ifndef ASM_OUTPUT_DEF
   /* If aliases aren't supported by the assembler, fail.  */
   return NULL;
 #endif
   /* Langhooks can create same body aliases of symbols not defined.
      Those are useless. Drop them on the floor.  */
-  if (cgraph_global_info_ready)
+  if (symtab->global_info_ready)
     return NULL;
 
   n = cgraph_node::create_alias (alias, decl);
   n->cpp_implicit_alias = true;
-  if (cpp_implicit_aliases_done)
+  if (symtab->cpp_implicit_aliases_done)
     n->resolve_alias (cgraph_node::get (decl));
   return n;
 }
@@ -628,14 +549,14 @@  cgraph_node::create_same_body_alias (tree alias, tree decl)
    aliases DECL with an adjustments made into the first parameter.
    See comments in thunk_adjust for detail on the parameters.  */
 
-struct cgraph_node *
+cgraph_node *
 cgraph_node::create_thunk (tree alias, tree, bool this_adjusting,
 			   HOST_WIDE_INT fixed_offset,
 			   HOST_WIDE_INT virtual_value,
 			   tree virtual_offset,
 			   tree real_alias)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   node = cgraph_node::get (alias);
   if (node)
@@ -662,7 +583,7 @@  cgraph_node *
 cgraph_node::get_for_asmname (tree asmname)
 {
   /* We do not want to look at inline clones.  */
-  for (symtab_node *node = symtab_node_for_asm (asmname);
+  for (symtab_node *node = symtab_node::get_for_asmname (asmname);
        node;
        node = node->next_sharing_asm_name)
     {
@@ -678,7 +599,7 @@  cgraph_node::get_for_asmname (tree asmname)
 static hashval_t
 edge_hash (const void *x)
 {
-  return htab_hash_pointer (((const struct cgraph_edge *) x)->call_stmt);
+  return htab_hash_pointer (((const cgraph_edge *) x)->call_stmt);
 }
 
 /* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y.  */
@@ -686,13 +607,13 @@  edge_hash (const void *x)
 static int
 edge_eq (const void *x, const void *y)
 {
-  return ((const struct cgraph_edge *) x)->call_stmt == y;
+  return ((const cgraph_edge *) x)->call_stmt == y;
 }
 
 /* Add call graph edge E to call site hash of its caller.  */
 
 static inline void
-cgraph_update_edge_in_call_site_hash (struct cgraph_edge *e)
+cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
 {
   void **slot;
   slot = htab_find_slot_with_hash (e->caller->call_site_hash,
@@ -705,7 +626,7 @@  cgraph_update_edge_in_call_site_hash (struct cgraph_edge *e)
 /* Add call graph edge E to call site hash of its caller.  */
 
 static inline void
-cgraph_add_edge_to_call_site_hash (struct cgraph_edge *e)
+cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
 {
   void **slot;
   /* There are two speculative edges for every statement (one direct,
@@ -718,7 +639,7 @@  cgraph_add_edge_to_call_site_hash (struct cgraph_edge *e)
 				   INSERT);
   if (*slot)
     {
-      gcc_assert (((struct cgraph_edge *)*slot)->speculative);
+      gcc_assert (((cgraph_edge *)*slot)->speculative);
       if (e->callee)
 	*slot = e;
       return;
@@ -733,11 +654,11 @@  cgraph_add_edge_to_call_site_hash (struct cgraph_edge *e)
 cgraph_edge *
 cgraph_node::get_edge (gimple call_stmt)
 {
-  struct cgraph_edge *e, *e2;
+  cgraph_edge *e, *e2;
   int n = 0;
 
   if (call_site_hash)
-    return (struct cgraph_edge *)
+    return (cgraph_edge *)
       htab_find_with_hash (call_site_hash, call_stmt,
       	                   htab_hash_pointer (call_stmt));
 
@@ -774,49 +695,50 @@  cgraph_node::get_edge (gimple call_stmt)
 }
 
 
-/* Change field call_stmt of edge E to NEW_STMT.
+/* 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
-cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt,
-		      bool update_speculative)
+cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative)
 {
   tree decl;
 
   /* Speculative edges has three component, update all of them
      when asked to.  */
-  if (update_speculative && e->speculative)
+  if (update_speculative && speculative)
     {
-      struct cgraph_edge *direct, *indirect;
-      struct ipa_ref *ref;
+      cgraph_edge *direct, *indirect;
+      ipa_ref *ref;
 
-      cgraph_speculative_call_info (e, direct, indirect, ref);
-      cgraph_set_call_stmt (direct, new_stmt, false);
-      cgraph_set_call_stmt (indirect, new_stmt, false);
+      speculative_call_info (direct, indirect, ref);
+      direct->set_call_stmt (new_stmt, false);
+      indirect->set_call_stmt (new_stmt, false);
       ref->stmt = new_stmt;
       return;
     }
 
   /* Only direct speculative edges go to call_site_hash.  */
-  if (e->caller->call_site_hash
-      && (!e->speculative || !e->indirect_unknown_callee))
+  if (caller->call_site_hash
+      && (!speculative || !indirect_unknown_callee))
     {
-      htab_remove_elt_with_hash (e->caller->call_site_hash,
-				 e->call_stmt,
-				 htab_hash_pointer (e->call_stmt));
+      htab_remove_elt_with_hash (caller->call_site_hash,
+				 call_stmt,
+				 htab_hash_pointer (call_stmt));
     }
 
-  e->call_stmt = new_stmt;
-  if (e->indirect_unknown_callee
+  cgraph_edge *e = this;
+
+  call_stmt = new_stmt;
+  if (indirect_unknown_callee
       && (decl = gimple_call_fndecl (new_stmt)))
     {
       /* Constant propagation (and possibly also inlining?) can turn an
 	 indirect call into a direct one.  */
-      struct cgraph_node *new_callee = cgraph_node::get (decl);
+      cgraph_node *new_callee = cgraph_node::get (decl);
 
       gcc_checking_assert (new_callee);
-      e = cgraph_make_edge_direct (e, new_callee);
+      e = make_direct (new_callee);
     }
 
   push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
@@ -831,9 +753,9 @@  cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt,
    edge).  */
 
 cgraph_edge *
-cgraph_node::create_edge (cgraph_node *caller, cgraph_node *callee,
-			  gimple call_stmt, gcov_type count, int freq,
-			  bool indir_unknown_callee)
+symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
+		     gimple call_stmt, gcov_type count, int freq,
+		     bool indir_unknown_callee)
 {
   cgraph_edge *edge;
 
@@ -844,7 +766,7 @@  cgraph_node::create_edge (cgraph_node *caller, cgraph_node *callee,
       /* This is a rather expensive check possibly triggering
 	 construction of call stmt hashtable.  */
 #ifdef ENABLE_CHECKING
-      struct cgraph_edge *e;
+      cgraph_edge *e;
       gcc_checking_assert (
 	!(e = caller->get_edge (call_stmt)) || e->speculative);
 #endif
@@ -859,10 +781,12 @@  cgraph_node::create_edge (cgraph_node *caller, cgraph_node *callee,
     }
   else
     {
-      edge = ggc_alloc<struct cgraph_edge> ();
-      edge->uid = cgraph_edge_max_uid++;
+      edge = ggc_alloc<cgraph_edge> ();
+      edge->uid = edges_max_uid++;
     }
 
+  edges_count++;
+
   edge->aux = NULL;
   edge->caller = caller;
   edge->callee = callee;
@@ -903,12 +827,12 @@  cgraph_node::create_edge (cgraph_node *caller, cgraph_node *callee,
 
 /* Create edge from a given function to CALLEE in the cgraph.  */
 
-struct cgraph_edge *
-cgraph_node::create_edge (struct cgraph_node *callee,
+cgraph_edge *
+cgraph_node::create_edge (cgraph_node *callee,
 			  gimple call_stmt, gcov_type count, int freq)
 {
-  cgraph_edge *edge = cgraph_node::create_edge (this, callee, call_stmt,
-						count, freq, false);
+  cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count,
+					   freq, false);
 
   initialize_inline_failed (edge);
 
@@ -926,10 +850,10 @@  cgraph_node::create_edge (struct cgraph_node *callee,
 
 /* Allocate cgraph_indirect_call_info and set its fields to default values. */
 
-struct cgraph_indirect_call_info *
+cgraph_indirect_call_info *
 cgraph_allocate_init_indirect_info (void)
 {
-  struct cgraph_indirect_call_info *ii;
+  cgraph_indirect_call_info *ii;
 
   ii = ggc_cleared_alloc<cgraph_indirect_call_info> ();
   ii->param_index = -1;
@@ -940,13 +864,13 @@  cgraph_allocate_init_indirect_info (void)
    statement destination is a formal parameter of the caller with index
    PARAM_INDEX. */
 
-struct cgraph_edge *
+cgraph_edge *
 cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags,
 				   gcov_type count, int freq,
 				   bool compute_indirect_info)
 {
-  struct cgraph_edge *edge = cgraph_node::create_edge (this, NULL, call_stmt,
-						       count, freq, true);
+  cgraph_edge *edge = symtab->create_edge (this, NULL, call_stmt,
+							    count, freq, true);
   tree target;
 
   initialize_inline_failed (edge);
@@ -995,46 +919,46 @@  cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags,
   return edge;
 }
 
-/* Remove the edge E from the list of the callers of the callee.  */
+/* Remove the edge from the list of the callers of the callee.  */
 
-static inline void
-cgraph_edge_remove_callee (struct cgraph_edge *e)
+void
+cgraph_edge::remove_callee (void)
 {
-  gcc_assert (!e->indirect_unknown_callee);
-  if (e->prev_caller)
-    e->prev_caller->next_caller = e->next_caller;
-  if (e->next_caller)
-    e->next_caller->prev_caller = e->prev_caller;
-  if (!e->prev_caller)
-    e->callee->callers = e->next_caller;
+  gcc_assert (!indirect_unknown_callee);
+  if (prev_caller)
+    prev_caller->next_caller = next_caller;
+  if (next_caller)
+    next_caller->prev_caller = prev_caller;
+  if (!prev_caller)
+    callee->callers = next_caller;
 }
 
-/* Remove the edge E from the list of the callees of the caller.  */
+/* Remove the edge from the list of the callees of the caller.  */
 
-static inline void
-cgraph_edge_remove_caller (struct cgraph_edge *e)
+void
+cgraph_edge::remove_caller (void)
 {
-  if (e->prev_callee)
-    e->prev_callee->next_callee = e->next_callee;
-  if (e->next_callee)
-    e->next_callee->prev_callee = e->prev_callee;
-  if (!e->prev_callee)
+  if (prev_callee)
+    prev_callee->next_callee = next_callee;
+  if (next_callee)
+    next_callee->prev_callee = prev_callee;
+  if (!prev_callee)
     {
-      if (e->indirect_unknown_callee)
-	e->caller->indirect_calls = e->next_callee;
+      if (indirect_unknown_callee)
+	caller->indirect_calls = next_callee;
       else
-	e->caller->callees = e->next_callee;
+	caller->callees = next_callee;
     }
-  if (e->caller->call_site_hash)
-    htab_remove_elt_with_hash (e->caller->call_site_hash,
-			       e->call_stmt,
-	  		       htab_hash_pointer (e->call_stmt));
+  if (caller->call_site_hash)
+    htab_remove_elt_with_hash (caller->call_site_hash,
+			       call_stmt,
+			       htab_hash_pointer (call_stmt));
 }
 
 /* Put the edge onto the free list.  */
 
-static void
-cgraph_free_edge (struct cgraph_edge *e)
+void
+symbol_table::free_edge (cgraph_edge *e)
 {
   int uid = e->uid;
 
@@ -1046,32 +970,33 @@  cgraph_free_edge (struct cgraph_edge *e)
   e->uid = uid;
   NEXT_FREE_EDGE (e) = free_edges;
   free_edges = e;
+  edges_count--;
 }
 
-/* Remove the edge E in the cgraph.  */
+/* Remove the edge in the cgraph.  */
 
 void
-cgraph_remove_edge (struct cgraph_edge *e)
+cgraph_edge::remove (void)
 {
   /* Call all edge removal hooks.  */
-  cgraph_call_edge_removal_hooks (e);
+  symtab->call_edge_removal_hooks (this);
 
-  if (!e->indirect_unknown_callee)
+  if (!indirect_unknown_callee)
     /* Remove from callers list of the callee.  */
-    cgraph_edge_remove_callee (e);
+    remove_callee ();
 
   /* Remove from callees list of the callers.  */
-  cgraph_edge_remove_caller (e);
+  remove_caller ();
 
   /* Put the edge onto the free list.  */
-  cgraph_free_edge (e);
+  symtab->free_edge (this);
 }
 
 /* Set callee of call graph edge E and add it to the corresponding set of
    callers. */
 
 static void
-cgraph_set_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
+cgraph_set_edge_callee (cgraph_edge *e, cgraph_node *n)
 {
   e->prev_caller = NULL;
   if (n->callers)
@@ -1081,7 +1006,7 @@  cgraph_set_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
   e->callee = n;
 }
 
-/* Turn edge E into speculative call calling N2. Update
+/* Turn edge into speculative call calling N2. Update
    the profile so the direct call is taken COUNT times
    with FREQUENCY.  
 
@@ -1099,15 +1024,13 @@  cgraph_set_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
 
    Return direct edge created.  */
 
-struct cgraph_edge *
-cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
-				 struct cgraph_node *n2,
-				 gcov_type direct_count,
-				 int direct_frequency)
+cgraph_edge *
+cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
+			       int direct_frequency)
 {
-  struct cgraph_node *n = e->caller;
-  struct ipa_ref *ref = NULL;
-  struct cgraph_edge *e2;
+  cgraph_node *n = caller;
+  ipa_ref *ref = NULL;
+  cgraph_edge *e2;
 
   if (dump_file)
     {
@@ -1116,21 +1039,21 @@  cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
 	       xstrdup (n->name ()), n->order,
 	       xstrdup (n2->name ()), n2->order);
     }
-  e->speculative = true;
-  e2 = n->create_edge (n2, e->call_stmt, direct_count, direct_frequency);
+  speculative = true;
+  e2 = n->create_edge (n2, call_stmt, direct_count, direct_frequency);
   initialize_inline_failed (e2);
   e2->speculative = true;
   if (TREE_NOTHROW (n2->decl))
     e2->can_throw_external = false;
   else
-    e2->can_throw_external = e->can_throw_external;
-  e2->lto_stmt_uid = e->lto_stmt_uid;
-  e->count -= e2->count;
-  e->frequency -= e2->frequency;
-  cgraph_call_edge_duplication_hooks (e, e2);
-  ref = n->add_reference (n2, IPA_REF_ADDR, e->call_stmt);
-  ref->lto_stmt_uid = e->lto_stmt_uid;
-  ref->speculative = e->speculative;
+    e2->can_throw_external = can_throw_external;
+  e2->lto_stmt_uid = lto_stmt_uid;
+  count -= e2->count;
+  frequency -= e2->frequency;
+  symtab->call_edge_duplication_hooks (this, e2);
+  ref = n->create_reference (n2, IPA_REF_ADDR, call_stmt);
+  ref->lto_stmt_uid = lto_stmt_uid;
+  ref->speculative = speculative;
   n2->mark_address_taken ();
   return e2;
 }
@@ -1142,18 +1065,18 @@  cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
    All three components are attached to single statement (the indirect
    call) and if one of them exists, all of them must exist.
 
-   Given speculative call edge E, return all three components. 
+   Given speculative call edge, return all three components.
  */
 
 void
-cgraph_speculative_call_info (struct cgraph_edge *e,
-			      struct cgraph_edge *&direct,
-			      struct cgraph_edge *&indirect,
-			      struct ipa_ref *&reference)
+cgraph_edge::speculative_call_info (cgraph_edge *&direct,
+				    cgraph_edge *&indirect,
+				    ipa_ref *&reference)
 {
-  struct ipa_ref *ref;
+  ipa_ref *ref;
   int i;
-  struct cgraph_edge *e2;
+  cgraph_edge *e2;
+  cgraph_edge *e = this;
 
   if (!e->indirect_unknown_callee)
     for (e2 = e->caller->indirect_calls;
@@ -1196,31 +1119,32 @@  cgraph_speculative_call_info (struct cgraph_edge *e,
   gcc_assert (e && e2 && ref);
 }
 
-/* Redirect callee of E to N.  The function does not update underlying
+/* Redirect callee of the edge to N.  The function does not update underlying
    call expression.  */
 
 void
-cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
+cgraph_edge::redirect_callee (cgraph_node *n)
 {
   /* Remove from callers list of the current callee.  */
-  cgraph_edge_remove_callee (e);
+  remove_callee ();
 
   /* Insert to callers list of the new callee.  */
-  cgraph_set_edge_callee (e, n);
+  cgraph_set_edge_callee (this, n);
 }
 
-/* Speculative call EDGE turned out to be direct call to CALLE_DECL.
+/* 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. */
 
-struct cgraph_edge *
-cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
+cgraph_edge *
+cgraph_edge::resolve_speculation (tree callee_decl)
 {
-  struct cgraph_edge *e2;
-  struct ipa_ref *ref;
+  cgraph_edge *edge = this;
+  cgraph_edge *e2;
+  ipa_ref *ref;
 
   gcc_assert (edge->speculative);
-  cgraph_speculative_call_info (edge, e2, edge, ref);
+  edge->speculative_call_info (e2, edge, ref);
   if (!callee_decl
       || !ref->referred->semantically_equivalent_p
 	   (symtab_node::get (callee_decl)))
@@ -1246,7 +1170,7 @@  cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
     }
   else
     {
-      struct cgraph_edge *tmp = edge;
+      cgraph_edge *tmp = edge;
       if (dump_file)
         fprintf (dump_file, "Speculative call turned into direct call.\n");
       edge = e2;
@@ -1262,7 +1186,7 @@  cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
   e2->speculative = false;
   ref->remove_reference ();
   if (e2->indirect_unknown_callee || e2->inline_failed)
-    cgraph_remove_edge (e2);
+    e2->remove ();
   else
     e2->callee->remove_symbol_and_inline_clones ();
   if (edge->caller->call_site_hash)
@@ -1270,50 +1194,51 @@  cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
   return edge;
 }
 
-/* Make an indirect EDGE with an unknown callee an ordinary edge leading to
+/* 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.  */
 
-struct cgraph_edge *
-cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
+cgraph_edge *
+cgraph_edge::make_direct (cgraph_node *callee)
 {
-  gcc_assert (edge->indirect_unknown_callee);
+  cgraph_edge *edge = this;
+  gcc_assert (indirect_unknown_callee);
 
   /* If we are redirecting speculative call, make it non-speculative.  */
-  if (edge->indirect_unknown_callee && edge->speculative)
+  if (indirect_unknown_callee && speculative)
     {
-      edge = cgraph_resolve_speculation (edge, callee->decl);
+      edge = edge->resolve_speculation (callee->decl);
 
       /* On successful speculation just return the pre existing direct edge.  */
-      if (!edge->indirect_unknown_callee)
+      if (!indirect_unknown_callee)
         return edge;
     }
 
-  edge->indirect_unknown_callee = 0;
-  ggc_free (edge->indirect_info);
-  edge->indirect_info = NULL;
+  indirect_unknown_callee = 0;
+  ggc_free (indirect_info);
+  indirect_info = NULL;
 
   /* Get the edge out of the indirect edge list. */
-  if (edge->prev_callee)
-    edge->prev_callee->next_callee = edge->next_callee;
-  if (edge->next_callee)
-    edge->next_callee->prev_callee = edge->prev_callee;
-  if (!edge->prev_callee)
-    edge->caller->indirect_calls = edge->next_callee;
+  if (prev_callee)
+    prev_callee->next_callee = next_callee;
+  if (next_callee)
+    next_callee->prev_callee = prev_callee;
+  if (!prev_callee)
+    caller->indirect_calls = next_callee;
 
   /* Put it into the normal callee list */
-  edge->prev_callee = NULL;
-  edge->next_callee = edge->caller->callees;
-  if (edge->caller->callees)
-    edge->caller->callees->prev_callee = edge;
-  edge->caller->callees = edge;
+  prev_callee = NULL;
+  next_callee = caller->callees;
+  if (caller->callees)
+    caller->callees->prev_callee = edge;
+  caller->callees = edge;
 
   /* Insert to callers list of the new callee.  */
   cgraph_set_edge_callee (edge, callee);
 
-  if (edge->call_stmt)
-    edge->call_stmt_cannot_inline_p
-      = !gimple_check_call_matching_types (edge->call_stmt, callee->decl,
+  if (call_stmt)
+    call_stmt_cannot_inline_p
+      = !gimple_check_call_matching_types (call_stmt, callee->decl,
 					   false);
 
   /* We need to re-determine the inlining status of the edge.  */
@@ -1325,27 +1250,29 @@  cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
    associated with E so that it corresponds to the edge callee.  */
 
 gimple
-cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
+cgraph_edge::redirect_call_stmt_to_callee (void)
 {
+  cgraph_edge *e = this;
+
   tree decl = gimple_call_fndecl (e->call_stmt);
   tree lhs = gimple_call_lhs (e->call_stmt);
   gimple new_stmt;
   gimple_stmt_iterator gsi;
 #ifdef ENABLE_CHECKING
-  struct cgraph_node *node;
+  cgraph_node *node;
 #endif
 
   if (e->speculative)
     {
-      struct cgraph_edge *e2;
+      cgraph_edge *e2;
       gimple new_stmt;
-      struct ipa_ref *ref;
+      ipa_ref *ref;
 
-      cgraph_speculative_call_info (e, e, e2, ref);
+      e->speculative_call_info (e, e2, ref);
       /* If there already is an direct call (i.e. as a result of inliner's
 	 substitution), forget about speculating.  */
       if (decl)
-	e = cgraph_resolve_speculation (e, decl);
+	e = e->resolve_speculation (decl);
       /* If types do not match, speculation was likely wrong. 
          The direct edge was posisbly redirected to the clone with a different
 	 signature.  We did not update the call statement yet, so compare it 
@@ -1361,7 +1288,7 @@  cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
 		     e->caller->order,
 		     xstrdup (e->callee->name ()),
 		     e->callee->order);
-	  e = cgraph_resolve_speculation (e, NULL);
+	  e = e->resolve_speculation ();
 	  /* We are producing the final function body and will throw away the
 	     callgraph edges really soon.  Reset the counts/frequencies to
 	     keep verifier happy in the case of roundoff errors.  */
@@ -1423,16 +1350,16 @@  cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
     }
 #endif
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
+      fprintf (symtab->dump_file, "updating call of %s/%i -> %s/%i: ",
 	       xstrdup (e->caller->name ()), e->caller->order,
 	       xstrdup (e->callee->name ()), e->callee->order);
-      print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
+      print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
       if (e->callee->clone.combined_args_to_skip)
 	{
-	  fprintf (cgraph_dump_file, " combined args to skip: ");
-	  dump_bitmap (cgraph_dump_file,
+	  fprintf (symtab->dump_file, " combined args to skip: ");
+	  dump_bitmap (symtab->dump_file,
 		       e->callee->clone.combined_args_to_skip);
 	}
     }
@@ -1498,10 +1425,10 @@  cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
 
   e->caller->set_call_stmt_including_clones (e->call_stmt, new_stmt, false);
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "  updated to:");
-      print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
+      fprintf (symtab->dump_file, "  updated to:");
+      print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
     }
   return new_stmt;
 }
@@ -1513,7 +1440,7 @@  cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
    replacement.  */
 
 static void
-cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
+cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 					gimple old_stmt, tree old_call,
 					gimple new_stmt)
 {
@@ -1527,8 +1454,8 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
      into different builtin.  */
   if (old_call != new_call)
     {
-      struct cgraph_edge *e = node->get_edge (old_stmt);
-      struct cgraph_edge *ne = NULL;
+      cgraph_edge *e = node->get_edge (old_stmt);
+      cgraph_edge *ne = NULL;
       gcov_type count;
       int frequency;
 
@@ -1539,13 +1466,13 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
 	     it.  We also might've cloned and redirected the edge.  */
 	  if (new_call && e->callee)
 	    {
-	      struct cgraph_node *callee = e->callee;
+	      cgraph_node *callee = e->callee;
 	      while (callee)
 		{
 		  if (callee->decl == new_call
 		      || callee->former_clone_of == new_call)
 		    {
-		      cgraph_set_call_stmt (e, new_stmt);
+		      e->set_call_stmt (new_stmt);
 		      return;
 		    }
 		  callee = callee->clone_of;
@@ -1558,7 +1485,7 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
 	  count = e->count;
 	  frequency = e->frequency;
  	  if (e->indirect_unknown_callee || e->inline_failed)
-	    cgraph_remove_edge (e);
+	    e->remove ();
 	  else
 	    e->callee->remove_symbol_and_inline_clones ();
 	}
@@ -1580,7 +1507,7 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
     }
   /* We only updated the call stmt; update pointer in cgraph edge..  */
   else if (old_stmt != new_stmt)
-    cgraph_set_call_stmt (node->get_edge (old_stmt), new_stmt);
+    node->get_edge (old_stmt)->set_call_stmt (new_stmt);
 }
 
 /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
@@ -1590,8 +1517,8 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
 void
 cgraph_update_edges_for_call_stmt (gimple old_stmt, tree old_decl, gimple new_stmt)
 {
-  struct cgraph_node *orig = cgraph_node::get (cfun->decl);
-  struct cgraph_node *node;
+  cgraph_node *orig = cgraph_node::get (cfun->decl);
+  cgraph_node *node;
 
   gcc_checking_assert (orig);
   cgraph_update_edges_for_call_stmt_node (orig, old_stmt, old_decl, new_stmt);
@@ -1619,7 +1546,7 @@  cgraph_update_edges_for_call_stmt (gimple old_stmt, tree old_decl, gimple new_st
 void
 cgraph_node::remove_callees (void)
 {
-  struct cgraph_edge *e, *f;
+  cgraph_edge *e, *f;
 
   /* It is sufficient to remove the edges from the lists of callers of
      the callees.  The callee list of the node can be zapped with one
@@ -1627,18 +1554,18 @@  cgraph_node::remove_callees (void)
   for (e = callees; e; e = f)
     {
       f = e->next_callee;
-      cgraph_call_edge_removal_hooks (e);
+      symtab->call_edge_removal_hooks (e);
       if (!e->indirect_unknown_callee)
-	cgraph_edge_remove_callee (e);
-      cgraph_free_edge (e);
+	e->remove_callee ();
+      symtab->free_edge (e);
     }
   for (e = indirect_calls; e; e = f)
     {
       f = e->next_callee;
-      cgraph_call_edge_removal_hooks (e);
+      symtab->call_edge_removal_hooks (e);
       if (!e->indirect_unknown_callee)
-	cgraph_edge_remove_callee (e);
-      cgraph_free_edge (e);
+	e->remove_callee ();
+      symtab->free_edge (e);
     }
   indirect_calls = NULL;
   callees = NULL;
@@ -1654,7 +1581,7 @@  cgraph_node::remove_callees (void)
 void
 cgraph_node::remove_callers (void)
 {
-  struct cgraph_edge *e, *f;
+  cgraph_edge *e, *f;
 
   /* It is sufficient to remove the edges from the lists of callees of
      the callers.  The caller list of the node can be zapped with one
@@ -1662,9 +1589,9 @@  cgraph_node::remove_callers (void)
   for (e = callers; e; e = f)
     {
       f = e->next_caller;
-      cgraph_call_edge_removal_hooks (e);
-      cgraph_edge_remove_caller (e);
-      cgraph_free_edge (e);
+      symtab->call_edge_removal_hooks (e);
+      e->remove_caller ();
+      symtab->free_edge (e);
     }
   callers = NULL;
 }
@@ -1719,7 +1646,7 @@  void
 cgraph_node::release_body (void)
 {
   ipa_transforms_to_apply.release ();
-  if (!used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
+  if (!used_as_abstract_origin && symtab->state != PARSING)
     {
       DECL_RESULT (decl) = NULL;
       DECL_ARGUMENTS (decl) = NULL;
@@ -1739,10 +1666,10 @@  cgraph_node::release_body (void)
 void
 cgraph_node::remove (void)
 {
-  struct cgraph_node *n;
+  cgraph_node *n;
   int uid = this->uid;
 
-  cgraph_call_node_removal_hooks (this);
+  symtab->call_cgraph_removal_hooks (this);
   remove_callers ();
   remove_callees ();
   ipa_transforms_to_apply.release ();
@@ -1756,7 +1683,7 @@  cgraph_node::remove (void)
   nested = NULL;
   if (origin)
     {
-      struct cgraph_node **node2 = &origin->nested;
+      cgraph_node **node2 = &origin->nested;
 
       while (*node2 != this)
 	node2 = &(*node2)->next_nested;
@@ -1771,7 +1698,7 @@  cgraph_node::remove (void)
     next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
   if (clones)
     {
-      struct cgraph_node *n, *next;
+      cgraph_node *n, *next;
 
       if (clone_of)
         {
@@ -1804,12 +1731,12 @@  cgraph_node::remove (void)
      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.
      */
-  if (cgraph_state != CGRAPH_LTO_STREAMING)
+  if (symtab->state != LTO_STREAMING)
     {
       n = cgraph_node::get (decl);
       if (!n
 	  || (!n->clones && !n->clone_of && !n->global.inlined_to
-	      && (cgraph_global_info_ready
+	      && (symtab->global_info_ready
 		  && (TREE_ASM_WRITTEN (n->decl)
 		      || DECL_EXTERNAL (n->decl)
 		      || !n->analyzed
@@ -1823,15 +1750,8 @@  cgraph_node::remove (void)
       htab_delete (call_site_hash);
       call_site_hash = NULL;
     }
-  cgraph_n_nodes--;
 
-  /* Clear out the node to NULL all pointers and add the node to the free
-     list.  */
-  memset (this, 0, sizeof (*this));
-  type = SYMTAB_FUNCTION;
-  this->uid = uid;
-  SET_NEXT_FREE_NODE (this, free_nodes);
-  free_nodes = this;
+  symtab->release_symbol (this, uid);
 }
 
 /* Likewise indicate that a node is having address taken.  */
@@ -1860,27 +1780,24 @@  cgraph_node::mark_address_taken (void)
 
 /* Return local info for the compiled function.  */
 
-struct cgraph_local_info *
-cgraph_local_info (tree decl)
+cgraph_local_info *
+cgraph_node::local_info (tree decl)
 {
-  struct cgraph_node *node;
-
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
-  node = cgraph_node::get (decl);
+  cgraph_node *node = get (decl);
   if (!node)
     return NULL;
   return &node->local;
 }
 
-/* Return local info for the compiled function.  */
+/* Return global info for the compiled function.  */
 
-struct cgraph_global_info *
-cgraph_global_info (tree decl)
+cgraph_global_info *
+cgraph_node::global_info (tree decl)
 {
-  struct cgraph_node *node;
-
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL && cgraph_global_info_ready);
-  node = cgraph_node::get (decl);
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+    && symtab->global_info_ready);
+  cgraph_node *node = get (decl);
   if (!node)
     return NULL;
   return &node->global;
@@ -1888,13 +1805,11 @@  cgraph_global_info (tree decl)
 
 /* Return local info for the compiled function.  */
 
-struct cgraph_rtl_info *
-cgraph_rtl_info (tree decl)
+cgraph_rtl_info *
+cgraph_node::rtl_info (tree decl)
 {
-  struct cgraph_node *node;
-
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
-  node = cgraph_node::get (decl);
+  cgraph_node *node = get (decl);
   if (!node
       || (decl != current_function_decl
 	  && !TREE_ASM_WRITTEN (node->decl)))
@@ -1948,7 +1863,7 @@  const char * const cgraph_availability_names[] =
 void
 cgraph_node::dump (FILE *f)
 {
-  struct cgraph_edge *edge;
+  cgraph_edge *edge;
   int indirect_calls_count = 0;
 
   dump_base (f);
@@ -1963,7 +1878,7 @@  cgraph_node::dump (FILE *f)
     fprintf (f, "  Clone of %s/%i\n",
 	     clone_of->asm_name (),
 	     clone_of->order);
-  if (cgraph_function_flags_ready)
+  if (symtab->function_flags_ready)
     fprintf (f, "  Availability: %s\n",
 	     cgraph_availability_names [get_availability ()]);
 
@@ -2028,12 +1943,12 @@  cgraph_node::dump (FILE *f)
     {
       fprintf (f, "%s/%i ", edge->caller->asm_name (),
 	       edge->caller->order);
-      if (edge->count)
+      if (count)
 	fprintf (f, "(%"PRId64"x) ",
-		 (int64_t)edge->count);
-      if (edge->frequency)
+		 (int64_t)count);
+      if (frequency)
 	fprintf (f, "(%.2f per call) ",
-		 edge->frequency / (double)CGRAPH_FREQ_BASE);
+		 frequency / (double)CGRAPH_FREQ_BASE);
       if (edge->speculative)
 	fprintf (f, "(speculative) ");
       if (!edge->inline_failed)
@@ -2057,10 +1972,10 @@  cgraph_node::dump (FILE *f)
 	fprintf (f, "(indirect_inlining) ");
       if (edge->count)
 	fprintf (f, "(%"PRId64"x) ",
-		 (int64_t)edge->count);
+		 (int64_t)count);
       if (edge->frequency)
 	fprintf (f, "(%.2f per call) ",
-		 edge->frequency / (double)CGRAPH_FREQ_BASE);
+		 frequency / (double)CGRAPH_FREQ_BASE);
       if (edge->can_throw_external)
 	fprintf (f, "(can throw external) ");
     }
@@ -2086,7 +2001,7 @@  cgraph_node::debug (void)
 void
 cgraph_node::dump_cgraph (FILE *f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "callgraph:\n\n");
   FOR_EACH_FUNCTION (node)
@@ -2098,7 +2013,7 @@  cgraph_node::dump_cgraph (FILE *f)
 bool
 cgraph_function_possibly_inlined_p (tree decl)
 {
-  if (!cgraph_global_info_ready)
+  if (!symtab->global_info_ready)
     return !DECL_UNINLINABLE (decl);
   return DECL_POSSIBLY_INLINED (decl);
 }
@@ -2107,7 +2022,7 @@  cgraph_function_possibly_inlined_p (tree decl)
 void
 cgraph_node::unnest (void)
 {
-  struct cgraph_node **node2 = &origin->nested;
+  cgraph_node **node2 = &origin->nested;
   gcc_assert (origin);
 
   while (*node2 != this)
@@ -2157,7 +2072,7 @@  cgraph_node::get_availability (void)
 
 /* Worker for cgraph_node_can_be_local_p.  */
 static bool
-cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node, void *)
+cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *)
 {
   return !(!node->force_output
 	   && ((DECL_COMDAT (node->decl)
@@ -2189,8 +2104,8 @@  cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
 						 void *data,
 						 bool include_overwritable)
 {
-  struct cgraph_edge *e;
-  struct ipa_ref *ref;
+  cgraph_edge *e;
+  ipa_ref *ref;
 
   if (callback (this, data))
     return true;
@@ -2204,7 +2119,7 @@  cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
 
   FOR_EACH_ALIAS (this, ref)
     {
-      struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
       if (include_overwritable
 	  || alias->get_availability () > AVAIL_INTERPOSABLE)
 	if (alias->call_for_symbol_thunks_and_aliases (callback, data,
@@ -2224,14 +2139,14 @@  cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
 					  void *data,
 					  bool include_overwritable)
 {
-  struct ipa_ref *ref;
+  ipa_ref *ref;
 
   if (callback (this, data))
     return true;
 
   FOR_EACH_ALIAS (this, ref)
     {
-      struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
       if (include_overwritable
 	  || alias->get_availability () > AVAIL_INTERPOSABLE)
 	if (alias->call_for_symbol_and_aliases (callback, data,
@@ -2244,7 +2159,7 @@  cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
 /* Worker to bring NODE local.  */
 
 bool
-cgraph_node::make_local (struct cgraph_node *node, void *)
+cgraph_node::make_local (cgraph_node *node, void *)
 {
   gcc_checking_assert (node->can_be_local_p ());
   if (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
@@ -2275,9 +2190,9 @@  cgraph_node::make_local (void)
 /* Worker to set nothrow flag.  */
 
 static bool
-cgraph_set_nothrow_flag_1 (struct cgraph_node *node, void *data)
+cgraph_set_nothrow_flag_1 (cgraph_node *node, void *data)
 {
-  struct cgraph_edge *e;
+  cgraph_edge *e;
 
   TREE_NOTHROW (node->decl) = data != NULL;
 
@@ -2300,7 +2215,7 @@  cgraph_node::set_nothrow_flag (bool nothrow)
 /* Worker to set const flag.  */
 
 static bool
-cgraph_set_const_flag_1 (struct cgraph_node *node, void *data)
+cgraph_set_const_flag_1 (cgraph_node *node, void *data)
 {
   /* Static constructors and destructors without a side effect can be
      optimized out.  */
@@ -2330,7 +2245,7 @@  cgraph_node::set_const_flag (bool readonly, bool looping)
 /* Worker to set pure flag.  */
 
 static bool
-cgraph_set_pure_flag_1 (struct cgraph_node *node, void *data)
+cgraph_set_pure_flag_1 (cgraph_node *node, void *data)
 {
   /* Static constructors and destructors without a side effect can be
      optimized out.  */
@@ -2371,19 +2286,19 @@  cgraph_node::cannot_return_p (void)
 	     == (ECF_NORETURN | ECF_NOTHROW));
 }
 
-/* Return true when call of E can not lead to return from caller
+/* 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.
    FIXME: We could actually mark all edges that have no reaching
    patch to the exit block or throw to get better results.  */
 bool
-cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e)
+cgraph_edge::cannot_lead_to_return_p (void)
 {
-  if (e->caller->cannot_return_p ())
+  if (caller->cannot_return_p ())
     return true;
-  if (e->indirect_unknown_callee)
+  if (indirect_unknown_callee)
     {
-      int flags = e->indirect_info->ecf_flags;
+      int flags = indirect_info->ecf_flags;
       if (!flag_exceptions)
 	return (flags & ECF_NORETURN) != 0;
       else
@@ -2391,7 +2306,7 @@  cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e)
 		 == (ECF_NORETURN | ECF_NOTHROW));
     }
   else
-    return e->callee->cannot_return_p ();
+    return callee->cannot_return_p ();
 }
 
 /* Return true when function can be removed from callgraph
@@ -2422,7 +2337,7 @@  cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
 /* Worker for cgraph_can_remove_if_no_direct_calls_p.  */
 
 static bool
-nonremovable_p (struct cgraph_node *node, void *)
+nonremovable_p (cgraph_node *node, void *)
 {
   return !node->can_remove_if_no_direct_calls_and_refs_p ();
 }
@@ -2477,7 +2392,7 @@  cgraph_node::will_be_removed_from_program_if_no_direct_calls_p (void)
 /* Worker for cgraph_only_called_directly_p.  */
 
 static bool
-cgraph_not_only_called_directly_p_1 (struct cgraph_node *node, void *)
+cgraph_not_only_called_directly_p_1 (cgraph_node *node, void *)
 {
   return !node->only_called_directly_or_aliased_p ();
 }
@@ -2499,10 +2414,10 @@  cgraph_node::only_called_directly_p (void)
 /* Collect all callers of NODE.  Worker for collect_callers_of_node.  */
 
 static bool
-collect_callers_of_node_1 (struct cgraph_node *node, void *data)
+collect_callers_of_node_1 (cgraph_node *node, void *data)
 {
   vec<cgraph_edge *> *redirect_callers = (vec<cgraph_edge *> *)data;
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   enum availability avail;
   node->ultimate_alias_target (&avail);
 
@@ -2528,7 +2443,7 @@  cgraph_node::collect_callers (void)
 /* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  */
 
 static bool
-clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
+clone_of_p (cgraph_node *node, cgraph_node *node2)
 {
   bool skipped_thunk = false;
   node = node->ultimate_alias_target ();
@@ -2566,7 +2481,7 @@  clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
 /* Verify edge E count and frequency.  */
 
 static bool
-verify_edge_count_and_frequency (struct cgraph_edge *e)
+verify_edge_count_and_frequency (cgraph_edge *e)
 {
   bool error_found = false;
   if (e->count < 0)
@@ -2608,7 +2523,7 @@  verify_edge_count_and_frequency (struct cgraph_edge *e)
 
 /* Switch to THIS_CFUN if needed and print STMT to stderr.  */
 static void
-cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
+cgraph_debug_gimple_stmt (function *this_cfun, gimple stmt)
 {
   bool fndecl_was_null = false;
   /* debug_gimple_stmt needs correct cfun */
@@ -2629,13 +2544,13 @@  cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
    statement.  Return true if the verification should fail.  */
 
 static bool
-verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
+verify_edge_corresponds_to_fndecl (cgraph_edge *e, tree decl)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   if (!decl || e->callee->global.inlined_to)
     return false;
-  if (cgraph_state == CGRAPH_LTO_STREAMING)
+  if (symtab->state == LTO_STREAMING)
     return false;
   node = cgraph_node::get (decl);
 
@@ -2669,8 +2584,8 @@  verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
 DEBUG_FUNCTION void
 cgraph_node::verify_node (void)
 {
-  struct cgraph_edge *e;
-  struct function *this_cfun = DECL_STRUCT_FUNCTION (decl);
+  cgraph_edge *e;
+  function *this_cfun = DECL_STRUCT_FUNCTION (decl);
   basic_block this_block;
   gimple_stmt_iterator gsi;
   bool error_found = false;
@@ -2786,7 +2701,7 @@  cgraph_node::verify_node (void)
 
   if (clone_of)
     {
-      struct cgraph_node *n;
+      cgraph_node *n;
       for (n = clone_of->clones; n; n = n->next_sibling_clone)
 	if (n == this)
 	  break;
@@ -2798,7 +2713,7 @@  cgraph_node::verify_node (void)
     }
   if (clones)
     {
-      struct cgraph_node *n;
+      cgraph_node *n;
       for (n = clones; n; n = n->next_sibling_clone)
 	if (n->clone_of != this)
 	  break;
@@ -2828,7 +2743,7 @@  cgraph_node::verify_node (void)
     {
       bool ref_found = false;
       int i;
-      struct ipa_ref *ref = NULL;
+      ipa_ref *ref = NULL;
 
       if (callees)
 	{
@@ -2881,7 +2796,7 @@  cgraph_node::verify_node (void)
 	{
 	  hash_set<gimple> stmts;
 	  int i;
-	  struct ipa_ref *ref = NULL;
+	  ipa_ref *ref = NULL;
 
 	  /* Reach the trees by walking over the CFG, and note the
 	     enclosing basic-blocks in the call edges.  */
@@ -2898,7 +2813,7 @@  cgraph_node::verify_node (void)
 		  stmts.add (stmt);
 		  if (is_gimple_call (stmt))
 		    {
-		      struct cgraph_edge *e = get_edge (stmt);
+		      cgraph_edge *e = get_edge (stmt);
 		      tree decl = gimple_call_fndecl (stmt);
 		      if (e)
 			{
@@ -2986,7 +2901,7 @@  cgraph_node::verify_node (void)
 DEBUG_FUNCTION void
 cgraph_node::verify_cgraph_nodes (void)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   if (seen_error ())
     return;
@@ -3029,7 +2944,7 @@  cgraph_node::function_symbol (enum availability *availability)
 bool
 cgraph_node::get_body (void)
 {
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data *file_data;
   const char *data, *name;
   size_t len;
   tree decl = this->decl;
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.  */
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index b10061b..96d7015 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -56,7 +56,7 @@  record_reference (tree *tp, int *walk_subtrees, void *data)
 {
   tree t = *tp;
   tree decl;
-  struct record_reference_ctx *ctx = (struct record_reference_ctx *)data;
+  record_reference_ctx *ctx = (record_reference_ctx *)data;
 
   t = canonicalize_constructor_val (t, NULL);
   if (!t)
@@ -78,16 +78,16 @@  record_reference (tree *tp, int *walk_subtrees, void *data)
       decl = get_base_var (*tp);
       if (TREE_CODE (decl) == FUNCTION_DECL)
 	{
-	  struct cgraph_node *node = cgraph_node::get_create (decl);
+	  cgraph_node *node = cgraph_node::get_create (decl);
 	  if (!ctx->only_vars)
 	    node->mark_address_taken ();
-	  ctx->varpool_node->add_reference (node, IPA_REF_ADDR);
+	  ctx->varpool_node->create_reference (node, IPA_REF_ADDR);
 	}
 
       if (TREE_CODE (decl) == VAR_DECL)
 	{
 	  varpool_node *vnode = varpool_node::get_create (decl);
-	  ctx->varpool_node->add_reference (vnode, IPA_REF_ADDR);
+	  ctx->varpool_node->create_reference (vnode, IPA_REF_ADDR);
 	}
       *walk_subtrees = 0;
       break;
@@ -109,7 +109,7 @@  record_reference (tree *tp, int *walk_subtrees, void *data)
 /* Record references to typeinfos in the type list LIST.  */
 
 static void
-record_type_list (struct cgraph_node *node, tree list)
+record_type_list (cgraph_node *node, tree list)
 {
   for (; list; list = TREE_CHAIN (list))
     {
@@ -124,7 +124,7 @@  record_type_list (struct cgraph_node *node, tree list)
 	  if (TREE_CODE (type) == VAR_DECL)
 	    {
 	      varpool_node *vnode = varpool_node::get_create (type);
-	      node->add_reference (vnode, IPA_REF_ADDR);
+	      node->create_reference (vnode, IPA_REF_ADDR);
 	    }
 	}
     }
@@ -134,16 +134,16 @@  record_type_list (struct cgraph_node *node, tree list)
    for NODE.  */
 
 static void
-record_eh_tables (struct cgraph_node *node, struct function *fun)
+record_eh_tables (cgraph_node *node, function *fun)
 {
   eh_region i;
 
   if (DECL_FUNCTION_PERSONALITY (node->decl))
     {
       tree per_decl = DECL_FUNCTION_PERSONALITY (node->decl);
-      struct cgraph_node *per_node = cgraph_node::get_create (per_decl);
+      cgraph_node *per_node = cgraph_node::get_create (per_decl);
 
-      node->add_reference (per_node, IPA_REF_ADDR);
+      node->create_reference (per_node, IPA_REF_ADDR);
       per_node->mark_address_taken ();
     }
 
@@ -222,16 +222,16 @@  mark_address (gimple stmt, tree addr, tree, void *data)
   addr = get_base_address (addr);
   if (TREE_CODE (addr) == FUNCTION_DECL)
     {
-      struct cgraph_node *node = cgraph_node::get_create (addr);
+      cgraph_node *node = cgraph_node::get_create (addr);
       node->mark_address_taken ();
-      ((symtab_node *)data)->add_reference (node, IPA_REF_ADDR, stmt);
+      ((symtab_node *)data)->create_reference (node, IPA_REF_ADDR, stmt);
     }
   else if (addr && TREE_CODE (addr) == VAR_DECL
 	   && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
     {
       varpool_node *vnode = varpool_node::get_create (addr);
 
-      ((symtab_node *)data)->add_reference (vnode, IPA_REF_ADDR, stmt);
+      ((symtab_node *)data)->create_reference (vnode, IPA_REF_ADDR, stmt);
     }
 
   return false;
@@ -247,16 +247,16 @@  mark_load (gimple stmt, tree t, tree, void *data)
     {
       /* ??? This can happen on platforms with descriptors when these are
 	 directly manipulated in the code.  Pretend that it's an address.  */
-      struct cgraph_node *node = cgraph_node::get_create (t);
+      cgraph_node *node = cgraph_node::get_create (t);
       node->mark_address_taken ();
-      ((symtab_node *)data)->add_reference (node, IPA_REF_ADDR, stmt);
+      ((symtab_node *)data)->create_reference (node, IPA_REF_ADDR, stmt);
     }
   else if (t && TREE_CODE (t) == VAR_DECL
 	   && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
       varpool_node *vnode = varpool_node::get_create (t);
 
-      ((symtab_node *)data)->add_reference (vnode, IPA_REF_LOAD, stmt);
+      ((symtab_node *)data)->create_reference (vnode, IPA_REF_LOAD, stmt);
     }
   return false;
 }
@@ -272,7 +272,7 @@  mark_store (gimple stmt, tree t, tree, void *data)
     {
       varpool_node *vnode = varpool_node::get_create (t);
 
-      ((symtab_node *)data)->add_reference (vnode, IPA_REF_STORE, stmt);
+      ((symtab_node *)data)->create_reference (vnode, IPA_REF_STORE, stmt);
      }
   return false;
 }
@@ -320,7 +320,7 @@  unsigned int
 pass_build_cgraph_edges::execute (function *fun)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node::get (current_function_decl);
+  cgraph_node *node = cgraph_node::get (current_function_decl);
   gimple_stmt_iterator gsi;
   tree decl;
   unsigned ix;
@@ -343,8 +343,7 @@  pass_build_cgraph_edges::execute (function *fun)
 							 bb);
 	      decl = gimple_call_fndecl (stmt);
 	      if (decl)
-		node->create_edge (cgraph_node::get_create (decl),
-				   stmt, bb->count, freq);
+		node->create_edge (cgraph_node::get_create (decl), stmt, bb->count, freq);
 	      else if (gimple_call_internal_p (stmt))
 		;
 	      else
@@ -357,18 +356,18 @@  pass_build_cgraph_edges::execute (function *fun)
 	      && gimple_omp_parallel_child_fn (stmt))
 	    {
 	      tree fn = gimple_omp_parallel_child_fn (stmt);
-	      node->add_reference (cgraph_node::get_create (fn),
+	      node->create_reference (cgraph_node::get_create (fn),
 				      IPA_REF_ADDR, stmt);
 	    }
 	  if (gimple_code (stmt) == GIMPLE_OMP_TASK)
 	    {
 	      tree fn = gimple_omp_task_child_fn (stmt);
 	      if (fn)
-		node->add_reference (cgraph_node::get_create (fn),
+		node->create_reference (cgraph_node::get_create (fn),
 					IPA_REF_ADDR, stmt);
 	      fn = gimple_omp_task_copy_fn (stmt);
 	      if (fn)
-		node->add_reference (cgraph_node::get_create (fn),
+		node->create_reference (cgraph_node::get_create (fn),
 					IPA_REF_ADDR, stmt);
 	    }
 	}
@@ -404,7 +403,7 @@  record_references_in_initializer (tree decl, bool only_vars)
 {
   varpool_node *node = varpool_node::get_create (decl);
   hash_set<tree> visited_nodes;
-  struct record_reference_ctx ctx = {false, NULL};
+  record_reference_ctx ctx = {false, NULL};
 
   ctx.varpool_node = node;
   ctx.only_vars = only_vars;
@@ -416,10 +415,10 @@  record_references_in_initializer (tree decl, bool only_vars)
    passes that don't update the cgraph.  */
 
 unsigned int
-rebuild_cgraph_edges (void)
+cgraph_edge::rebuild_edges (void)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node::get (current_function_decl);
+  cgraph_node *node = cgraph_node::get (current_function_decl);
   gimple_stmt_iterator gsi;
 
   node->remove_callees ();
@@ -460,16 +459,16 @@  rebuild_cgraph_edges (void)
   return 0;
 }
 
-/* Rebuild cgraph edges for current function node.  This needs to be run after
-   passes that don't update the cgraph.  */
+/* Rebuild cgraph references for current function node.  This needs to be run
+   after passes that don't update the cgraph.  */
 
 void
-cgraph_rebuild_references (void)
+cgraph_edge::rebuild_references (void)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node::get (current_function_decl);
+  cgraph_node *node = cgraph_node::get (current_function_decl);
   gimple_stmt_iterator gsi;
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
   int i;
 
   /* Keep speculative references for further cgraph edge expansion.  */
@@ -515,7 +514,10 @@  public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_rebuild_cgraph_edges (m_ctxt); }
-  virtual unsigned int execute (function *) { return rebuild_cgraph_edges (); }
+  virtual unsigned int execute (function *)
+  {
+    return cgraph_edge::rebuild_edges ();
+  }
 
 }; // class pass_rebuild_cgraph_edges
 
@@ -561,7 +563,7 @@  public:
 unsigned int
 pass_remove_cgraph_callee_edges::execute (function *)
 {
-  struct cgraph_node *node = cgraph_node::get (current_function_decl);
+  cgraph_node *node = cgraph_node::get (current_function_decl);
   node->remove_callees ();
   node->remove_all_references ();
   return 0;
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 557f734..eb04418 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -102,69 +102,70 @@  along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "except.h"
 
-/* Create clone of E in the node N represented by CALL_EXPR the callgraph.  */
-struct cgraph_edge *
-cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
-		   gimple call_stmt, unsigned stmt_uid, gcov_type count_scale,
-		   int freq_scale, bool update_original)
+/* Create clone of edge in the node N represented by CALL_EXPR
+   the callgraph.  */
+
+cgraph_edge *
+cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
+		    gcov_type count_scale, int freq_scale, bool update_original)
 {
-  struct cgraph_edge *new_edge;
-  gcov_type count = apply_probability (e->count, count_scale);
+  cgraph_edge *new_edge;
+  gcov_type gcov_count = apply_probability (count, count_scale);
   gcov_type freq;
 
   /* We do not want to ignore loop nest after frequency drops to 0.  */
   if (!freq_scale)
     freq_scale = 1;
-  freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
+  freq = frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE;
   if (freq > CGRAPH_FREQ_MAX)
     freq = CGRAPH_FREQ_MAX;
 
-  if (e->indirect_unknown_callee)
+  if (indirect_unknown_callee)
     {
       tree decl;
 
       if (call_stmt && (decl = gimple_call_fndecl (call_stmt))
 	  /* When the call is speculative, we need to resolve it 
 	     via cgraph_resolve_speculation and not here.  */
-	  && !e->speculative)
+	  && !speculative)
 	{
-	  struct cgraph_node *callee = cgraph_node::get (decl);
+	  cgraph_node *callee = cgraph_node::get (decl);
 	  gcc_checking_assert (callee);
-	  new_edge = n->create_edge (callee, call_stmt, count, freq);
+	  new_edge = n->create_edge (callee, call_stmt, gcov_count, freq);
 	}
       else
 	{
 	  new_edge = n->create_indirect_edge (call_stmt,
-					      e->indirect_info->ecf_flags,
+					      indirect_info->ecf_flags,
 					      count, freq, false);
-	  *new_edge->indirect_info = *e->indirect_info;
+	  *new_edge->indirect_info = *indirect_info;
 	}
     }
   else
     {
-      new_edge = n->create_edge (e->callee, call_stmt, count, freq);
-      if (e->indirect_info)
+      new_edge = n->create_edge (callee, call_stmt, gcov_count, freq);
+      if (indirect_info)
 	{
 	  new_edge->indirect_info
 	    = ggc_cleared_alloc<cgraph_indirect_call_info> ();
-	  *new_edge->indirect_info = *e->indirect_info;
+	  *new_edge->indirect_info = *indirect_info;
 	}
     }
 
-  new_edge->inline_failed = e->inline_failed;
-  new_edge->indirect_inlining_edge = e->indirect_inlining_edge;
+  new_edge->inline_failed = inline_failed;
+  new_edge->indirect_inlining_edge = indirect_inlining_edge;
   new_edge->lto_stmt_uid = stmt_uid;
   /* Clone flags that depend on call_stmt availability manually.  */
-  new_edge->can_throw_external = e->can_throw_external;
-  new_edge->call_stmt_cannot_inline_p = e->call_stmt_cannot_inline_p;
-  new_edge->speculative = e->speculative;
+  new_edge->can_throw_external = can_throw_external;
+  new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
+  new_edge->speculative = speculative;
   if (update_original)
     {
-      e->count -= new_edge->count;
-      if (e->count < 0)
-	e->count = 0;
+      count -= new_edge->count;
+      if (count < 0)
+	count = 0;
     }
-  cgraph_call_edge_duplication_hooks (e, new_edge);
+  symtab->call_edge_duplication_hooks (this, new_edge);
   return new_edge;
 }
 
@@ -309,7 +310,7 @@  duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
   if (thunk_of->thunk.thunk_p)
     node = duplicate_thunk_for_node (thunk_of, node);
 
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   for (cs = node->callers; cs; cs = cs->next_caller)
     if (cs->caller->thunk.thunk_p
 	&& cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting
@@ -350,13 +351,14 @@  duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
   new_thunk->clone.args_to_skip = node->clone.args_to_skip;
   new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip;
 
-  struct cgraph_edge *e = new_thunk->create_edge (node, NULL, 0,
+  cgraph_edge *e = new_thunk->create_edge (node, NULL, 0,
 						  CGRAPH_FREQ_BASE);
   e->call_stmt_cannot_inline_p = true;
-  cgraph_call_edge_duplication_hooks (thunk->callees, e);
+  symtab->call_edge_duplication_hooks (thunk->callees, e);
   if (!new_thunk->expand_thunk (false, false))
     new_thunk->analyzed = true;
-  thunk->call_duplication_hooks (new_thunk);
+
+  symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
   return new_thunk;
 }
 
@@ -365,13 +367,13 @@  duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
    chain.  */
 
 void
-redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n)
+redirect_edge_duplicating_thunks (cgraph_edge *e, cgraph_node *n)
 {
   cgraph_node *orig_to = e->callee->ultimate_alias_target ();
   if (orig_to->thunk.thunk_p)
     n = duplicate_thunk_for_node (orig_to, n);
 
-  cgraph_redirect_edge_callee (e, n);
+  e->redirect_callee (n);
 }
 
 /* Create node representing clone of N executed COUNT times.  Decrease
@@ -395,11 +397,11 @@  cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq,
 			   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)
 {
-  struct cgraph_node *new_node = cgraph_node::create_empty ();
-  struct cgraph_edge *e;
+  cgraph_node *new_node = symtab->create_empty ();
+  cgraph_edge *e;
   gcov_type count_scale;
   unsigned i;
 
@@ -466,12 +468,12 @@  cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq,
     }
 
   for (e = callees;e; e=e->next_callee)
-    cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
-		       count_scale, freq, update_original);
+    e->clone (new_node, e->call_stmt, e->lto_stmt_uid, count_scale,
+	      freq, update_original);
 
   for (e = indirect_calls; e; e = e->next_callee)
-    cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
-		       count_scale, freq, update_original);
+    e->clone (new_node, e->call_stmt, e->lto_stmt_uid,
+	      count_scale, freq, update_original);
   new_node->clone_references (this);
 
   new_node->next_sibling_clone = clones;
@@ -481,7 +483,7 @@  cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq,
   new_node->clone_of = this;
 
   if (call_duplication_hook)
-    call_duplication_hooks (new_node);
+    symtab->call_cgraph_duplication_hooks (this, new_node);
   return new_node;
 }
 
@@ -516,16 +518,16 @@  clone_function_name (tree decl, const char *suffix)
    TODO: after merging in ipa-sra use function call notes instead of args_to_skip
    bitmap interface.
    */
-struct cgraph_node *
+cgraph_node *
 cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
 				   vec<ipa_replace_map *, va_gc> *tree_map,
 				   bitmap args_to_skip, const char * suffix)
 {
   tree old_decl = decl;
-  struct cgraph_node *new_node = NULL;
+  cgraph_node *new_node = NULL;
   tree new_decl;
   size_t len, i;
-  struct ipa_replace_map *map;
+  ipa_replace_map *map;
   char *name;
 
   if (!in_lto_p)
@@ -578,13 +580,13 @@  cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
       || in_lto_p)
     new_node->unique_name = true;
   FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
-    new_node->maybe_add_reference (map->new_tree, IPA_REF_ADDR, NULL);
+    new_node->maybe_create_reference (map->new_tree, IPA_REF_ADDR, NULL);
 
   if (ipa_transforms_to_apply.exists ())
     new_node->ipa_transforms_to_apply
       = ipa_transforms_to_apply.copy ();
 
-  call_duplication_hooks (new_node);
+  symtab->call_cgraph_duplication_hooks (this, new_node);
 
   return new_node;
 }
@@ -594,7 +596,7 @@  cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
 cgraph_node *
 cgraph_node::find_replacement (void)
 {
-  struct cgraph_node *next_inline_clone, *replacement;
+  cgraph_node *next_inline_clone, *replacement;
 
   for (next_inline_clone = clones;
        next_inline_clone
@@ -607,8 +609,8 @@  cgraph_node::find_replacement (void)
      other clones to be based on it.  */
   if (next_inline_clone)
     {
-      struct cgraph_node *n;
-      struct cgraph_node *new_clones;
+      cgraph_node *n;
+      cgraph_node *new_clones;
 
       replacement = next_inline_clone;
 
@@ -684,30 +686,30 @@  void
 cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt,
 					     bool update_speculative)
 {
-  struct cgraph_node *node;
-  struct cgraph_edge *edge = get_edge (old_stmt);
+  cgraph_node *node;
+  cgraph_edge *edge = get_edge (old_stmt);
 
   if (edge)
-    cgraph_set_call_stmt (edge, new_stmt, update_speculative);
+    edge->set_call_stmt (new_stmt, update_speculative);
 
   node = clones;
   if (node)
     while (node != this)
       {
-	struct cgraph_edge *edge = node->get_edge (old_stmt);
+	cgraph_edge *edge = node->get_edge (old_stmt);
 	if (edge)
 	  {
-	    cgraph_set_call_stmt (edge, new_stmt, update_speculative);
+	    edge->set_call_stmt (new_stmt, update_speculative);
 	    /* If UPDATE_SPECULATIVE is false, it means that we are turning
 	       speculative call into a real code sequence.  Update the
 	       callgraph edges.  */
 	    if (edge->speculative && !update_speculative)
 	      {
-		struct cgraph_edge *direct, *indirect;
-		struct ipa_ref *ref;
+		cgraph_edge *direct, *indirect;
+		ipa_ref *ref;
 
 		gcc_assert (!edge->indirect_unknown_callee);
-		cgraph_speculative_call_info (edge, direct, indirect, ref);
+		edge->speculative_call_info (direct, indirect, ref);
 		direct->speculative = false;
 		indirect->speculative = false;
 		ref->speculative = false;
@@ -735,14 +737,14 @@  cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt,
    frequencies of the clones.  */
 
 void
-cgraph_node::create_edge_including_clones (struct cgraph_node *callee,
+cgraph_node::create_edge_including_clones (cgraph_node *callee,
 					   gimple old_stmt, gimple stmt,
 					   gcov_type count,
 					   int freq,
 					   cgraph_inline_failed_t reason)
 {
-  struct cgraph_node *node;
-  struct cgraph_edge *edge;
+  cgraph_node *node;
+  cgraph_edge *edge;
 
   if (!get_edge (stmt))
     {
@@ -754,14 +756,14 @@  cgraph_node::create_edge_including_clones (struct cgraph_node *callee,
   if (node)
     while (node != this)
       {
-	struct cgraph_edge *edge = node->get_edge (old_stmt);
+	cgraph_edge *edge = node->get_edge (old_stmt);
 
         /* It is possible that clones already contain the edge while
 	   master didn't.  Either we promoted indirect call into direct
 	   call in the clone or we are processing clones of unreachable
 	   master where edges has been removed.  */
 	if (edge)
-	  cgraph_set_call_stmt (edge, stmt);
+	  edge->set_call_stmt (stmt);
 	else if (! node->get_edge (stmt))
 	  {
 	    edge = node->create_edge (callee, stmt, count, freq);
@@ -790,12 +792,12 @@  cgraph_node::create_edge_including_clones (struct cgraph_node *callee,
 bool
 cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
 {
-  struct cgraph_edge *e, *next;
+  cgraph_edge *e, *next;
   bool found = false;
 
   if (this == forbidden_node)
     {
-      cgraph_remove_edge (callers);
+      callers->remove ();
       return true;
     }
   for (e = callees; e; e = next)
@@ -813,16 +815,16 @@  cgraph_node::remove_symbol_and_inline_clones (cgraph_node *forbidden_node)
    respective tree code should be updated to call the NEW_VERSION.  */
 
 static void
-update_call_expr (struct cgraph_node *new_version)
+update_call_expr (cgraph_node *new_version)
 {
-  struct cgraph_edge *e;
+  cgraph_edge *e;
 
   gcc_assert (new_version);
 
   /* Update the call expr on the edges to call the new version.  */
   for (e = new_version->callers; e; e = e->next_caller)
     {
-      struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
+      function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
       gimple_call_set_fndecl (e->call_stmt, new_version->decl);
       maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
     }
@@ -845,8 +847,8 @@  cgraph_node::create_version_clone (tree new_decl,
 				  vec<cgraph_edge *> redirect_callers,
 				  bitmap bbs_to_copy)
  {
-   struct cgraph_node *new_version;
-   struct cgraph_edge *e;
+   cgraph_node *new_version;
+   cgraph_edge *e;
    unsigned i;
 
    new_version = cgraph_node::create (new_decl);
@@ -863,25 +865,25 @@  cgraph_node::create_version_clone (tree new_decl,
    for (e = callees; e; e=e->next_callee)
      if (!bbs_to_copy
 	 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
-       cgraph_clone_edge (e, new_version, e->call_stmt,
-			  e->lto_stmt_uid, REG_BR_PROB_BASE,
-			  CGRAPH_FREQ_BASE,
-			  true);
+       e->clone (new_version, e->call_stmt,
+		 e->lto_stmt_uid, REG_BR_PROB_BASE,
+		 CGRAPH_FREQ_BASE,
+		 true);
    for (e = indirect_calls; e; e=e->next_callee)
      if (!bbs_to_copy
 	 || bitmap_bit_p (bbs_to_copy, gimple_bb (e->call_stmt)->index))
-       cgraph_clone_edge (e, new_version, e->call_stmt,
-			  e->lto_stmt_uid, REG_BR_PROB_BASE,
-			  CGRAPH_FREQ_BASE,
-			  true);
+       e->clone (new_version, e->call_stmt,
+		 e->lto_stmt_uid, REG_BR_PROB_BASE,
+		 CGRAPH_FREQ_BASE,
+		 true);
    FOR_EACH_VEC_ELT (redirect_callers, i, e)
      {
        /* Redirect calls to the old version node to point to its new
 	  version.  */
-       cgraph_redirect_edge_callee (e, new_version);
+       e->redirect_callee (new_version);
      }
 
-   call_duplication_hooks (new_version);
+   symtab->call_cgraph_duplication_hooks (this, new_version);
 
    return new_version;
  }
@@ -913,7 +915,7 @@  cgraph_node::create_version_clone_with_body
    const char *clone_name)
 {
   tree old_decl = decl;
-  struct cgraph_node *new_version_node = NULL;
+  cgraph_node *new_version_node = NULL;
   tree new_decl;
 
   if (!tree_versionable_function_p (old_decl))
@@ -970,14 +972,14 @@  cgraph_node::create_version_clone_with_body
   /* Update the call_expr on the edges to call the new version node. */
   update_call_expr (new_version_node);
 
-  new_version_node->call_function_insertion_hooks ();
+  symtab->call_cgraph_insertion_hooks (this);
   return new_version_node;
 }
 
 /* Given virtual clone, turn it into actual clone.  */
 
 static void
-cgraph_materialize_clone (struct cgraph_node *node)
+cgraph_materialize_clone (cgraph_node *node)
 {
   bitmap_obstack_initialize (NULL);
   node->former_clone_of = node->clone_of->decl;
@@ -988,10 +990,11 @@  cgraph_materialize_clone (struct cgraph_node *node)
   			    node->clone.tree_map, true,
 			    node->clone.args_to_skip, false,
 			    NULL, NULL);
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      dump_function_to_file (node->clone_of->decl, cgraph_dump_file, dump_flags);
-      dump_function_to_file (node->decl, cgraph_dump_file, dump_flags);
+      dump_function_to_file (node->clone_of->decl, symtab->dump_file,
+			     dump_flags);
+      dump_function_to_file (node->decl, symtab->dump_file, dump_flags);
     }
 
   /* Function is no longer clone.  */
@@ -1020,14 +1023,14 @@  cgraph_materialize_clone (struct cgraph_node *node)
    this order.  */
 
 void
-cgraph_materialize_all_clones (void)
+symbol_table::materialize_all_clones (void)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
   bool stabilized = false;
   
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Materializing clones\n");
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file, "Materializing clones\n");
 #ifdef ENABLE_CHECKING
   cgraph_node::verify_cgraph_nodes ();
 #endif
@@ -1047,39 +1050,40 @@  cgraph_materialize_all_clones (void)
 		node->clone_of->get_body ();
 	      if (gimple_has_body_p (node->clone_of->decl))
 	        {
-		  if (cgraph_dump_file)
+		  if (symtab->dump_file)
 		    {
-		      fprintf (cgraph_dump_file, "cloning %s to %s\n",
+		      fprintf (symtab->dump_file, "cloning %s to %s\n",
 			       xstrdup (node->clone_of->name ()),
 			       xstrdup (node->name ()));
 		      if (node->clone.tree_map)
 		        {
 			  unsigned int i;
-		          fprintf (cgraph_dump_file, "   replace map: ");
+			  fprintf (symtab->dump_file, "   replace map: ");
 			  for (i = 0;
 			       i < vec_safe_length (node->clone.tree_map);
 			       i++)
 			    {
-			      struct ipa_replace_map *replace_info;
+			      ipa_replace_map *replace_info;
 			      replace_info = (*node->clone.tree_map)[i];
-			      print_generic_expr (cgraph_dump_file, replace_info->old_tree, 0);
-			      fprintf (cgraph_dump_file, " -> ");
-			      print_generic_expr (cgraph_dump_file, replace_info->new_tree, 0);
-			      fprintf (cgraph_dump_file, "%s%s;",
+			      print_generic_expr (symtab->dump_file, replace_info->old_tree, 0);
+			      fprintf (symtab->dump_file, " -> ");
+			      print_generic_expr (symtab->dump_file, replace_info->new_tree, 0);
+			      fprintf (symtab->dump_file, "%s%s;",
 			      	       replace_info->replace_p ? "(replace)":"",
 				       replace_info->ref_p ? "(ref)":"");
 			    }
-			  fprintf (cgraph_dump_file, "\n");
+			  fprintf (symtab->dump_file, "\n");
 			}
 		      if (node->clone.args_to_skip)
 			{
-		          fprintf (cgraph_dump_file, "   args_to_skip: ");
-		          dump_bitmap (cgraph_dump_file, node->clone.args_to_skip);
+			  fprintf (symtab->dump_file, "   args_to_skip: ");
+			  dump_bitmap (symtab->dump_file,
+				       node->clone.args_to_skip);
 			}
 		      if (node->clone.args_to_skip)
 			{
-		          fprintf (cgraph_dump_file, "   combined_args_to_skip:");
-		          dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
+			  fprintf (symtab->dump_file, "   combined_args_to_skip:");
+			  dump_bitmap (symtab->dump_file, node->clone.combined_args_to_skip);
 			}
 		    }
 		  cgraph_materialize_clone (node);
@@ -1096,12 +1100,12 @@  cgraph_materialize_all_clones (void)
       }
     else
       node->clear_stmts_in_references ();
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file, "Materialization Call site updates done.\n");
 #ifdef ENABLE_CHECKING
   cgraph_node::verify_cgraph_nodes ();
 #endif
-  symtab_remove_unreachable_nodes (false, cgraph_dump_file);
+  symtab->remove_unreachable_nodes (false, symtab->dump_file);
 }
 
 #include "gt-cgraphclones.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0bbe9f6..3444ddc 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -25,7 +25,7 @@  along with GCC; see the file COPYING3.  If not see
 
    The front-end is supposed to use following functionality:
 
-    - cgraph_finalize_function
+    - finalize_function
 
       This function is called once front-end has parsed whole body of function
       and it is certain that the function body nor the declaration will change.
@@ -219,45 +219,34 @@  vec<cgraph_node *> cgraph_new_nodes;
 
 static void expand_all_functions (void);
 static void mark_functions_to_output (void);
-static void expand_function (struct cgraph_node *);
 static void handle_alias_pairs (void);
 
-FILE *cgraph_dump_file;
-
-/* Linked list of cgraph asm nodes.  */
-struct asm_node *asm_nodes;
-
-/* Last node in cgraph_asm_nodes.  */
-static GTY(()) struct asm_node *asm_last_node;
-
 /* Used for vtable lookup in thunk adjusting.  */
 static GTY (()) tree vtable_entry_type;
 
-/* Determine if symbol DECL is needed.  That is, visible to something
+/* Determine if symbol declaration is needed.  That is, visible to something
    either outside this translation unit, something magic in the system
    configury */
 bool
-decide_is_symbol_needed (symtab_node *node)
+symtab_node::needed_p (void)
 {
-  tree decl = node->decl;
-
   /* Double check that no one output the function into assembly file
      early.  */
   gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
 	               || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
 
-  if (!node->definition)
+  if (!definition)
     return false;
 
   if (DECL_EXTERNAL (decl))
     return false;
 
   /* If the user told us it is used, then it must be so.  */
-  if (node->force_output)
+  if (force_output)
     return true;
 
   /* ABI forced symbols are needed when they are external.  */
-  if (node->forced_by_abi && TREE_PUBLIC (decl))
+  if (forced_by_abi && TREE_PUBLIC (decl))
     return true;
 
  /* Keep constructors, destructors and virtual functions.  */
@@ -297,7 +286,7 @@  enqueue_node (symtab_node *node)
    functions inserted into callgraph already at construction time.  */
 
 void
-cgraph_process_new_functions (void)
+symbol_table::process_new_functions (void)
 {
   tree fndecl;
 
@@ -311,19 +300,19 @@  cgraph_process_new_functions (void)
     {
       cgraph_node *node = cgraph_new_nodes[i];
       fndecl = node->decl;
-      switch (cgraph_state)
+      switch (state)
 	{
-	case CGRAPH_STATE_CONSTRUCTION:
+	case CONSTRUCTION:
 	  /* At construction time we just need to finalize function and move
 	     it into reachable functions list.  */
 
-	  cgraph_finalize_function (fndecl, false);
-	  node->call_function_insertion_hooks ();
+	  cgraph_node::finalize_function (fndecl, false);
+	  call_cgraph_insertion_hooks (node);
 	  enqueue_node (node);
 	  break;
 
-	case CGRAPH_STATE_IPA:
-	case CGRAPH_STATE_IPA_SSA:
+	case IPA:
+	case IPA_SSA:
 	  /* When IPA optimization already started, do all essential
 	     transformations that has been already performed on the whole
 	     cgraph but not on this function.  */
@@ -332,7 +321,7 @@  cgraph_process_new_functions (void)
 	  if (!node->analyzed)
 	    node->analyze ();
 	  push_cfun (DECL_STRUCT_FUNCTION (fndecl));
-	  if (cgraph_state == CGRAPH_STATE_IPA_SSA
+	  if (state == IPA_SSA
 	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
 	    g->get_passes ()->execute_early_local_passes ();
 	  else if (inline_summary_vec != NULL)
@@ -340,15 +329,14 @@  cgraph_process_new_functions (void)
 	  free_dominance_info (CDI_POST_DOMINATORS);
 	  free_dominance_info (CDI_DOMINATORS);
 	  pop_cfun ();
-	  node->call_function_insertion_hooks ();
 	  break;
 
-	case CGRAPH_STATE_EXPANSION:
+	case EXPANSION:
 	  /* Functions created during expansion shall be compiled
 	     directly.  */
 	  node->process = 0;
-	  node->call_function_insertion_hooks ();
-	  expand_function (node);
+	  call_cgraph_insertion_hooks (node);
+	  node->expand ();
 	  break;
 
 	default:
@@ -394,18 +382,18 @@  cgraph_node::reset (void)
   remove_all_references ();
 }
 
-/* Return true when there are references to NODE.  */
+/* Return true when there are references to the node.  */
 
-static bool
-referred_to_p (symtab_node *node)
+bool
+symtab_node::referred_to_p (void)
 {
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
 
   /* See if there are any references at all.  */
-  if (node->iterate_referring (0, ref))
+  if (iterate_referring (0, ref))
     return true;
   /* For functions check also calls.  */
-  cgraph_node *cn = dyn_cast <cgraph_node *> (node);
+  cgraph_node *cn = dyn_cast <cgraph_node *> (this);
   if (cn && cn->callers)
     return true;
   return false;
@@ -417,9 +405,9 @@  referred_to_p (symtab_node *node)
    a new GC context, or just not compile right now.  */
 
 void
-cgraph_finalize_function (tree decl, bool no_collect)
+cgraph_node::finalize_function (tree decl, bool no_collect)
 {
-  struct cgraph_node *node = cgraph_node::get_create (decl);
+  cgraph_node *node = cgraph_node::get_create (decl);
 
   if (node->definition)
     {
@@ -467,14 +455,13 @@  cgraph_finalize_function (tree decl, bool no_collect)
   if (!no_collect)
     ggc_collect ();
 
-  if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
-      && (decide_is_symbol_needed (node)
-	  || referred_to_p (node)))
+  if (symtab->state == CONSTRUCTION
+      && (node->needed_p () || node->referred_to_p ()))
     enqueue_node (node);
 }
 
 /* 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.
@@ -489,13 +476,13 @@  void
 cgraph_node::add_new_function (tree fndecl, bool lowered)
 {
   gcc::pass_manager *passes = g->get_passes ();
-  struct cgraph_node *node;
-  switch (cgraph_state)
+  cgraph_node *node;
+  switch (symtab->state)
     {
-      case CGRAPH_STATE_PARSING:
-	cgraph_finalize_function (fndecl, false);
+      case PARSING:
+	cgraph_node::finalize_function (fndecl, false);
 	break;
-      case CGRAPH_STATE_CONSTRUCTION:
+      case CONSTRUCTION:
 	/* Just enqueue function to be processed at nearest occurrence.  */
 	node = cgraph_node::get_create (fndecl);
 	if (lowered)
@@ -503,16 +490,16 @@  cgraph_node::add_new_function (tree fndecl, bool lowered)
 	cgraph_new_nodes.safe_push (node);
         break;
 
-      case CGRAPH_STATE_IPA:
-      case CGRAPH_STATE_IPA_SSA:
-      case CGRAPH_STATE_EXPANSION:
+      case IPA:
+      case IPA_SSA:
+      case EXPANSION:
 	/* Bring the function into finalized state and enqueue for later
 	   analyzing and compilation.  */
 	node = cgraph_node::get_create (fndecl);
 	node->local.local = false;
 	node->definition = true;
 	node->force_output = true;
-	if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
+	if (!lowered && symtab->state == EXPANSION)
 	  {
 	    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
 	    gimple_register_cfg_hooks ();
@@ -529,7 +516,7 @@  cgraph_node::add_new_function (tree fndecl, bool lowered)
 	cgraph_new_nodes.safe_push (node);
         break;
 
-      case CGRAPH_STATE_FINISHED:
+      case FINISHED:
 	/* At the very end of compilation we have to do all the work up
 	   to expansion.  */
 	node = cgraph_node::create (fndecl);
@@ -544,7 +531,7 @@  cgraph_node::add_new_function (tree fndecl, bool lowered)
 	  g->get_passes ()->execute_early_local_passes ();
 	bitmap_obstack_release (NULL);
 	pop_cfun ();
-	expand_function (node);
+	node->expand ();
 	break;
 
       default:
@@ -558,38 +545,20 @@  cgraph_node::add_new_function (tree fndecl, bool lowered)
     DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
 }
 
-/* Add a top-level asm statement to the list.  */
-
-struct asm_node *
-add_asm_node (tree asm_str)
-{
-  struct asm_node *node;
-
-  node = ggc_cleared_alloc<asm_node> ();
-  node->asm_str = asm_str;
-  node->order = symtab_order++;
-  node->next = NULL;
-  if (asm_nodes == NULL)
-    asm_nodes = node;
-  else
-    asm_last_node->next = node;
-  asm_last_node = node;
-  return node;
-}
-
 /* Output all asm statements we have stored up to be output.  */
 
-static void
-output_asm_statements (void)
+void
+symbol_table::output_asm_statements (void)
 {
-  struct asm_node *can;
+  asm_node *can;
 
   if (seen_error ())
     return;
 
-  for (can = asm_nodes; can; can = can->next)
+  for (can = first_asm_symbol (); can; can = can->next)
     assemble_asm (can->asm_str);
-  asm_nodes = NULL;
+
+  clear_asm_symbols ();
 }
 
 /* Analyze the function scheduled to be output.  */
@@ -617,7 +586,7 @@  cgraph_node::analyze (void)
   else if (dispatcher_function)
     {
       /* Generate the dispatcher body of multi-versioned functions.  */
-      struct cgraph_function_version_info *dispatcher_version_info
+      cgraph_function_version_info *dispatcher_version_info
 	= function_version ();
       if (dispatcher_version_info != NULL
           && (dispatcher_version_info->dispatcher_resolver
@@ -674,7 +643,7 @@  cgraph_node::analyze (void)
    PCH we build the links via this function.  */
 
 void
-cgraph_process_same_body_aliases (void)
+symbol_table::process_same_body_aliases (void)
 {
   symtab_node *node;
   FOR_EACH_SYMBOL (node)
@@ -718,7 +687,7 @@  process_common_attributes (tree decl)
    declaration -- but the front end will subsequently merge that declaration
    with the original declaration and discard the second declaration.
 
-   Furthermore, we can't mark these nodes in cgraph_finalize_function because:
+   Furthermore, we can't mark these nodes in finalize_function because:
 
     void f() {}
     void f() __attribute__((externally_visible));
@@ -729,14 +698,14 @@  process_common_attributes (tree decl)
    attributes at that point.  */
 
 static void
-process_function_and_variable_attributes (struct cgraph_node *first,
+process_function_and_variable_attributes (cgraph_node *first,
                                           varpool_node *first_var)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
   varpool_node *vnode;
 
-  for (node = cgraph_first_function (); node != first;
-       node = cgraph_next_function (node))
+  for (node = symtab->first_function (); node != first;
+       node = symtab->next_function (node))
     {
       tree decl = node->decl;
       if (DECL_PRESERVE_P (decl))
@@ -768,8 +737,8 @@  process_function_and_variable_attributes (struct cgraph_node *first,
      
       process_common_attributes (decl);
     }
-  for (vnode = varpool_first_variable (); vnode != first_var;
-       vnode = varpool_next_variable (vnode))
+  for (vnode = symtab->first_variable (); vnode != first_var;
+       vnode = symtab->next_variable (vnode))
     {
       tree decl = vnode->decl;
       if (DECL_EXTERNAL (decl)
@@ -821,16 +790,16 @@  varpool_node::finalize_decl (tree decl)
 	  && !DECL_ARTIFICIAL (node->decl)))
     node->force_output = true;
 
-  if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
-      && (decide_is_symbol_needed (node)
-	  || referred_to_p (node)))
+  if (symtab->state == CONSTRUCTION
+      && (node->needed_p () || node->referred_to_p ()))
     enqueue_node (node);
-  if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
+  if (symtab->state >= IPA_SSA)
     node->analyze ();
   /* Some frontends produce various interface variables after compilation
      finished.  */
-  if (cgraph_state == CGRAPH_STATE_FINISHED
-      || (!flag_toplevel_reorder && cgraph_state == CGRAPH_STATE_EXPANSION))
+  if (symtab->state == FINISHED
+      || (!flag_toplevel_reorder
+	&& symtab->state == EXPANSION))
     node->assemble_decl ();
 }
 
@@ -841,7 +810,7 @@  varpool_node::finalize_decl (tree decl)
 
 static void
 walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
-			       struct cgraph_edge *edge)
+			       cgraph_edge *edge)
 {
   unsigned int i;
   void *cache_token;
@@ -852,9 +821,9 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
 
   if (!reachable_call_targets->add (cache_token))
     {
-      if (cgraph_dump_file)
+      if (symtab->dump_file)
 	dump_possible_polymorphic_call_targets 
-	  (cgraph_dump_file, edge);
+	  (symtab->dump_file, edge);
 
       for (i = 0; i < targets.length (); i++)
 	{
@@ -887,11 +856,11 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
 	    target = cgraph_node::create
 			(builtin_decl_implicit (BUILT_IN_UNREACHABLE));
 
-	  if (cgraph_dump_file)
+	  if (symtab->dump_file)
 	    {
-	      fprintf (cgraph_dump_file,
+	      fprintf (symtab->dump_file,
 		       "Devirtualizing call: ");
-	      print_gimple_stmt (cgraph_dump_file,
+	      print_gimple_stmt (symtab->dump_file,
 				 edge->call_stmt, 0,
 				 TDF_SLIM);
 	    }
@@ -903,13 +872,13 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
 			       edge->caller->name (), target->name ());
 	    }
 
-	  cgraph_make_edge_direct (edge, target);
-	  cgraph_redirect_edge_call_stmt_to_callee (edge);
-	  if (cgraph_dump_file)
+	  edge->make_direct (target);
+	  edge->redirect_call_stmt_to_callee ();
+	  if (symtab->dump_file)
 	    {
-	      fprintf (cgraph_dump_file,
+	      fprintf (symtab->dump_file,
 		       "Devirtualized as: ");
-	      print_gimple_stmt (cgraph_dump_file,
+	      print_gimple_stmt (symtab->dump_file,
 				 edge->call_stmt, 0,
 				 TDF_SLIM);
 	    }
@@ -926,8 +895,8 @@  analyze_functions (void)
 {
   /* Keep track of already processed nodes when called multiple times for
      intermodule optimization.  */
-  static struct cgraph_node *first_analyzed;
-  struct cgraph_node *first_handled = first_analyzed;
+  static cgraph_node *first_analyzed;
+  cgraph_node *first_handled = first_analyzed;
   static varpool_node *first_analyzed_var;
   varpool_node *first_handled_var = first_analyzed_var;
   hash_set<void *> reachable_call_targets;
@@ -935,17 +904,17 @@  analyze_functions (void)
   symtab_node *node;
   symtab_node *next;
   int i;
-  struct ipa_ref *ref;
+  ipa_ref *ref;
   bool changed = true;
   location_t saved_loc = input_location;
 
   bitmap_obstack_initialize (NULL);
-  cgraph_state = CGRAPH_STATE_CONSTRUCTION;
+  symtab->state = CONSTRUCTION;
   input_location = UNKNOWN_LOCATION;
 
   /* Ugly, but the fixup can not happen at a time same body alias is created;
      C++ FE is confused about the COMDAT groups being right.  */
-  if (cpp_implicit_aliases_done)
+  if (symtab->cpp_implicit_aliases_done)
     FOR_EACH_SYMBOL (node)
       if (node->cpp_implicit_alias)
 	  node->fixup_same_cpp_alias_visibility (node->get_alias_target ());
@@ -961,33 +930,33 @@  analyze_functions (void)
 						first_analyzed_var);
 
       /* First identify the trivially needed symbols.  */
-      for (node = symtab_nodes;
+      for (node = symtab->first_symbol ();
 	   node != first_analyzed
 	   && node != first_analyzed_var; node = node->next)
 	{
 	  /* Convert COMDAT group designators to IDENTIFIER_NODEs.  */
 	  node->get_comdat_group_id ();
-	  if (decide_is_symbol_needed (node))
+	  if (node->needed_p ())
 	    {
 	      enqueue_node (node);
-	      if (!changed && cgraph_dump_file)
-		fprintf (cgraph_dump_file, "Trivially needed symbols:");
+	      if (!changed && symtab->dump_file)
+		fprintf (symtab->dump_file, "Trivially needed symbols:");
 	      changed = true;
-	      if (cgraph_dump_file)
-		fprintf (cgraph_dump_file, " %s", node->asm_name ());
-	      if (!changed && cgraph_dump_file)
-		fprintf (cgraph_dump_file, "\n");
+	      if (symtab->dump_file)
+		fprintf (symtab->dump_file, " %s", node->asm_name ());
+	      if (!changed && symtab->dump_file)
+		fprintf (symtab->dump_file, "\n");
 	    }
 	  if (node == first_analyzed
 	      || node == first_analyzed_var)
 	    break;
 	}
-      cgraph_process_new_functions ();
-      first_analyzed_var = varpool_first_variable ();
-      first_analyzed = cgraph_first_function ();
+      symtab->process_new_functions ();
+      first_analyzed_var = symtab->first_variable ();
+      first_analyzed = symtab->first_function ();
 
-      if (changed && cgraph_dump_file)
-	fprintf (cgraph_dump_file, "\n");
+      if (changed && symtab->dump_file)
+	fprintf (symtab->dump_file, "\n");
 
       /* Lower representation, build callgraph edges and references for all trivially
          needed symbols and all symbols referred by them.  */
@@ -999,7 +968,7 @@  analyze_functions (void)
 	  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
 	  if (cnode && cnode->definition)
 	    {
-	      struct cgraph_edge *edge;
+	      cgraph_edge *edge;
 	      tree decl = cnode->decl;
 
 	      /* ??? It is possible to create extern inline function
@@ -1023,7 +992,7 @@  analyze_functions (void)
 		   enqueue_node (edge->callee);
 	      if (optimize && flag_devirtualize)
 		{
-		  struct cgraph_edge *next;
+		  cgraph_edge *next;
 
 		  for (edge = cnode->indirect_calls; edge; edge = next)
 		    {
@@ -1040,7 +1009,7 @@  analyze_functions (void)
 	      will be later needed to output debug info.  */
 	      if (DECL_ABSTRACT_ORIGIN (decl))
 		{
-		  struct cgraph_node *origin_node
+		  cgraph_node *origin_node
 		    = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl));
 		  origin_node->used_as_abstract_origin = true;
 		}
@@ -1063,31 +1032,31 @@  analyze_functions (void)
 	  for (i = 0; node->iterate_reference (i, ref); i++)
 	    if (ref->referred->definition)
 	      enqueue_node (ref->referred);
-          cgraph_process_new_functions ();
+	  symtab->process_new_functions ();
 	}
     }
   if (optimize && flag_devirtualize)
     update_type_inheritance_graph ();
 
   /* Collect entry points to the unit.  */
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "\n\nInitial ");
-      symtab_node::dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "\n\nInitial ");
+      symtab_node::dump_table (symtab->dump_file);
     }
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "\nRemoving unused symbols:");
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file, "\nRemoving unused symbols:");
 
-  for (node = symtab_nodes;
+  for (node = symtab->first_symbol ();
        node != first_handled
        && node != first_handled_var; node = next)
     {
       next = node->next;
-      if (!node->aux && !referred_to_p (node))
+      if (!node->aux && !node->referred_to_p ())
 	{
-	  if (cgraph_dump_file)
-	    fprintf (cgraph_dump_file, " %s", node->name ());
+	  if (symtab->dump_file)
+	    fprintf (symtab->dump_file, " %s", node->name ());
 	  node->remove ();
 	  continue;
 	}
@@ -1109,12 +1078,12 @@  analyze_functions (void)
     }
   for (;node; node = node->next)
     node->aux = NULL;
-  first_analyzed = cgraph_first_function ();
-  first_analyzed_var = varpool_first_variable ();
-  if (cgraph_dump_file)
+  first_analyzed = symtab->first_function ();
+  first_analyzed_var = symtab->first_variable ();
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "\n\nReclaimed ");
-      symtab_node::dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "\n\nReclaimed ");
+      symtab_node::dump_table (symtab->dump_file);
     }
   bitmap_obstack_release (NULL);
   ggc_collect ();
@@ -1122,7 +1091,7 @@  analyze_functions (void)
      mangling and same body alias creation before we free DECL_ARGUMENTS
      used by it.  */
   if (!seen_error ())
-    symtab_initialize_asm_name_hash ();
+    symtab->symtab_initialize_asm_name_hash ();
 
   input_location = saved_loc;
 }
@@ -1139,7 +1108,7 @@  handle_alias_pairs (void)
   
   for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
     {
-      symtab_node *target_node = symtab_node_for_asm (p->target);
+      symtab_node *target_node = symtab_node::get_for_asmname (p->target);
 
       /* Weakrefs with target not defined in current unit are easy to handle:
 	 they behave just as external variables except we need to note the
@@ -1182,7 +1151,7 @@  handle_alias_pairs (void)
       if (TREE_CODE (p->decl) == FUNCTION_DECL
           && target_node && is_a <cgraph_node *> (target_node))
 	{
-	  struct cgraph_node *src_node = cgraph_node::get (p->decl);
+	  cgraph_node *src_node = cgraph_node::get (p->decl);
 	  if (src_node && src_node->definition)
 	    src_node->reset ();
 	  cgraph_node::create_alias (p->decl, target_node->decl);
@@ -1212,7 +1181,7 @@  handle_alias_pairs (void)
 static void
 mark_functions_to_output (void)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 #ifdef ENABLE_CHECKING
   bool check_same_comdat_groups = false;
 
@@ -1241,7 +1210,7 @@  mark_functions_to_output (void)
 	  node->process = 1;
 	  if (node->same_comdat_group)
 	    {
-	      struct cgraph_node *next;
+	      cgraph_node *next;
 	      for (next = dyn_cast<cgraph_node *> (node->same_comdat_group);
 		   next != node;
 		   next = dyn_cast<cgraph_node *> (next->same_comdat_group))
@@ -1696,62 +1665,61 @@  cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
   return true;
 }
 
-/* Assemble thunks and aliases associated to NODE.  */
+/* Assemble thunks and aliases associated to node.  */
 
-static void
-assemble_thunks_and_aliases (struct cgraph_node *node)
+void
+cgraph_node::assemble_thunks_and_aliases (void)
 {
-  struct cgraph_edge *e;
-  struct ipa_ref *ref;
+  cgraph_edge *e;
+  ipa_ref *ref;
 
-  for (e = node->callers; e;)
+  for (e = callers; e;)
     if (e->caller->thunk.thunk_p)
       {
-	struct cgraph_node *thunk = e->caller;
+	cgraph_node *thunk = e->caller;
 
 	e = e->next_caller;
 	thunk->expand_thunk (true, false);
-	assemble_thunks_and_aliases (thunk);
+	thunk->assemble_thunks_and_aliases ();
       }
     else
       e = e->next_caller;
 
-  FOR_EACH_ALIAS (node, ref)
+  FOR_EACH_ALIAS (this, ref)
     {
-      struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
-      bool saved_written = TREE_ASM_WRITTEN (node->decl);
+      cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+      bool saved_written = TREE_ASM_WRITTEN (decl);
 
       /* Force assemble_alias to really output the alias this time instead
 	 of buffering it in same alias pairs.  */
-      TREE_ASM_WRITTEN (node->decl) = 1;
+      TREE_ASM_WRITTEN (decl) = 1;
       do_assemble_alias (alias->decl,
-			 DECL_ASSEMBLER_NAME (node->decl));
-      assemble_thunks_and_aliases (alias);
-      TREE_ASM_WRITTEN (node->decl) = saved_written;
+			 DECL_ASSEMBLER_NAME (decl));
+      alias->assemble_thunks_and_aliases ();
+      TREE_ASM_WRITTEN (decl) = saved_written;
     }
 }
 
-/* Expand function specified by NODE.  */
+/* Expand function specified by node.  */
 
-static void
-expand_function (struct cgraph_node *node)
+void
+cgraph_node::expand (void)
 {
-  tree decl = node->decl;
   location_t saved_loc;
 
   /* We ought to not compile any inline clones.  */
-  gcc_assert (!node->global.inlined_to);
+  gcc_assert (!global.inlined_to);
 
   announce_function (decl);
-  node->process = 0;
-  gcc_assert (node->lowered);
-  node->get_body ();
+  process = 0;
+  gcc_assert (lowered);
+  get_body ();
 
   /* Generate RTL for the body of DECL.  */
 
   timevar_push (TV_REST_OF_COMPILATION);
 
-  gcc_assert (cgraph_global_info_ready);
+  gcc_assert (symtab->global_info_ready);
 
   /* Initialize the default bitmap obstack.  */
   bitmap_obstack_initialize (NULL);
@@ -1836,12 +1804,12 @@  expand_function (struct cgraph_node *node)
      make one pass assemblers, like one on AIX, happy.  See PR 50689.
      FIXME: Perhaps thunks should be move before function IFF they are not in comdat
      groups.  */
-  assemble_thunks_and_aliases (node);
-  node->release_body ();
+  assemble_thunks_and_aliases ();
+  release_body ();
   /* Eliminate all call edges.  This is important so the GIMPLE_CALL no longer
      points to the dead function body.  */
-  node->remove_callees ();
-  node->remove_all_references ();
+  remove_callees ();
+  remove_all_references ();
 }
 
 /* Node comparer that is responsible for the order that corresponds
@@ -1850,8 +1818,8 @@  expand_function (struct cgraph_node *node)
 static int
 node_cmp (const void *pa, const void *pb)
 {
-  const struct cgraph_node *a = *(const struct cgraph_node * const *) pa;
-  const struct cgraph_node *b = *(const struct cgraph_node * const *) pb;
+  const cgraph_node *a = *(const cgraph_node * const *) pa;
+  const cgraph_node *b = *(const cgraph_node * const *) pb;
 
   /* Functions with time profile must be before these without profile.  */
   if (!a->tp_first_run || !b->tp_first_run)
@@ -1875,14 +1843,15 @@  node_cmp (const void *pa, const void *pb)
 static void
 expand_all_functions (void)
 {
-  struct cgraph_node *node;
-  struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  cgraph_node *node;
+  cgraph_node **order = XCNEWVEC (cgraph_node *,
+					 symtab->cgraph_count);
   unsigned int expanded_func_count = 0, profiled_func_count = 0;
   int order_pos, new_order_pos = 0;
   int i;
 
   order_pos = ipa_reverse_postorder (order);
-  gcc_assert (order_pos == cgraph_n_nodes);
+  gcc_assert (order_pos == symtab->cgraph_count);
 
   /* Garbage collector may remove inline clones we eliminate during
      optimization.  So we must be sure to not reference them.  */
@@ -1891,7 +1860,7 @@  expand_all_functions (void)
       order[new_order_pos++] = order[i];
 
   if (flag_profile_reorder_functions)
-    qsort (order, new_order_pos, sizeof (struct cgraph_node *), node_cmp);
+    qsort (order, new_order_pos, sizeof (cgraph_node *), node_cmp);
 
   for (i = new_order_pos - 1; i >= 0; i--)
     {
@@ -1903,11 +1872,12 @@  expand_all_functions (void)
      if(node->tp_first_run)
        profiled_func_count++;
 
-    if (cgraph_dump_file)
-      fprintf (cgraph_dump_file, "Time profile order in expand_all_functions:%s:%d\n", node->asm_name (), node->tp_first_run);
-
+    if (symtab->dump_file)
+	  fprintf (symtab->dump_file,
+		   "Time profile order in expand_all_functions:%s:%d\n",
+		   node->asm_name (), node->tp_first_run);
 	  node->process = 0;
-	  expand_function (node);
+	  node->expand ();
 	}
     }
 
@@ -1915,11 +1885,11 @@  expand_all_functions (void)
       fprintf (dump_file, "Expanded functions with time profile (%s):%u/%u\n",
                main_input_filename, profiled_func_count, expanded_func_count);
 
-  if (cgraph_dump_file && flag_profile_reorder_functions)
-    fprintf (cgraph_dump_file, "Expanded functions with time profile:%u/%u\n",
+  if (symtab->dump_file && flag_profile_reorder_functions)
+    fprintf (symtab->dump_file, "Expanded functions with time profile:%u/%u\n",
              profiled_func_count, expanded_func_count);
 
-  cgraph_process_new_functions ();
+  symtab->process_new_functions ();
   free_gimplify_stack ();
 
   free (order);
@@ -1940,9 +1910,9 @@  struct cgraph_order_sort
   enum cgraph_order_sort_kind kind;
   union
   {
-    struct cgraph_node *f;
+    cgraph_node *f;
     varpool_node *v;
-    struct asm_node *a;
+    asm_node *a;
   } u;
 };
 
@@ -1956,14 +1926,13 @@  static void
 output_in_order (void)
 {
   int max;
-  struct cgraph_order_sort *nodes;
+  cgraph_order_sort *nodes;
   int i;
-  struct cgraph_node *pf;
+  cgraph_node *pf;
   varpool_node *pv;
-  struct asm_node *pa;
-
-  max = symtab_order;
-  nodes = XCNEWVEC (struct cgraph_order_sort, max);
+  asm_node *pa;
+  max = symtab->order;
+  nodes = XCNEWVEC (cgraph_order_sort, max);
 
   FOR_EACH_DEFINED_FUNCTION (pf)
     {
@@ -1985,7 +1954,7 @@  output_in_order (void)
 	nodes[i].u.v = pv;
       }
 
-  for (pa = asm_nodes; pa; pa = pa->next)
+  for (pa = symtab->first_asm_symbol (); pa; pa = pa->next)
     {
       i = pa->order;
       gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
@@ -2005,7 +1974,7 @@  output_in_order (void)
 	{
 	case ORDER_FUNCTION:
 	  nodes[i].u.f->process = 0;
-	  expand_function (nodes[i].u.f);
+	  nodes[i].u.f->expand ();
 	  break;
 
 	case ORDER_VAR:
@@ -2024,7 +1993,8 @@  output_in_order (void)
 	}
     }
 
-  asm_nodes = NULL;
+  symtab->clear_asm_symbols ();
+
   free (nodes);
 }
 
@@ -2049,12 +2019,12 @@  ipa_passes (void)
 
   /* This extra symtab_remove_unreachable_nodes pass tends to catch some
      devirtualization and other changes where removal iterate.  */
-  symtab_remove_unreachable_nodes (true, cgraph_dump_file);
+  symtab->remove_unreachable_nodes (true, symtab->dump_file);
 
   /* If pass_all_early_optimizations was not scheduled, the state of
      the cgraph will not be properly updated.  Update it now.  */
-  if (cgraph_state < CGRAPH_STATE_IPA_SSA)
-    cgraph_state = CGRAPH_STATE_IPA_SSA;
+  if (symtab->state < IPA_SSA)
+    symtab->state = IPA_SSA;
 
   if (!in_lto_p)
     {
@@ -2064,7 +2034,7 @@  ipa_passes (void)
       /* Process new functions added.  */
       set_cfun (NULL);
       current_function_decl = NULL;
-      cgraph_process_new_functions ();
+      symtab->process_new_functions ();
 
       execute_ipa_summary_passes
 	((ipa_opt_pass_d *) passes->all_regular_ipa_passes);
@@ -2102,8 +2072,8 @@  get_alias_symbol (tree decl)
 /* Weakrefs may be associated to external decls and thus not output
    at expansion time.  Emit all necessary aliases.  */
 
-static void
-output_weakrefs (void)
+void
+symbol_table::output_weakrefs (void)
 {
   symtab_node *node;
   FOR_EACH_SYMBOL (node)
@@ -2133,20 +2103,10 @@  output_weakrefs (void)
       }
 }
 
-/* Initialize callgraph dump file.  */
-
-void
-init_cgraph (void)
-{
-  if (!cgraph_dump_file)
-    cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
-}
-
-
 /* Perform simple optimizations based on callgraph.  */
 
 void
-compile (void)
+symbol_table::compile (void)
 {
   if (seen_error ())
     return;
@@ -2163,7 +2123,7 @@  compile (void)
     }
   if (!quiet_flag)
     fprintf (stderr, "Performing interprocedural optimizations\n");
-  cgraph_state = CGRAPH_STATE_IPA;
+  symtab->state = IPA;
 
   /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
   if (flag_lto)
@@ -2184,12 +2144,12 @@  compile (void)
   /* This pass remove bodies of extern inline functions we never inlined.
      Do this later so other IPA passes see what is really going on.
      FIXME: This should be run just after inlining by pasmanager.  */
-  symtab_remove_unreachable_nodes (false, dump_file);
-  cgraph_global_info_ready = true;
-  if (cgraph_dump_file)
+  symtab->remove_unreachable_nodes (false, dump_file);
+  symtab->global_info_ready = true;
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Optimized ");
-      symtab_node:: dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "Optimized ");
+      symtab_node:: dump_table (symtab->dump_file);
     }
   if (post_ipa_mem_report)
     {
@@ -2206,7 +2166,7 @@  compile (void)
   symtab_node::verify_symtab_nodes ();
 #endif
 
-  cgraph_materialize_all_clones ();
+  symtab->materialize_all_clones ();
   bitmap_obstack_initialize (NULL);
   execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
   bitmap_obstack_release (NULL);
@@ -2238,26 +2198,26 @@  compile (void)
       }
 #endif
 
-  cgraph_state = CGRAPH_STATE_EXPANSION;
+  symtab->state = EXPANSION;
 
   if (!flag_toplevel_reorder)
     output_in_order ();
   else
     {
-      output_asm_statements ();
+      symtab->output_asm_statements ();
 
       expand_all_functions ();
-      varpool_node::output_variables ();
+      symtab->output_variables ();
     }
 
-  cgraph_process_new_functions ();
-  cgraph_state = CGRAPH_STATE_FINISHED;
-  output_weakrefs ();
+  symtab->process_new_functions ();
+  symtab->state = FINISHED;
+  symtab->output_weakrefs ();
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "\nFinal ");
-      symtab_node::dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "\nFinal ");
+      symtab_node::dump_table (symtab->dump_file);
     }
 #ifdef ENABLE_CHECKING
   symtab_node::verify_symtab_nodes ();
@@ -2265,7 +2225,7 @@  compile (void)
      function bodies have been released from memory.  */
   if (!seen_error ())
     {
-      struct cgraph_node *node;
+      cgraph_node *node;
       bool error_found = false;
 
       FOR_EACH_DEFINED_FUNCTION (node)
@@ -2285,7 +2245,7 @@  compile (void)
 /* Analyze the whole compilation unit once it is parsed completely.  */
 
 void
-finalize_compilation_unit (void)
+symbol_table::finalize_compilation_unit (void)
 {
   timevar_push (TV_CGRAPH);
 
@@ -2332,7 +2292,7 @@  finalize_compilation_unit (void)
    kind of wrapper method.  */
 
 void
-cgraph_node::create_wrapper (struct cgraph_node *target)
+cgraph_node::create_wrapper (cgraph_node *target)
 {
     /* Preserve DECL_RESULT so we get right by reference flag.  */
     tree decl_result = DECL_RESULT (decl);
@@ -2351,7 +2311,7 @@  cgraph_node::create_wrapper (struct cgraph_node *target)
     thunk.thunk_p = true;
     thunk.this_adjusting = false;
 
-    struct cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
+    cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
 
     if (!expand_thunk (false, true))
       analyzed = true;
diff --git a/gcc/combine.c b/gcc/combine.c
index 64142c9..1a768d5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1548,7 +1548,7 @@  setup_incoming_promotions (rtx_insn *first)
          function lie within the current compilation unit.  (This does
 	 take into account the exporting of a function via taking its
 	 address, and so forth.)  */
-      strictly_local = cgraph_local_info (current_function_decl)->local;
+      strictly_local = cgraph_node::local_info (current_function_decl)->local;
 
       /* The mode and signedness of the argument before any promotions happen
          (equal to the mode of the pseudo holding it at that stage).  */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 858f0d7..7a82a9b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -5135,7 +5135,7 @@  arm_get_pcs_model (const_tree type, const_tree decl)
 	     so we are free to use whatever conventions are
 	     appropriate.  */
 	  /* FIXME: remove CONST_CAST_TREE when cgraph is constified.  */
-	  struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
+	  cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl));
 	  if (i && i->local)
 	    return ARM_PCS_AAPCS_LOCAL;
 	}
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 07edad2..59456a8 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -1045,7 +1045,7 @@  bfin_load_pic_reg (rtx dest)
   struct cgraph_local_info *i = NULL;
   rtx addr;
  
-  i = cgraph_local_info (current_function_decl);
+  i = cgraph_node::local_info (current_function_decl);
  
   /* Functions local to the translation unit don't need to reload the
      pic reg, since the caller always passes a usable one.  */
@@ -1839,8 +1839,8 @@  bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
     /* Not enough information.  */
     return false;
  
-  this_func = cgraph_local_info (current_function_decl);
-  called_func = cgraph_local_info (decl);
+  this_func = cgraph_node::local_info (current_function_decl);
+  called_func = cgraph_node::local_info (decl);
   if (!called_func)
     return false;
   return !called_func->local || this_func->local;
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 9998734..aaea6c0 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -1177,7 +1177,7 @@  c6x_function_ok_for_sibcall (tree decl, tree exp)
 	/* Not enough information.  */
 	return false;
 
-      this_func = cgraph_local_info (current_function_decl);
+      this_func = cgraph_node::local_info (current_function_decl);
       return this_func->local;
     }
 
@@ -2540,7 +2540,7 @@  must_reload_pic_reg_p (void)
   if (!TARGET_DSBT)
     return false;
 
-  i = cgraph_local_info (current_function_decl);
+  i = cgraph_node::local_info (current_function_decl);
 
   if ((crtl->uses_pic_offset_table || !crtl->is_leaf) && !i->local)
     return true;
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 787c3fc..cef1198 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -2578,7 +2578,7 @@  cris_legitimate_pic_operand (rtx x)
 void 
 cris_asm_output_ident (const char *string)
 {
-  if (cgraph_state != CGRAPH_STATE_PARSING)
+  if (symtab->state != PARSING)
     return;
 
   default_asm_output_ident_directive (string);
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index c5aa83e..12b1ea8 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -859,7 +859,7 @@  enum cris_symbol_type
 /* We don't want an .ident for gcc.  To avoid that but still support
    #ident, we override TARGET_ASM_OUTPUT_IDENT and, since the gcc .ident
    is its only use besides front-end .ident directives, we return if
-   the state if the cgraph is not CGRAPH_STATE_PARSING.  */
+   the state if the cgraph is not PARSING.  */
 #undef TARGET_ASM_OUTPUT_IDENT
 #define TARGET_ASM_OUTPUT_IDENT cris_asm_output_ident
 
diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index 892ba35..9e876cf 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -731,7 +731,7 @@  darwin_objc_declare_unresolved_class_reference (const char *name)
   gcc_checking_assert (!strncmp (name, ".objc_class_name_", 17));
 
   snprintf (buf, len, "%s%s", reference, name);
-  add_asm_node (build_string (strlen (buf), buf));
+  symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
 }
 
 static void
@@ -746,10 +746,10 @@  darwin_objc_declare_class_definition (const char *name)
 
   /* Mimic default_globalize_label.  */
   snprintf (buf, len, ".globl\t%s", xname);
-  add_asm_node (build_string (strlen (buf), buf));
+  symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
 
   snprintf (buf, len, "%s = 0", xname);
-  add_asm_node (build_string (strlen (buf), buf));
+  symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
 }
 
 #undef  TARGET_HANDLE_C_OPTION
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3e4c93e..796ba72 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5664,7 +5664,7 @@  ix86_function_regparm (const_tree type, const_tree decl)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE (decl));
+      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE (decl));
       if (i && i->local && i->can_change_signature)
 	{
 	  int local_regparm, globals = 0, regno;
@@ -5741,7 +5741,7 @@  ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
+      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl));
       if (i && i->local && i->can_change_signature)
 	return TARGET_SSE2 ? 2 : 1;
     }
@@ -6150,7 +6150,7 @@  init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
 
   if (fndecl)
     {
-      i = cgraph_local_info (fndecl);
+      i = cgraph_node::local_info (fndecl);
       cum->call_abi = ix86_function_abi (fndecl);
     }
   else
@@ -32231,7 +32231,7 @@  make_resolver_func (const tree default_decl,
   *empty_bb = init_lowered_empty_function (decl, false);
 
   cgraph_node::add_new_function (decl, true);
-  cgraph_node::get_create (decl)->call_function_insertion_hooks ();
+  symtab->call_cgraph_insertion_hooks (cgraph_node::get_create (decl));
 
   pop_cfun ();
 
@@ -32304,7 +32304,7 @@  ix86_generate_version_dispatcher_body (void *node_p)
     }
 
   dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
-  rebuild_cgraph_edges (); 
+  cgraph_edge::rebuild_edges ();
   pop_cfun ();
   return resolver_decl;
 }
@@ -32493,7 +32493,7 @@  fold_builtin_cpu (tree fndecl, tree *args)
 					"__cpu_model");
 
 
-  varpool_add_new_variable (__cpu_model_var);
+  varpool_node::add (__cpu_model_var);
 
   gcc_assert ((args != NULL) && (*args != NULL));
 
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 3ae61db..ee18e26 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -3350,7 +3350,7 @@  microblaze_asm_output_ident (const char *string)
   int size;
   char *buf;
 
-  if (cgraph_state != CGRAPH_STATE_PARSING)
+  if (symtab->state != PARSING)
     return;
 
   size = strlen (string) + 1;
@@ -3360,7 +3360,7 @@  microblaze_asm_output_ident (const char *string)
     section_asm_op = READONLY_DATA_SECTION_ASM_OP;
 
   buf = ACONCAT ((section_asm_op, "\n\t.ascii \"", string, "\\0\"\n", NULL));
-  add_asm_node (build_string (strlen (buf), buf));
+  symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
 }
 
 static void
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 34f975d..d936cb0 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -1090,8 +1090,8 @@  coverage_obj_init (void)
   if (!prg_ctr_mask)
     return false;
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name);
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file, "Using data file %s\n", da_file_name);
 
   /* Prune functions.  */
   for (fn_prev = &functions_head; (fn = *fn_prev);)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 74a10fb..3df6442 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4316,7 +4316,7 @@  cp_write_global_declarations (void)
       return;
     }
 
-  cgraph_process_same_body_aliases ();
+  symtab->process_same_body_aliases ();
 
   /* Handle -fdump-ada-spec[-slim] */
   if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
@@ -4659,7 +4659,7 @@  cp_write_global_declarations (void)
       vtv_build_vtable_verify_fndecl ();
     }
 
-  finalize_compilation_unit ();
+  symtab->finalize_compilation_unit ();
 
   if (flag_vtable_verify)
     {
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f0beb42..ad99cab 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16619,7 +16619,7 @@  cp_parser_asm_definition (cp_parser* parser)
 	    }
 	}
       else
-	add_asm_node (string);
+	symtab->finalize_toplevel_asm (string);
     }
 }
 
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a54011f..16abad0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4056,7 +4056,7 @@  expand_or_defer_fn (tree fn)
       function_depth++;
 
       /* Expand or defer, at the whim of the compilation unit manager.  */
-      cgraph_finalize_function (fn, function_depth > 1);
+      cgraph_node::finalize_function (fn, function_depth > 1);
       emit_associated_thunks (fn);
 
       function_depth--;
diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c
index 2c10fd3..54c5dd3 100644
--- a/gcc/cp/vtable-class-hierarchy.c
+++ b/gcc/cp/vtable-class-hierarchy.c
@@ -1188,7 +1188,7 @@  vtv_generate_init_routine (void)
       gimplify_function_tree (vtv_fndecl);
       cgraph_node::add_new_function (vtv_fndecl, false);
 
-      cgraph_process_new_functions ();
+      symtab->process_new_functions ();
 
       if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
         assemble_vtv_preinit_initializer (vtv_fndecl);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c50d8b8..1a9e50a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15344,7 +15344,7 @@  reference_to_unused (tree * tp, int * walk_subtrees,
   /* ???  The C++ FE emits debug information for using decls, so
      putting gcc_unreachable here falls over.  See PR31899.  For now
      be conservative.  */
-  else if (!cgraph_global_info_ready
+  else if (!symtab->global_info_ready
 	   && (TREE_CODE (*tp) == VAR_DECL || TREE_CODE (*tp) == FUNCTION_DECL))
     return *tp;
   else if (TREE_CODE (*tp) == VAR_DECL)
diff --git a/gcc/final.c b/gcc/final.c
index 3208220..8cef83d 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4697,8 +4697,8 @@  rest_of_clean_state (void)
       unsigned int pref = crtl->preferred_stack_boundary;
       if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
         pref = crtl->stack_alignment_needed;
-      cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
-        = pref;
+      cgraph_node::rtl_info (current_function_decl)
+	->preferred_incoming_stack_boundary = pref;
     }
 
   /* Make sure volatile mem refs aren't considered valid operands for
@@ -4820,7 +4820,7 @@  collect_fn_hard_reg_usage (void)
   if (hard_reg_set_subset_p (call_used_reg_set, function_used_regs))
     return;
 
-  node = cgraph_rtl_info (current_function_decl);
+  node = cgraph_node::rtl_info (current_function_decl);
   gcc_assert (node != NULL);
 
   COPY_HARD_REG_SET (node->function_used_regs, function_used_regs);
@@ -4861,7 +4861,7 @@  get_call_cgraph_rtl_info (rtx_insn *insn)
       || !decl_binds_to_current_def_p (fndecl))
     return NULL;
 
-  return cgraph_rtl_info (fndecl);
+  return cgraph_node::rtl_info (fndecl);
 }
 
 /* Find hard registers used by function call instruction INSN, and return them
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 25ab419..3063fea 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2565,7 +2565,7 @@  build_entry_thunks (gfc_namespace * ns, bool global)
 
       current_function_decl = NULL_TREE;
 
-      cgraph_finalize_function (thunk_fndecl, true);
+      cgraph_node::finalize_function (thunk_fndecl, true);
 
       /* We share the symbols in the formal argument list with other entry
 	 points and the master function.  Clear them so that they are
@@ -4817,7 +4817,7 @@  generate_coarray_init (gfc_namespace * ns __attribute((unused)))
   if (decl_function_context (fndecl))
     (void) cgraph_node::create (fndecl);
   else
-    cgraph_finalize_function (fndecl, true);
+    cgraph_node::finalize_function (fndecl, true);
 
   pop_function_context ();
   current_function_decl = save_fn_decl;
@@ -5529,7 +5529,7 @@  create_main_function (tree fndecl)
   /* Output the GENERIC tree.  */
   dump_function (TDI_original, ftn_main);
 
-  cgraph_finalize_function (ftn_main, true);
+  cgraph_node::finalize_function (ftn_main, true);
 
   if (old_context)
     {
@@ -5911,7 +5911,7 @@  gfc_generate_function_code (gfc_namespace * ns)
 	(void) cgraph_node::create (fndecl);
     }
   else
-    cgraph_finalize_function (fndecl, true);
+    cgraph_node::finalize_function (fndecl, true);
 
   gfc_trans_use_stmts (ns);
   gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
diff --git a/gcc/gcc-symtab.h b/gcc/gcc-symtab.h
deleted file mode 100644
index e253561..0000000
--- a/gcc/gcc-symtab.h
+++ /dev/null
@@ -1,28 +0,0 @@ 
-/* Declarations for symtab.c.
-   FIXME - This file should be named symtab.h, but that name conflicts
-           with libcpp's symtab.h.
-
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
-
-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/>.  */
-
-#ifndef GCC_SYMTAB_H
-#define GCC_SYMTAB_H
-
-extern void change_decl_assembler_name (tree, tree);
-
-#endif  // GCC_SYMTAB_H
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 3c03c01..f4fe65b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -98,7 +98,7 @@  can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
     {
       /* Before we start optimizing unreachable code we can be sure all
 	 static objects are defined.  */
-      if (cgraph_function_flags_ready)
+      if (symtab->function_flags_ready)
 	return true;
       snode = symtab_node::get (decl);
       if (!snode || !snode->definition)
@@ -143,7 +143,7 @@  can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
      units where they are used and when the other unit was compiled with LTO
      it is possible that vtable was kept public while the function itself
      was privatized. */
-  if (!cgraph_function_flags_ready)
+  if (!symtab->function_flags_ready)
     return true;
 
   snode = symtab_node::get (decl);
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index a34fad8..059706e 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -2914,7 +2914,7 @@  Gcc_backend::write_global_definitions(
         {
           go_preserve_from_gc(decl);
           gimplify_function_tree(decl);
-          cgraph_finalize_function(decl, true);
+          cgraph_node::finalize_function(decl, true);
 
           defs[i] = decl;
           ++i;
@@ -2925,7 +2925,7 @@  Gcc_backend::write_global_definitions(
 
   wrapup_global_declarations(defs, i);
 
-  finalize_compilation_unit();
+  symtab->finalize_compilation_unit();
 
   check_global_declarations(defs, i);
   emit_debug_global_declarations(defs, i);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 8d3d6ed..44d4c9a 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -498,7 +498,7 @@  gather_caller_stats (struct cgraph_node *node, void *data)
 	stats->count_sum += cs->count;
 	stats->freq_sum += cs->frequency;
 	stats->n_calls++;
-	if (cgraph_maybe_hot_edge_p (cs))
+	if (cs->maybe_hot_p ())
 	  stats->n_hot_calls ++;
       }
   return false;
@@ -585,8 +585,9 @@  struct topo_info
 static void
 build_toporder_info (struct topo_info *topo)
 {
-  topo->order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
-  topo->stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
+  topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
+
   topo->stack_top = 0;
   topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL);
 }
@@ -2284,7 +2285,7 @@  propagate_effects (void)
       for (val = base; val; val = val->scc_next)
 	for (src = val->sources; src; src = src->next)
 	  if (src->val
-	      && cgraph_maybe_hot_edge_p (src->cs))
+	      && src->cs->maybe_hot_p ())
 	    {
 	      src->val->prop_time_benefit = safe_add (time,
 						src->val->prop_time_benefit);
@@ -2415,11 +2416,11 @@  static inline void
 grow_edge_clone_vectors (void)
 {
   if (next_edge_clone.length ()
-      <=  (unsigned) cgraph_edge_max_uid)
-    next_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1);
+      <=  (unsigned) symtab->edges_max_uid)
+    next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (prev_edge_clone.length ()
-      <=  (unsigned) cgraph_edge_max_uid)
-    prev_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1);
+      <=  (unsigned) symtab->edges_max_uid)
+    prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
 }
 
 /* Edge duplication hook to grow the appropriate linked list in
@@ -2555,7 +2556,7 @@  get_info_about_necessary_edges (struct ipcp_value *val, int *freq_sum,
 	      count++;
 	      freq += cs->frequency;
 	      cnt += cs->count;
-	      hot |= cgraph_maybe_hot_edge_p (cs);
+	      hot |= cs->maybe_hot_p ();
 	    }
 	  cs = get_next_cgraph_edge_clone (cs);
 	}
@@ -2805,7 +2806,7 @@  create_specialized_node (struct cgraph_node *node,
 					 args_to_skip, "constprop");
   ipa_set_node_agg_value_chain (new_node, aggvals);
   for (av = aggvals; av; av = av->next)
-    new_node->maybe_add_reference (av->value, IPA_REF_ADDR, NULL);
+    new_node->maybe_create_reference (av->value, IPA_REF_ADDR, NULL);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -3366,7 +3367,7 @@  perhaps_add_new_callers (struct cgraph_node *node, struct ipcp_value *val)
 			     xstrdup (val->spec_node->name ()),
 			     val->spec_node->order);
 
-		  cgraph_redirect_edge_callee (cs, val->spec_node);
+		  cs->redirect_callee (val->spec_node);
 		  redirected_sum += cs->count;
 		}
 	    }
@@ -3687,9 +3688,9 @@  ipcp_driver (void)
   ipa_check_create_edge_args ();
   grow_edge_clone_vectors ();
   edge_duplication_hook_holder =
-    cgraph_add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
+    symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
   edge_removal_hook_holder =
-    cgraph_add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
+    symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
 
   ipcp_values_pool = create_alloc_pool ("IPA-CP values",
 					sizeof (struct ipcp_value), 32);
@@ -3716,8 +3717,8 @@  ipcp_driver (void)
   /* Free all IPCP structures.  */
   free_toporder_info (&topo);
   next_edge_clone.release ();
-  cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
-  cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
+  symtab->remove_edge_removal_hook (edge_removal_hook_holder);
+  symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   ipa_free_all_structures_after_ipa_cp ();
   if (dump_file)
     fprintf (dump_file, "\nIPA constant propagation end\n");
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 2e74ca6..f98a18e 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -217,7 +217,7 @@  static bool
 type_all_ctors_visible_p (tree t)
 {
   return !flag_ltrans
-	 && cgraph_state >= CGRAPH_STATE_CONSTRUCTION
+	 && symtab->state >= CONSTRUCTION
 	 /* We can not always use type_all_derivations_known_p.
 	    For function local types we must assume case where
 	    the function is COMDAT and shared in between units. 
@@ -1085,14 +1085,14 @@  add_type_duplicate (odr_type val, tree type)
 	  merge = false;
 	  odr_violation_reported = true;
 	  val->odr_violated = true;
-	  if (cgraph_dump_file)
+	  if (symtab->dump_file)
 	    {
-	      fprintf (cgraph_dump_file, "ODR violation\n");
+	      fprintf (symtab->dump_file, "ODR violation\n");
 	    
-	      print_node (cgraph_dump_file, "", val->type, 0);
-	      putc ('\n',cgraph_dump_file);
-	      print_node (cgraph_dump_file, "", type, 0);
-	      putc ('\n',cgraph_dump_file);
+	      print_node (symtab->dump_file, "", val->type, 0);
+	      putc ('\n',symtab->dump_file);
+	      print_node (symtab->dump_file, "", type, 0);
+	      putc ('\n',symtab->dump_file);
 	    }
 	}
 
@@ -1125,14 +1125,14 @@  add_type_duplicate (odr_type val, tree type)
 			  "a type with the same name but different bases is "
 			  "defined in another translation unit");
 	      val->odr_violated = true;
-	      if (cgraph_dump_file)
+	      if (symtab->dump_file)
 		{
-		  fprintf (cgraph_dump_file, "ODR bse violation or merging bug?\n");
+		  fprintf (symtab->dump_file, "ODR bse violation or merging bug?\n");
 		
-		  print_node (cgraph_dump_file, "", val->type, 0);
-		  putc ('\n',cgraph_dump_file);
-		  print_node (cgraph_dump_file, "", type, 0);
-		  putc ('\n',cgraph_dump_file);
+		  print_node (symtab->dump_file, "", val->type, 0);
+		  putc ('\n',symtab->dump_file);
+		  print_node (symtab->dump_file, "", type, 0);
+		  putc ('\n',symtab->dump_file);
 		}
 	    }
 	}
@@ -1446,7 +1446,7 @@  referenced_from_vtable_p (struct cgraph_node *node)
     return true;
 
   /* We need references built.  */
-  if (cgraph_state <= CGRAPH_STATE_CONSTRUCTION)
+  if (symtab->state <= CONSTRUCTION)
     return true;
 
   for (i = 0; node->iterate_referring (i, ref); i++)
@@ -3388,8 +3388,8 @@  possible_polymorphic_call_targets (tree otr_type,
       if (!node_removal_hook_holder)
 	{
 	  node_removal_hook_holder =
-	    cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL);
-	  varpool_add_node_removal_hook (&devirt_variable_node_removal_hook,
+	    symtab->add_cgraph_removal_hook (&devirt_node_removal_hook, NULL);
+	  symtab->add_varpool_removal_hook (&devirt_variable_node_removal_hook,
 					 NULL);
 	}
     }
@@ -3866,7 +3866,7 @@  ipa_devirt (void)
 	    if (!flag_devirtualize_speculatively)
 	      continue;
 
-	    if (!cgraph_maybe_hot_edge_p (e))
+	    if (!e->maybe_hot_p ())
 	      {
 		if (dump_file)
 		  fprintf (dump_file, "Call is cold\n\n");
@@ -3917,7 +3917,7 @@  ipa_devirt (void)
 	      {
 		struct cgraph_edge *e2;
 		struct ipa_ref *ref;
-		cgraph_speculative_call_info (e, e2, e, ref);
+		e->speculative_call_info (e2, e, ref);
 		if (e2->callee->ultimate_alias_target ()
 		    == likely_target->ultimate_alias_target ())
 		  {
@@ -3988,8 +3988,8 @@  ipa_devirt (void)
 		  }
 		nconverted++;
 		update = true;
-		cgraph_turn_edge_to_speculative
-		  (e, likely_target, e->count * 8 / 10, e->frequency * 8 / 10);
+		e->make_speculative
+		  (likely_target, e->count * 8 / 10, e->frequency * 8 / 10);
 	      }
 	  }
       if (update)
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 02deeb4..38f56d2 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -758,9 +758,8 @@  edge_set_predicate (struct cgraph_edge *e, struct predicate *predicate)
     {
       struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
 
-      cgraph_redirect_edge_callee (e,
-				   cgraph_node::get_create
-				     (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
+      e->redirect_callee (cgraph_node::get_create
+			    (builtin_decl_implicit (BUILT_IN_UNREACHABLE)));
       e->inline_failed = CIF_UNREACHABLE;
       if (callee)
 	callee->remove_symbol_and_inline_clones ();
@@ -961,21 +960,21 @@  inline_summary_alloc (void)
 {
   if (!node_removal_hook_holder)
     node_removal_hook_holder =
-      cgraph_add_node_removal_hook (&inline_node_removal_hook, NULL);
+      symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
-      cgraph_add_edge_removal_hook (&inline_edge_removal_hook, NULL);
+      symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
   if (!node_duplication_hook_holder)
     node_duplication_hook_holder =
-      cgraph_add_node_duplication_hook (&inline_node_duplication_hook, NULL);
+      symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
-      cgraph_add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
+      symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
 
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) cgraph_max_uid)
-    vec_safe_grow_cleared (inline_summary_vec, cgraph_max_uid + 1);
-  if (inline_edge_summary_vec.length () <= (unsigned) cgraph_edge_max_uid)
-    inline_edge_summary_vec.safe_grow_cleared (cgraph_edge_max_uid + 1);
+  if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
+    vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+  if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
+    inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (!edge_predicate_pool)
     edge_predicate_pool = create_alloc_pool ("edge predicates",
 					     sizeof (struct predicate), 10);
@@ -1291,10 +1290,10 @@  inline_edge_removal_hook (struct cgraph_edge *edge,
 void
 initialize_growth_caches (void)
 {
-  if (cgraph_edge_max_uid)
-    edge_growth_cache.safe_grow_cleared (cgraph_edge_max_uid);
-  if (cgraph_max_uid)
-    node_growth_cache.safe_grow_cleared (cgraph_max_uid);
+  if (symtab->edges_max_uid)
+    edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
+  if (symtab->cgraph_max_uid)
+    node_growth_cache.safe_grow_cleared (symtab->cgraph_max_uid);
 }
 
 
@@ -3019,7 +3018,7 @@  estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
   if (!e->callee
       && estimate_edge_devirt_benefit (e, &call_size, &call_time,
 				       known_vals, known_binfos, known_aggs)
-      && hints && cgraph_maybe_hot_edge_p (e))
+      && hints && e->maybe_hot_p ())
     *hints |= INLINE_HINT_indirect_call;
   cur_size = call_size * INLINE_SIZE_SCALE;
   *size += cur_size;
@@ -3633,7 +3632,7 @@  simple_edge_hints (struct cgraph_edge *edge)
 			    ? edge->caller->global.inlined_to : edge->caller);
   if (inline_summary (to)->scc_no
       && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
-      && !cgraph_edge_recursive_p (edge))
+      && !edge->recursive_p ())
     hints |= INLINE_HINT_same_scc;
 
   if (to->lto_file_data && edge->callee->lto_file_data
@@ -3677,7 +3676,7 @@  do_estimate_edge_time (struct cgraph_edge *edge)
      edges and for those we disable size limits.  Don't do that when
      probability that caller will call the callee is low however, since it
      may hurt optimization of the caller's hot path.  */
-  if (edge->count && cgraph_maybe_hot_edge_p (edge)
+  if (edge->count && edge->maybe_hot_p ()
       && (edge->count * 2
           > (edge->caller->global.inlined_to
 	     ? edge->caller->global.inlined_to->count : edge->caller->count)))
@@ -3694,7 +3693,7 @@  do_estimate_edge_time (struct cgraph_edge *edge)
     {
       inline_summary (edge->callee)->min_size = min_size;
       if ((int) edge_growth_cache.length () <= edge->uid)
-	edge_growth_cache.safe_grow_cleared (cgraph_edge_max_uid);
+	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
       edge_growth_cache[edge->uid].time = time + (time >= 0);
 
       edge_growth_cache[edge->uid].size = size + (size >= 0);
@@ -3888,7 +3887,7 @@  do_estimate_growth (struct cgraph_node *node)
   if (node_growth_cache.exists ())
     {
       if ((int) node_growth_cache.length () <= node->uid)
-	node_growth_cache.safe_grow_cleared (cgraph_max_uid);
+	node_growth_cache.safe_grow_cleared (symtab->cgraph_max_uid);
       node_growth_cache[node->uid] = d.growth + (d.growth >= 0);
     }
   return d.growth;
@@ -4015,7 +4014,7 @@  inline_generate_summary (void)
     return;
 
   function_insertion_hook_holder =
-    cgraph_add_function_insertion_hook (&add_new_function, NULL);
+    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
 
   ipa_register_cgraph_hooks ();
   inline_free_summary ();
@@ -4199,7 +4198,7 @@  inline_read_summary (void)
 	ipa_prop_read_jump_functions ();
     }
   function_insertion_hook_holder =
-    cgraph_add_function_insertion_hook (&add_new_function, NULL);
+    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
 }
 
 
@@ -4332,19 +4331,19 @@  inline_free_summary (void)
     if (!node->alias)
       reset_inline_summary (node);
   if (function_insertion_hook_holder)
-    cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
+    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
   if (node_removal_hook_holder)
-    cgraph_remove_node_removal_hook (node_removal_hook_holder);
+    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
   node_removal_hook_holder = NULL;
   if (edge_removal_hook_holder)
-    cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
+    symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
   if (node_duplication_hook_holder)
-    cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
+    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
   node_duplication_hook_holder = NULL;
   if (edge_duplication_hook_holder)
-    cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
+    symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
   vec_free (inline_summary_vec);
   inline_edge_summary_vec.release ();
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 2ddd029..4b0fcad 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -188,7 +188,7 @@  clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 				       update_original, vNULL, true,
 				       inlining_into,
 				       NULL);
-	  cgraph_redirect_edge_callee (e, n);
+	  e->redirect_callee (n);
 	}
     }
   else
@@ -204,7 +204,7 @@  clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
         clone_inlined_nodes (e, duplicate, update_original, overall_size, freq_scale);
       if (e->speculative && !speculation_useful_p (e, true))
 	{
-	  cgraph_resolve_speculation (e, NULL);
+	  e->resolve_speculation (NULL);
 	  speculation_removed = true;
 	}
     }
@@ -257,7 +257,7 @@  inline_call (struct cgraph_edge *e, bool update_original,
   if (e->callee != callee)
     {
       struct cgraph_node *alias = e->callee, *next_alias;
-      cgraph_redirect_edge_callee (e, callee);
+      e->redirect_callee (callee);
       while (alias && alias != callee)
 	{
 	  if (!alias->callers
@@ -421,7 +421,7 @@  save_inline_function_body (struct cgraph_node *node)
 static bool
 preserve_function_body_p (struct cgraph_node *node)
 {
-  gcc_assert (cgraph_global_info_ready);
+  gcc_assert (symtab->global_info_ready);
   gcc_assert (!node->alias && !node->thunk.thunk_p);
 
   /* Look if there is any clone around.  */
@@ -451,7 +451,7 @@  inline_transform (struct cgraph_node *node)
   for (e = node->callees; e; e = next)
     {
       next = e->next_callee;
-      cgraph_redirect_edge_call_stmt_to_callee (e);
+      e->redirect_call_stmt_to_callee ();
     }
   node->remove_all_references ();
 
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 314262b..d7a232c 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -463,7 +463,7 @@  want_early_inline_function_p (struct cgraph_edge *e)
 
       if (growth <= 0)
 	;
-      else if (!cgraph_maybe_hot_edge_p (e)
+      else if (!e->maybe_hot_p ()
 	       && growth > 0)
 	{
 	  if (dump_file)
@@ -578,7 +578,7 @@  want_inline_small_function_p (struct cgraph_edge *e, bool report)
      promote non-inline function to inline and we increase
      MAX_INLINE_INSNS_SINGLE 16fold for inline functions.  */
   else if ((!DECL_DECLARED_INLINE_P (callee->decl)
-	   && (!e->count || !cgraph_maybe_hot_edge_p (e)))
+	   && (!e->count || !e->maybe_hot_p ()))
 	   && inline_summary (callee)->min_size - inline_edge_summary (e)->call_stmt_size
 	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
@@ -651,7 +651,7 @@  want_inline_small_function_p (struct cgraph_edge *e, bool report)
  	    }
 	}
       /* If call is cold, do not inline when function body would grow. */
-      else if (!cgraph_maybe_hot_edge_p (e)
+      else if (!e->maybe_hot_p ()
 	       && (growth >= MAX_INLINE_INSNS_SINGLE
 		   || growth_likely_positive (callee, growth)))
 	{
@@ -689,7 +689,7 @@  want_inline_self_recursive_call_p (struct cgraph_edge *edge,
   if (DECL_DECLARED_INLINE_P (edge->caller->decl))
     max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
 
-  if (!cgraph_maybe_hot_edge_p (edge))
+  if (!edge->maybe_hot_p ())
     {
       reason = "recursive call is cold";
       want_inline = false;
@@ -797,7 +797,7 @@  check_callers (struct cgraph_node *node, void *has_hot_call)
      {
        if (!can_inline_edge_p (e, true))
          return true;
-       if (!(*(bool *)has_hot_call) && cgraph_maybe_hot_edge_p (e))
+       if (!(*(bool *)has_hot_call) && e->maybe_hot_p ())
 	 *(bool *)has_hot_call = true;
      }
   return false;
@@ -1052,7 +1052,7 @@  edge_badness (struct cgraph_edge *edge, bool dump)
   gcc_assert (badness >= INT_MIN);
   gcc_assert (badness <= INT_MAX - 1);
   /* Make recursive inlining happen always after other inlining is done.  */
-  if (cgraph_edge_recursive_p (edge))
+  if (edge->recursive_p ())
     return badness + 1;
   else
     return badness;
@@ -1342,13 +1342,13 @@  recursive_inlining (struct cgraph_edge *edge,
 	 the already modified body.  */
       if (master_clone)
 	{
-          cgraph_redirect_edge_callee (curr, master_clone);
-          reset_edge_growth_cache (curr);
+	  curr->redirect_callee (master_clone);
+	  reset_edge_growth_cache (curr);
 	}
 
       if (estimate_size_after_inlining (node, curr) > limit)
 	{
-	  cgraph_redirect_edge_callee (curr, dest);
+	  curr->redirect_callee (dest);
 	  reset_edge_growth_cache (curr);
 	  break;
 	}
@@ -1362,7 +1362,7 @@  recursive_inlining (struct cgraph_edge *edge,
 
       if (!want_inline_self_recursive_call_p (curr, node, false, depth))
 	{
-	  cgraph_redirect_edge_callee (curr, dest);
+	  curr->redirect_callee (dest);
 	  reset_edge_growth_cache (curr);
 	  continue;
 	}
@@ -1387,7 +1387,7 @@  recursive_inlining (struct cgraph_edge *edge,
 	  for (e = master_clone->callees; e; e = e->next_callee)
 	    if (!e->inline_failed)
 	      clone_inlined_nodes (e, true, false, NULL, CGRAPH_FREQ_BASE);
-          cgraph_redirect_edge_callee (curr, master_clone);
+	  curr->redirect_callee (master_clone);
           reset_edge_growth_cache (curr);
 	}
 
@@ -1413,10 +1413,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_first_function (); node != master_clone;
+  for (node = symtab->first_function (); node != master_clone;
        node = next)
     {
-      next = cgraph_next_function (node);
+      next = symtab->next_function (node);
       if (node->global.inlined_to == master_clone)
 	node->remove ();
     }
@@ -1485,7 +1485,7 @@  speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
 
   gcc_assert (e->speculative && !e->indirect_unknown_callee);
 
-  if (!cgraph_maybe_hot_edge_p (e))
+  if (!e->maybe_hot_p ())
     return false;
 
   /* See if IP optimizations found something potentially useful about the
@@ -1496,13 +1496,13 @@  speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
       int ecf_flags = flags_from_decl_or_type (target->decl);
       if (ecf_flags & ECF_CONST)
         {
-          cgraph_speculative_call_info (e, direct, indirect, ref);
+	  e->speculative_call_info (direct, indirect, ref);
 	  if (!(indirect->indirect_info->ecf_flags & ECF_CONST))
 	    return true;
         }
       else if (ecf_flags & ECF_PURE)
         {
-          cgraph_speculative_call_info (e, direct, indirect, ref);
+	  e->speculative_call_info (direct, indirect, ref);
 	  if (!(indirect->indirect_info->ecf_flags & ECF_PURE))
 	    return true;
         }
@@ -1534,7 +1534,7 @@  resolve_noninline_speculation (fibheap_t edge_heap, struct cgraph_edge *edge)
       bitmap updated_nodes = BITMAP_ALLOC (NULL);
 
       spec_rem += edge->count;
-      cgraph_resolve_speculation (edge, NULL);
+      edge->resolve_speculation ();
       reset_edge_caches (where);
       inline_update_overall_summary (where);
       update_caller_keys (edge_heap, where,
@@ -1561,14 +1561,13 @@  inline_small_functions (void)
   int min_size, max_size;
   auto_vec<cgraph_edge *> new_indirect_edges;
   int initial_size = 0;
-  struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  struct cgraph_node **order = XCNEWVEC (cgraph_node *, symtab->cgraph_count);
   struct cgraph_edge_hook_list *edge_removal_hook_holder;
-
   if (flag_indirect_inlining)
     new_indirect_edges.create (8);
 
   edge_removal_hook_holder
-    = cgraph_add_edge_removal_hook (&heap_edge_removal_hook, edge_heap);
+    = symtab->add_edge_removal_hook (&heap_edge_removal_hook, edge_heap);
 
   /* Compute overall unit size and other global parameters used by badness
      metrics.  */
@@ -1651,7 +1650,7 @@  inline_small_functions (void)
 	    }
 	  if (edge->speculative && !speculation_useful_p (edge, edge->aux != NULL))
 	    {
-	      cgraph_resolve_speculation (edge, NULL);
+	      edge->resolve_speculation ();
 	      update = true;
 	    }
 	}
@@ -1756,7 +1755,7 @@  inline_small_functions (void)
 	 recursive calls where we do effects similar to loop unrolling.
 	 When inlining such edge seems profitable, leave decision on
 	 specific inliner.  */
-      if (cgraph_edge_recursive_p (edge))
+      if (edge->recursive_p ())
 	{
 	  where = edge->caller;
 	  if (where->global.inlined_to)
@@ -1859,7 +1858,7 @@  inline_small_functions (void)
 	     initial_size, overall_size,
 	     initial_size ? overall_size * 100 / (initial_size) - 100: 0);
   BITMAP_FREE (updated_nodes);
-  cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
+  symtab->remove_edge_removal_hook (edge_removal_hook_holder);
 }
 
 /* Flatten NODE.  Performed both during early inlining and
@@ -1908,7 +1907,7 @@  flatten_function (struct cgraph_node *node, bool early)
 	  : !can_early_inline_edge_p (e))
 	continue;
 
-      if (cgraph_edge_recursive_p (e))
+      if (e->recursive_p ())
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "Not inlining: recursive call.\n");
@@ -2141,7 +2140,7 @@  ipa_inline (void)
   if (!optimize)
     return 0;
 
-  order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
 
   if (in_lto_p && optimize)
     ipa_update_after_lto_read ();
@@ -2184,7 +2183,7 @@  ipa_inline (void)
 
   /* Do first after-inlining removal.  We want to remove all "stale" extern inline
      functions and virtual functions so we really know what is called once.  */
-  symtab_remove_unreachable_nodes (false, dump_file);
+  symtab->remove_unreachable_nodes (false, dump_file);
   free (order);
 
   /* Inline functions with a property that after inlining into all callers the
@@ -2222,7 +2221,7 @@  ipa_inline (void)
 	      next = edge->next_callee;
 	      if (edge->speculative && !speculation_useful_p (edge, false))
 		{
-		  cgraph_resolve_speculation (edge, NULL);
+		  edge->resolve_speculation ();
 		  spec_rem += edge->count;
 		  update = true;
 		  remove_functions = true;
@@ -2284,7 +2283,7 @@  inline_always_inline_functions (struct cgraph_node *node)
       if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl))
 	continue;
 
-      if (cgraph_edge_recursive_p (e))
+      if (e->recursive_p ())
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "  Not inlining recursive call to %s.\n",
@@ -2346,7 +2345,7 @@  early_inline_small_functions (struct cgraph_node *node)
       if (!can_early_inline_edge_p (e))
 	continue;
 
-      if (cgraph_edge_recursive_p (e))
+      if (e->recursive_p ())
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "  Not inlining: recursive call.\n");
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index b059696..ac461e2 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -379,13 +379,13 @@  contains_hot_call_p (struct cgraph_node *node)
 {
   struct cgraph_edge *e;
   for (e = node->callees; e; e = e->next_callee)
-    if (cgraph_maybe_hot_edge_p (e))
+    if (e->maybe_hot_p ())
       return true;
     else if (!e->inline_failed
 	     && contains_hot_call_p (e->callee))
       return true;
   for (e = node->indirect_calls; e; e = e->next_callee)
-    if (cgraph_maybe_hot_edge_p (e))
+    if (e->maybe_hot_p ())
       return true;
   return false;
 }
@@ -603,7 +603,7 @@  ipa_profile (void)
 			fprintf (dump_file,
 				 "Not speculating: probability is too low.\n");
 		    }
-		  else if (!cgraph_maybe_hot_edge_p (e))
+		  else if (!e->maybe_hot_p ())
 		    {
 		      nuseless++;
 		      if (dump_file)
@@ -633,8 +633,8 @@  ipa_profile (void)
 			    n2 = alias;
 			}
 		      nconverted++;
-		      cgraph_turn_edge_to_speculative
-			(e, n2,
+		      e->make_speculative
+			(n2,
 			 apply_scale (e->count,
 				      e->indirect_info->common_target_probability),
 			 apply_scale (e->frequency,
@@ -669,7 +669,7 @@  ipa_profile (void)
 	     nuseless, nuseless * 100.0 / nindirect,
 	     nconverted, nconverted * 100.0 / nindirect);
 
-  order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   order_pos = ipa_reverse_postorder (order);
   for (i = order_pos - 1; i >= 0; i--)
     {
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index a4556f1..9632ea85 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2897,7 +2897,7 @@  ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
 		       "converting indirect call in %s to direct call to %s\n",
 		       ie->caller->name (), callee->name ());
     }
-  ie = cgraph_make_edge_direct (ie, callee);
+  ie = ie->make_direct (callee);
   es = inline_edge_summary (ie);
   es->call_stmt_size -= (eni_size_weights.indirect_call_cost
 			 - eni_size_weights.call_cost);
@@ -3510,8 +3510,10 @@  void
 ipa_set_node_agg_value_chain (struct cgraph_node *node,
 			      struct ipa_agg_replacement_value *aggvals)
 {
-  if (vec_safe_length (ipa_node_agg_replacements) <= (unsigned) cgraph_max_uid)
-    vec_safe_grow_cleared (ipa_node_agg_replacements, cgraph_max_uid + 1);
+  if (vec_safe_length (ipa_node_agg_replacements)
+      <= (unsigned) symtab->cgraph_max_uid)
+    vec_safe_grow_cleared (ipa_node_agg_replacements,
+			   symtab->cgraph_max_uid + 1);
 
   (*ipa_node_agg_replacements)[node->uid] = aggvals;
 }
@@ -3699,18 +3701,18 @@  ipa_register_cgraph_hooks (void)
 {
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
-      cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
+      symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
   if (!node_removal_hook_holder)
     node_removal_hook_holder =
-      cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
+      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
-      cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
+      symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
   if (!node_duplication_hook_holder)
     node_duplication_hook_holder =
-      cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
+      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
   function_insertion_hook_holder =
-      cgraph_add_function_insertion_hook (&ipa_add_new_function, NULL);
+      symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
 }
 
 /* Unregister our cgraph hooks if they are not already there.  */
@@ -3718,15 +3720,15 @@  ipa_register_cgraph_hooks (void)
 static void
 ipa_unregister_cgraph_hooks (void)
 {
-  cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
+  symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  cgraph_remove_node_removal_hook (node_removal_hook_holder);
+  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
   node_removal_hook_holder = NULL;
-  cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
+  symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
+  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
   node_duplication_hook_holder = NULL;
-  cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
+  symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
 }
 
@@ -4256,7 +4258,7 @@  ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
     }
   gsi_replace (&gsi, new_stmt, true);
   if (cs)
-    cgraph_set_call_stmt (cs, new_stmt);
+    cs->set_call_stmt (new_stmt);
   do
     {
       current_node->record_stmt_references (gsi_stmt (gsi));
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index e5e8268..a6db8f6 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -538,10 +538,10 @@  static inline void
 ipa_check_create_node_params (void)
 {
   if (!ipa_node_params_vector.exists ())
-    ipa_node_params_vector.create (cgraph_max_uid);
+    ipa_node_params_vector.create (symtab->cgraph_max_uid);
 
-  if (ipa_node_params_vector.length () <= (unsigned) cgraph_max_uid)
-    ipa_node_params_vector.safe_grow_cleared (cgraph_max_uid + 1);
+  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
+    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
 }
 
 /* This function ensures the array of edge arguments infos is big enough to
@@ -550,8 +550,9 @@  ipa_check_create_node_params (void)
 static inline void
 ipa_check_create_edge_args (void)
 {
-  if (vec_safe_length (ipa_edge_args_vector) <= (unsigned) cgraph_edge_max_uid)
-    vec_safe_grow_cleared (ipa_edge_args_vector, cgraph_edge_max_uid + 1);
+  if (vec_safe_length (ipa_edge_args_vector)
+      <= (unsigned) symtab->edges_max_uid)
+    vec_safe_grow_cleared (ipa_edge_args_vector, symtab->edges_max_uid + 1);
 }
 
 /* Returns true if the array of edge infos is large enough to accommodate an
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b964502..459d08d 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -890,11 +890,11 @@  register_hooks (void)
   init_p = true;
 
   node_removal_hook_holder =
-      cgraph_add_node_removal_hook (&remove_node_data, NULL);
+      symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
   node_duplication_hook_holder =
-      cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
+      symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
   function_insertion_hook_holder =
-      cgraph_add_function_insertion_hook (&add_new_function, NULL);
+      symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
 }
 
 
@@ -1090,7 +1090,7 @@  propagate_pure_const (void)
   struct cgraph_node *node;
   struct cgraph_node *w;
   struct cgraph_node **order =
-    XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+    XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   int order_pos;
   int i;
   struct ipa_dfs_info * w_info;
@@ -1192,7 +1192,7 @@  propagate_pure_const (void)
 			       y_l->looping);
 		    }
 		  if (y_l->pure_const_state > IPA_PURE
-		      && cgraph_edge_cannot_lead_to_return (e))
+		      && e->cannot_lead_to_return_p ())
 		    {
 		      if (dump_file && (dump_flags & TDF_DETAILS))
 			fprintf (dump_file,
@@ -1213,7 +1213,7 @@  propagate_pure_const (void)
 	      else
 		state_from_flags (&edge_state, &edge_looping,
 				  flags_from_decl_or_type (y->decl),
-				  cgraph_edge_cannot_lead_to_return (e));
+				  e->cannot_lead_to_return_p ());
 
 	      /* Merge the results with what we already know.  */
 	      better_state (&edge_state, &edge_looping,
@@ -1237,7 +1237,7 @@  propagate_pure_const (void)
 		fprintf (dump_file, "    Indirect call");
 	      state_from_flags (&edge_state, &edge_looping,
 			        ie->indirect_info->ecf_flags,
-			        cgraph_edge_cannot_lead_to_return (ie));
+				ie->cannot_lead_to_return_p ());
 	      /* Merge the results with what we already know.  */
 	      better_state (&edge_state, &edge_looping,
 			    w_l->state_previously_known,
@@ -1368,7 +1368,7 @@  propagate_nothrow (void)
   struct cgraph_node *node;
   struct cgraph_node *w;
   struct cgraph_node **order =
-    XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+    XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   int order_pos;
   int i;
   struct ipa_dfs_info * w_info;
@@ -1473,9 +1473,9 @@  propagate (void)
 {
   struct cgraph_node *node;
 
-  cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
-  cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
-  cgraph_remove_node_removal_hook (node_removal_hook_holder);
+  symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
+  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
+  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
 
   /* Nothrow makes more function to not lead to return and improve
      later analysis.  */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index d999cb1..9767eab 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -387,7 +387,7 @@  propagate_bits (ipa_reference_global_vars_info_t x_global, struct cgraph_node *x
 		 seems so to local analysis.  If we cannot return from
 		 the function, we can safely ignore the call.  */
 	      if ((flags & ECF_PURE)
-		  || cgraph_edge_cannot_lead_to_return (e))
+		  || e->cannot_lead_to_return_p ())
 		continue;
 
 	      union_static_var_sets (x_global->statics_written,
@@ -419,9 +419,9 @@  ipa_init (void)
   all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
 
   node_removal_hook_holder =
-      cgraph_add_node_removal_hook (&remove_node_data, NULL);
+      symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
   node_duplication_hook_holder =
-      cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
+      symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
 }
 
 
@@ -642,7 +642,7 @@  get_read_write_all_from_node (struct cgraph_node *node,
 	read_all = true;
 	if (dump_file && (dump_flags & TDF_DETAILS))
 	  fprintf (dump_file, "   indirect call -> read all\n");
-	if (!cgraph_edge_cannot_lead_to_return (ie)
+	if (!ie->cannot_lead_to_return_p ()
 	    && !(ie->indirect_info->ecf_flags & ECF_PURE))
 	  {
 	    if (dump_file && (dump_flags & TDF_DETAILS))
@@ -660,7 +660,7 @@  propagate (void)
 {
   struct cgraph_node *node;
   struct cgraph_node **order =
-    XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+    XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   int order_pos;
   int i;
 
@@ -1011,9 +1011,9 @@  ipa_reference_read_optimization_summary (void)
   bitmap_obstack_initialize (&optimization_summary_obstack);
 
   node_removal_hook_holder =
-      cgraph_add_node_removal_hook (&remove_node_data, NULL);
+      symtab->add_cgraph_removal_hook (&remove_node_data, NULL);
   node_duplication_hook_holder =
-      cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
+      symtab->add_cgraph_duplication_hook (&duplicate_node_data, NULL);
   all_module_statics = BITMAP_ALLOC (&optimization_summary_obstack);
 
   while ((file_data = file_data_vec[j++]))
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 2af3a93..3762d6a 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1229,7 +1229,7 @@  split_function (struct split_point *split_point)
     }
 
   /* Now create the actual clone.  */
-  rebuild_cgraph_edges ();
+  cgraph_edge::rebuild_edges ();
   node = cur_node->create_version_clone_with_body
     (vNULL, NULL, args_to_skip, !split_part_return_p, split_point->split_bbs,
      split_point->entry_bb, "part");
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 590ac27..552071e 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -173,7 +173,7 @@  ipa_reduced_postorder (struct cgraph_node **order,
   struct cgraph_node *node;
   struct searchc_env env;
   splay_tree_node result;
-  env.stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  env.stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   env.stack_size = 0;
   env.result = order;
   env.order_pos = 0;
@@ -292,7 +292,7 @@  ipa_reverse_postorder (struct cgraph_node **order)
   struct ipa_ref *ref = NULL;
 
   struct postorder_stack *stack =
-    XCNEWVEC (struct postorder_stack, cgraph_n_nodes);
+    XCNEWVEC (struct postorder_stack, symtab->cgraph_count);
 
   /* We have to deal with cycles nicely, so use a depth first traversal
      output algorithm.  Ignore the fact that some functions won't need
@@ -407,9 +407,9 @@  ipa_merge_profiles (struct cgraph_node *dst,
 
   if (!dst->count)
     return;
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Merging profiles of %s/%i to %s/%i\n",
+      fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n",
 	       xstrdup (src->name ()), src->order,
 	       xstrdup (dst->name ()), dst->order);
     }
@@ -456,16 +456,16 @@  ipa_merge_profiles (struct cgraph_node *dst,
   if (n_basic_blocks_for_fn (srccfun)
       != n_basic_blocks_for_fn (dstcfun))
     {
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file,
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file,
 		 "Giving up; number of basic block mismatch.\n");
       match = false;
     }
   else if (last_basic_block_for_fn (srccfun)
 	   != last_basic_block_for_fn (dstcfun))
     {
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file,
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file,
 		 "Giving up; last block mismatch.\n");
       match = false;
     }
@@ -480,8 +480,8 @@  ipa_merge_profiles (struct cgraph_node *dst,
 	  dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index);
 	  if (dstbb == NULL)
 	    {
-	      if (cgraph_dump_file)
-		fprintf (cgraph_dump_file,
+	      if (symtab->dump_file)
+		fprintf (symtab->dump_file,
 			 "No matching block for bb %i.\n",
 			 srcbb->index);
 	      match = false;
@@ -489,8 +489,8 @@  ipa_merge_profiles (struct cgraph_node *dst,
 	    }
 	  if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs))
 	    {
-	      if (cgraph_dump_file)
-		fprintf (cgraph_dump_file,
+	      if (symtab->dump_file)
+		fprintf (symtab->dump_file,
 			 "Edge count mistmatch for bb %i.\n",
 			 srcbb->index);
 	      match = false;
@@ -502,8 +502,8 @@  ipa_merge_profiles (struct cgraph_node *dst,
 	      edge dste = EDGE_SUCC (dstbb, i);
 	      if (srce->dest->index != dste->dest->index)
 		{
-		  if (cgraph_dump_file)
-		    fprintf (cgraph_dump_file,
+		  if (symtab->dump_file)
+		    fprintf (symtab->dump_file,
 			     "Succ edge mistmatch for bb %i.\n",
 			     srce->dest->index);
 		  match = false;
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index edfd471..32199af 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -580,11 +580,11 @@  function_and_variable_visibility (bool whole_program)
 		{
 		  struct cgraph_edge *e = node->callers;
 
-		  cgraph_redirect_edge_callee (e, alias);
+		  e->redirect_callee (alias);
 		  if (gimple_has_body_p (e->caller->decl))
 		    {
 		      push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
-		      cgraph_redirect_edge_call_stmt_to_callee (e);
+		      e->redirect_call_stmt_to_callee ();
 		      pop_cfun ();
 		    }
 		}
@@ -717,7 +717,7 @@  function_and_variable_visibility (bool whole_program)
 	  fprintf (dump_file, " %s", vnode->name ());
       fprintf (dump_file, "\n\n");
     }
-  cgraph_function_flags_ready = true;
+  symtab->function_flags_ready = true;
   return 0;
 }
 
diff --git a/gcc/ipa.c b/gcc/ipa.c
index bf6b2d7..5afacd8 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -114,7 +114,7 @@  process_references (symtab_node *snode,
       if (node->definition && !node->in_other_partition
 	  && ((!DECL_EXTERNAL (node->decl) || node->alias)
 	      || (((before_inlining_p
-		    && (cgraph_state < CGRAPH_STATE_IPA_SSA
+		    && (symtab->state < IPA_SSA
 		        || !lookup_attribute ("always_inline",
 					      DECL_ATTRIBUTES (node->decl)))))
 		  /* We use variable constructors during late complation for
@@ -169,7 +169,7 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
 	     devirtualization.  */
 	   if (n->definition
 	       && (before_inlining_p
-		   && (cgraph_state < CGRAPH_STATE_IPA_SSA
+		   && (symtab->state < IPA_SSA
 		       || !lookup_attribute ("always_inline",
 					     DECL_ATTRIBUTES (n->decl)))))
 	     reachable->add (n);
@@ -205,11 +205,11 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                                target->name (),
                                target->order);
 	    }
-	  edge = cgraph_make_edge_direct (edge, target);
+	  edge = edge->make_direct (target);
 	  if (inline_summary_vec)
 	    inline_update_overall_summary (node);
 	  else if (edge->call_stmt)
-	    cgraph_redirect_edge_call_stmt_to_callee (edge);
+	    edge->redirect_call_stmt_to_callee ();
 	}
     }
 }
@@ -270,7 +270,7 @@  walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
    we set AUX pointer of processed symbols in the boundary to constant 2.  */
 
 bool
-symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
+symbol_table::remove_unreachable_nodes (bool before_inlining_p, FILE *file)
 {
   symtab_node *first = (symtab_node *) (void *) 1;
   struct cgraph_node *node, *next;
@@ -448,9 +448,9 @@  symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
     }
 
   /* Remove unreachable functions.   */
-  for (node = cgraph_first_function (); node; node = next)
+  for (node = first_function (); node; node = next)
     {
-      next = cgraph_next_function (node);
+      next = next_function (node);
 
       /* If node is not needed at all, remove it.  */
       if (!node->aux)
@@ -515,9 +515,9 @@  symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
   /* Remove unreachable variables.  */
   if (file)
     fprintf (file, "\nReclaiming variables:");
-  for (vnode = varpool_first_variable (); vnode; vnode = vnext)
+  for (vnode = first_variable (); vnode; vnode = vnext)
     {
-      vnext = varpool_next_variable (vnode);
+      vnext = next_variable (vnode);
       if (!vnode->aux
 	  /* For can_refer_decl_in_current_unit_p we want to track for
 	     all external variables if they are defined in other partition
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 38c5a9d..607aece 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1890,7 +1890,7 @@  finish_method (tree fndecl)
   cfun->function_end_locus = DECL_FUNCTION_LAST_LINE (fndecl);
 
   /* Defer inlining and expansion to the cgraph optimizers.  */
-  cgraph_finalize_function (fndecl, false);
+  cgraph_node::finalize_function (fndecl, false);
 }
 
 /* We pessimistically marked all methods and fields external until we
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index 7425b4e..9c4a9cf 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -1727,7 +1727,7 @@  java_emit_static_constructor (void)
 
       DECL_STATIC_CONSTRUCTOR (decl) = 1;
       java_genericize (decl);
-      cgraph_finalize_function (decl, false);
+      cgraph_node::finalize_function (decl, false);
     }
 }
 
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index aaf65d44..8ff91ba 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -320,7 +320,7 @@  write_global_declarations (void)
   timevar_start (TV_PHASE_OPT_GEN);
   /* This lang hook is dual-purposed, and also finalizes the
      compilation unit.  */
-  finalize_compilation_unit ();
+  symtab->finalize_compilation_unit ();
   timevar_stop (TV_PHASE_OPT_GEN);
 
   timevar_start (TV_PHASE_DBGINFO);
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 120f924..68f6a52 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -789,7 +789,7 @@  add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
 /* Add all references in NODE to encoders.  */
 
 static void
-add_references (lto_symtab_encoder_t encoder, symtab_node *node)
+create_references (lto_symtab_encoder_t encoder, symtab_node *node)
 {
   int i;
   struct ipa_ref *ref = NULL;
@@ -828,7 +828,7 @@  compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
       struct cgraph_node *node = lsei_cgraph_node (lsei);
       add_node_to (encoder, node, true);
       lto_set_symtab_encoder_in_partition (encoder, node);
-      add_references (encoder, node);
+      create_references (encoder, node);
       /* For proper debug info, we need to ship the origins, too.  */
       if (DECL_ABSTRACT_ORIGIN (node->decl))
 	{
@@ -844,7 +844,7 @@  compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
 
       lto_set_symtab_encoder_in_partition (encoder, vnode);
       lto_set_symtab_encoder_encode_initializer (encoder, vnode);
-      add_references (encoder, vnode);
+      create_references (encoder, vnode);
       /* For proper debug info, we need to ship the origins, too.  */
       if (DECL_ABSTRACT_ORIGIN (vnode->decl))
 	{
@@ -866,7 +866,7 @@  compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
 	      && vnode->ctor_useable_for_folding_p ())
 	    {
 	      lto_set_symtab_encoder_encode_initializer (encoder, vnode);
-	      add_references (encoder, vnode);
+	      create_references (encoder, vnode);
 	    }
        }
     }
@@ -1114,7 +1114,6 @@  input_node (struct lto_file_decl_data *file_data,
   int i, count;
   tree group;
   const char *section;
-
   order = streamer_read_hwi (ib) + order_base;
   clone_ref = streamer_read_hwi (ib);
 
@@ -1132,14 +1131,14 @@  input_node (struct lto_file_decl_data *file_data,
       /* Declaration of functions can be already merged with a declaration
 	 from other input file.  We keep cgraph unmerged until after streaming
 	 of ipa passes is done.  Alays forcingly create a fresh node.  */
-      node = cgraph_node::create_empty ();
+      node = symtab->create_empty ();
       node->decl = fn_decl;
       node->register_symbol ();
     }
 
   node->order = order;
-  if (order >= symtab_order)
-    symtab_order = order + 1;
+  if (order >= symtab->order)
+    symtab->order = order + 1;
 
   node->count = streamer_read_gcov_count (ib);
   node->count_materialization_scale = streamer_read_hwi (ib);
@@ -1241,8 +1240,8 @@  input_varpool_node (struct lto_file_decl_data *file_data,
   node->register_symbol ();
 
   node->order = order;
-  if (order >= symtab_order)
-    symtab_order = order + 1;
+  if (order >= symtab->order)
+    symtab->order = order + 1;
   node->lto_file_data = file_data;
 
   bp = streamer_read_bitpack (ib);
@@ -1308,7 +1307,7 @@  input_ref (struct lto_input_block *ib,
   use = (enum ipa_ref_use) bp_unpack_value (&bp, 2);
   speculative = (enum ipa_ref_use) bp_unpack_value (&bp, 1);
   node = nodes[streamer_read_hwi (ib)];
-  ref = referring_node->add_reference (node, use);
+  ref = referring_node->create_reference (node, use);
   ref->speculative = speculative;
   if (is_a <cgraph_node *> (referring_node))
     ref->lto_stmt_uid = streamer_read_hwi (ib);
@@ -1397,7 +1396,7 @@  input_cgraph_1 (struct lto_file_decl_data *file_data,
   unsigned i;
 
   tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
-  order_base = symtab_order;
+  order_base = symtab->order;
   while (tag)
     {
       if (tag == LTO_symtab_edge)
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index f6488d8..271b51c 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1358,10 +1358,10 @@  lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
 
   while ((str = streamer_read_string_cst (data_in, &ib)))
     {
-      struct asm_node *node = add_asm_node (str);
+      asm_node *node = symtab->finalize_toplevel_asm (str);
       node->order = streamer_read_hwi (&ib) + order_base;
-      if (node->order >= symtab_order)
-	symtab_order = node->order + 1;
+      if (node->order >= symtab->order)
+	symtab->order = node->order + 1;
     }
 
   lto_data_in_delete (data_in);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 00a7bad..b516c7b 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2098,7 +2098,7 @@  lto_output_toplevel_asms (void)
   char *section_name;
   struct lto_simple_header_with_strings header;
 
-  if (! asm_nodes)
+  if (!symtab->first_asm_symbol ())
     return;
 
   ob = create_output_block (LTO_section_asm);
@@ -2106,7 +2106,7 @@  lto_output_toplevel_asms (void)
   /* Make string 0 be a NULL string.  */
   streamer_write_char_stream (ob->string_stream, 0);
 
-  for (can = asm_nodes; can; can = can->next)
+  for (can = symtab->first_asm_symbol (); can; can = can->next)
     {
       streamer_write_string_cst (ob, ob->main_stream, can->asm_str);
       streamer_write_hwi (ob, can->order);
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 1837b99..5bd089b 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -22,7 +22,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "toplev.h"
 #include "tree.h"
-#include "gcc-symtab.h"
 #include "basic-block.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -140,8 +139,9 @@  add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
   if (symbol_partitioned_p (node))
     {
       node->in_other_partition = 1;
-      if (cgraph_dump_file)
-        fprintf (cgraph_dump_file, "Symbol node %s now used in multiple partitions\n",
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file,
+		 "Symbol node %s now used in multiple partitions\n",
 		 node->name ());
     }
   node->aux = (void *)((size_t)node->aux + 1);
@@ -413,7 +413,7 @@  lto_balanced_map (int n_lto_partitions)
 {
   int n_nodes = 0;
   int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
-  struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid);
+  struct cgraph_node **order = XNEWVEC (cgraph_node *, symtab->cgraph_max_uid);
   varpool_node **varpool_order = NULL;
   int i;
   struct cgraph_node *node;
@@ -446,9 +446,10 @@  lto_balanced_map (int n_lto_partitions)
      things works smoother if we order in source order.  */
   qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     for(i = 0; i < n_nodes; i++)
-      fprintf (cgraph_dump_file, "Balanced map symbol order:%s:%u\n", order[i]->name (), order[i]->tp_first_run);
+      fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n",
+	       order[i]->name (), order[i]->tp_first_run);
 
   if (!flag_toplevel_reorder)
     {
@@ -471,8 +472,8 @@  lto_balanced_map (int n_lto_partitions)
     partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
   npartitions = 1;
   partition = new_partition ("");
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Total unit size: %i, partition size: %i\n",
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file, "Total unit size: %i, partition size: %i\n",
 	     total_size, partition_size);
 
   for (i = 0; i < n_nodes; i++)
@@ -657,8 +658,8 @@  lto_balanced_map (int n_lto_partitions)
 	  best_total_size = total_size;
 	  best_varpool_pos = varpool_pos;
 	}
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file, "Step %i: added %s/%i, size %i, cost %i/%i "
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file, "Step %i: added %s/%i, size %i, cost %i/%i "
 		 "best %i/%i, step %i\n", i,
 		 order[i]->name (), order[i]->order,
 		 partition->insns, cost, internal,
@@ -669,8 +670,8 @@  lto_balanced_map (int n_lto_partitions)
 	{
 	  if (best_i != i)
 	    {
-	      if (cgraph_dump_file)
-		fprintf (cgraph_dump_file, "Unwinding %i insertions to step %i\n",
+	      if (symtab->dump_file)
+		fprintf (symtab->dump_file, "Unwinding %i insertions to step %i\n",
 			 i - best_i, best_i);
 	      undo_partition (partition, best_n_nodes);
 	      varpool_pos = best_varpool_pos;
@@ -686,8 +687,8 @@  lto_balanced_map (int n_lto_partitions)
 	  total_size = best_total_size;
 	  cost = 0;
 
-	  if (cgraph_dump_file)
-	    fprintf (cgraph_dump_file, "New partition\n");
+	  if (symtab->dump_file)
+	    fprintf (symtab->dump_file, "New partition\n");
 	  best_n_nodes = 0;
 	  best_cost = INT_MAX;
 
@@ -744,8 +745,8 @@  privatize_symbol_name (symtab_node *node)
   if (node->lto_file_data
       && lto_get_decl_name_mapping (node->lto_file_data, name) != name)
     {
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file,
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file,
 		"Not privatizing symbol name: %s. It privatized already.\n",
 		name);
       return false;
@@ -756,19 +757,20 @@  privatize_symbol_name (symtab_node *node)
      that are not really clones.  */
   if (node->unique_name)
     {
-      if (cgraph_dump_file)
-	fprintf (cgraph_dump_file,
+      if (symtab->dump_file)
+	fprintf (symtab->dump_file,
 		"Not privatizing symbol name: %s. Has unique name.\n",
 		name);
       return false;
     }
-  change_decl_assembler_name (decl, clone_function_name (decl, "lto_priv"));
+  symtab->change_decl_assembler_name (decl,
+				      clone_function_name (decl, "lto_priv"));
   if (node->lto_file_data)
     lto_record_renamed_decl (node->lto_file_data, name,
 			     IDENTIFIER_POINTER
 			     (DECL_ASSEMBLER_NAME (decl)));
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file,
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file,
 	    "Privatizing symbol name: %s -> %s\n",
 	    name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
   return true;
@@ -793,8 +795,8 @@  promote_symbol (symtab_node *node)
   TREE_PUBLIC (node->decl) = 1;
   DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN;
   DECL_VISIBILITY_SPECIFIED (node->decl) = true;
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file,
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file,
 	    "Promoting as hidden: %s\n", node->name ());
 }
 
@@ -842,7 +844,7 @@  rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
   /* Now walk symbols sharing the same name and see if there are any conflicts.
      (all types of symbols counts here, since we can not have static of the
      same name as external or public symbol.)  */
-  for (s = symtab_node_for_asm (name);
+  for (s = symtab_node::get_for_asmname (name);
        s; s = s->next_sharing_asm_name)
     if ((s->real_symbol_p () || may_need_named_section_p (encoder, s))
 	&& s->decl != node->decl
@@ -854,13 +856,13 @@  rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
   if (!s)
     return;
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file,
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file,
 	    "Renaming statics with asm name: %s\n", node->name ());
 
   /* Assign every symbol in the set that shares the same ASM name an unique
      mangled name.  */
-  for (s = symtab_node_for_asm (name); s;)
+  for (s = symtab_node::get_for_asmname (name); s;)
     if (!s->externally_visible
 	&& ((s->real_symbol_p ()
              && !DECL_EXTERNAL (node->decl)
@@ -871,7 +873,7 @@  rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
       {
         if (privatize_symbol_name (s))
 	  /* Re-start from beginning since we do not know how many symbols changed a name.  */
-	  s = symtab_node_for_asm (name);
+	  s = symtab_node::get_for_asmname (name);
         else s = s->next_sharing_asm_name;
       }
     else s = s->next_sharing_asm_name;
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index aae865a..cf00076 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -46,9 +46,9 @@  lto_cgraph_replace_node (struct cgraph_node *node,
   struct cgraph_edge *e, *next;
   bool compatible_p;
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i"
+      fprintf (symtab->dump_file, "Replacing cgraph node %s/%i by %s/%i"
  	       " for symbol %s\n",
 	       node->name (), node->order,
 	       prevailing_node->name (),
@@ -75,7 +75,7 @@  lto_cgraph_replace_node (struct cgraph_node *node,
   for (e = node->callers; e; e = next)
     {
       next = e->next_caller;
-      cgraph_redirect_edge_callee (e, prevailing_node);
+      e->redirect_callee (prevailing_node);
       /* If there is a mismatch between the supposed callee return type and
 	 the real one do not attempt to inline this function.
 	 ???  We really need a way to match function signatures for ABI
@@ -443,13 +443,13 @@  lto_symtab_merge_decls_1 (symtab_node *first)
   symtab_node *prevailing;
   bool diagnosed_p = false;
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Merging nodes for %s. Candidates:\n",
+      fprintf (symtab->dump_file, "Merging nodes for %s. Candidates:\n",
 	       first->asm_name ());
       for (e = first; e; e = e->next_sharing_asm_name)
 	if (TREE_PUBLIC (e->decl))
-	  e->dump (cgraph_dump_file);
+	  e->dump (symtab->dump_file);
     }
 
   /* Compute the symbol resolutions.  This is a no-op when using the
@@ -497,7 +497,7 @@  lto_symtab_merge_decls_1 (symtab_node *first)
 	}
     }
 
-  symtab_prevail_in_asm_name_hash (prevailing);
+  symtab->symtab_prevail_in_asm_name_hash (prevailing);
 
   /* Diagnose mismatched objects.  */
   for (e = prevailing->next_sharing_asm_name;
@@ -539,11 +539,11 @@  lto_symtab_merge_decls_1 (symtab_node *first)
      mismatches.  */
   lto_symtab_merge_decls_2 (prevailing, diagnosed_p);
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "After resolution:\n");
+      fprintf (symtab->dump_file, "After resolution:\n");
       for (e = prevailing; e; e = e->next_sharing_asm_name)
-	e->dump (cgraph_dump_file);
+	e->dump (symtab->dump_file);
     }
 }
 
@@ -555,7 +555,7 @@  lto_symtab_merge_decls (void)
   symtab_node *node;
 
   /* Populate assembler name hash.   */
-  symtab_initialize_asm_name_hash ();
+  symtab->symtab_initialize_asm_name_hash ();
 
   FOR_EACH_SYMBOL (node)
     if (!node->previous_sharing_asm_name
@@ -599,7 +599,7 @@  lto_symtab_merge_symbols (void)
 
   if (!flag_ltrans)
     {
-      symtab_initialize_asm_name_hash ();
+      symtab->symtab_initialize_asm_name_hash ();
 
       /* Do the actual merging.  
          At this point we invalidate hash translating decls into symtab nodes
@@ -621,7 +621,7 @@  lto_symtab_merge_symbols (void)
 
 	  if (!node->analyzed && node->alias_target)
 	    {
-	      symtab_node *tgt = symtab_node_for_asm (node->alias_target);
+	      symtab_node *tgt = symtab_node::get_for_asmname (node->alias_target);
 	      gcc_assert (node->weakref);
 	      if (tgt)
 		node->resolve_alias (tgt);
@@ -688,7 +688,7 @@  lto_symtab_prevailing_decl (tree decl)
   gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
 
   /* Walk through the list of candidates and return the one we merged to.  */
-  ret = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
+  ret = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (decl));
   if (!ret)
     return decl;
 
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 62444ed..1ecbbce 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2215,8 +2215,9 @@  lto_create_files_from_ids (lto_file *file, struct lto_file_decl_data *file_data,
 			   int *count)
 {
   lto_file_finalize (file_data, file);
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Creating file %s with sub id " HOST_WIDE_INT_PRINT_HEX "\n", 
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file,
+	     "Creating file %s with sub id " HOST_WIDE_INT_PRINT_HEX "\n",
 	     file_data->file_name, file_data->id);
   (*count)++;
   return 0;
@@ -2595,41 +2596,41 @@  lto_wpa_write_files (void)
 
       if (!quiet_flag)
 	fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name, part->insns);
-      if (cgraph_dump_file)
+      if (symtab->dump_file)
 	{
           lto_symtab_encoder_iterator lsei;
 	  
-	  fprintf (cgraph_dump_file, "Writing partition %s to file %s, %i insns\n",
+	  fprintf (symtab->dump_file, "Writing partition %s to file %s, %i insns\n",
 		   part->name, temp_filename, part->insns);
-	  fprintf (cgraph_dump_file, "  Symbols in partition: ");
+	  fprintf (symtab->dump_file, "  Symbols in partition: ");
 	  for (lsei = lsei_start_in_partition (part->encoder); !lsei_end_p (lsei);
 	       lsei_next_in_partition (&lsei))
 	    {
 	      symtab_node *node = lsei_node (lsei);
-	      fprintf (cgraph_dump_file, "%s ", node->asm_name ());
+	      fprintf (symtab->dump_file, "%s ", node->asm_name ());
 	    }
-	  fprintf (cgraph_dump_file, "\n  Symbols in boundary: ");
+	  fprintf (symtab->dump_file, "\n  Symbols in boundary: ");
 	  for (lsei = lsei_start (part->encoder); !lsei_end_p (lsei);
 	       lsei_next (&lsei))
 	    {
 	      symtab_node *node = lsei_node (lsei);
 	      if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
 		{
-	          fprintf (cgraph_dump_file, "%s ", node->asm_name ());
+		  fprintf (symtab->dump_file, "%s ", node->asm_name ());
 		  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
 		  if (cnode
 		      && lto_symtab_encoder_encode_body_p (part->encoder, cnode))
-		    fprintf (cgraph_dump_file, "(body included)");
+		    fprintf (symtab->dump_file, "(body included)");
 		  else
 		    {
 		      varpool_node *vnode = dyn_cast <varpool_node *> (node);
 		      if (vnode
 			  && lto_symtab_encoder_encode_initializer_p (part->encoder, vnode))
-			fprintf (cgraph_dump_file, "(initializer included)");
+			fprintf (symtab->dump_file, "(initializer included)");
 		    }
 		}
 	    }
-	  fprintf (cgraph_dump_file, "\n");
+	  fprintf (symtab->dump_file, "\n");
 	}
       gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);
 
@@ -2889,7 +2890,7 @@  read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   struct lto_file_decl_data **decl_data;
   symtab_node *snode;
 
-  init_cgraph ();
+  symtab->initialize ();
 
   timevar_push (TV_IPA_LTO_DECL_IN);
 
@@ -2914,7 +2915,7 @@  read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
       /* True, since the plugin splits the archives.  */
       gcc_assert (num_objects == nfiles);
     }
-  cgraph_state = CGRAPH_LTO_STREAMING;
+  symtab->state = LTO_STREAMING;
 
   canonical_type_hash_cache = new hash_map<const_tree, hashval_t> (251);
   gimple_canonical_types = htab_create_ggc (16381, gimple_canonical_type_hash,
@@ -3078,23 +3079,23 @@  read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
 
   /* Finally merge the cgraph according to the decl merging decisions.  */
   timevar_push (TV_IPA_LTO_CGRAPH_MERGE);
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Before merging:\n");
-      symtab_node::dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "Before merging:\n");
+      symtab_node::dump_table (symtab->dump_file);
     }
   lto_symtab_merge_symbols ();
   /* Removal of unreachable symbols is needed to make verify_symtab to pass;
      we are still having duplicated comdat groups containing local statics.
      We could also just remove them while merging.  */
-  symtab_remove_unreachable_nodes (true, dump_file);
+  symtab->remove_unreachable_nodes (true, dump_file);
   ggc_collect ();
-  cgraph_state = CGRAPH_STATE_IPA_SSA;
+  symtab->state = IPA_SSA;
 
   timevar_pop (TV_IPA_LTO_CGRAPH_MERGE);
 
   /* Indicate that the cgraph is built and ready.  */
-  cgraph_function_flags_ready = true;
+  symtab->function_flags_ready = true;
 
   ggc_free (all_file_decl_data);
   all_file_decl_data = NULL;
@@ -3236,20 +3237,20 @@  do_whole_program_analysis (void)
       dump_memory_report (false);
     }
 
-  cgraph_function_flags_ready = true;
+  symtab->function_flags_ready = true;
 
-  if (cgraph_dump_file)
-    symtab_node::dump_table (cgraph_dump_file);
+  if (symtab->dump_file)
+    symtab_node::dump_table (symtab->dump_file);
   bitmap_obstack_initialize (NULL);
-  cgraph_state = CGRAPH_STATE_IPA_SSA;
+  symtab->state = IPA_SSA;
 
   execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);
-  symtab_remove_unreachable_nodes (false, dump_file);
+  symtab->remove_unreachable_nodes (false, dump_file);
 
-  if (cgraph_dump_file)
+  if (symtab->dump_file)
     {
-      fprintf (cgraph_dump_file, "Optimized ");
-      symtab_node::dump_table (cgraph_dump_file);
+      fprintf (symtab->dump_file, "Optimized ");
+      symtab_node::dump_table (symtab->dump_file);
     }
 #ifdef ENABLE_CHECKING
   symtab_node::verify_symtab_nodes ();
@@ -3432,7 +3433,7 @@  lto_main (void)
 
 	  /* Let the middle end know that we have read and merged all of
 	     the input files.  */ 
-	  compile ();
+	  symtab->compile ();
 
 	  timevar_stop (TV_PHASE_OPT_GEN);
 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7f26865..9d1cd2c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -4907,7 +4907,7 @@  expand_omp_taskreg (struct omp_region *region)
       push_cfun (child_cfun);
       if (optimize)
 	optimize_omp_library_calls (entry_stmt);
-      rebuild_cgraph_edges ();
+      cgraph_edge::rebuild_edges ();
 
       /* Some EH regions might become dead, see PR34608.  If
 	 pass_cleanup_cfg isn't the first pass to happen with the
@@ -8022,7 +8022,7 @@  expand_omp_target (struct omp_region *region)
       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
 	 fixed in a following pass.  */
       push_cfun (child_cfun);
-      rebuild_cgraph_edges ();
+      cgraph_edge::rebuild_edges ();
 
       /* Some EH regions might become dead, see PR34608.  If
 	 pass_cleanup_cfg isn't the first pass to happen with the
@@ -11051,7 +11051,7 @@  simd_clone_create (struct cgraph_node *old_node)
       DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
       DECL_STATIC_DESTRUCTOR (new_decl) = 0;
       new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
-      new_node->call_function_insertion_hooks ();
+      symtab->call_cgraph_insertion_hooks (new_node);
     }
   if (new_node == NULL)
     return new_node;
@@ -11884,7 +11884,7 @@  expand_simd_clones (struct cgraph_node *node)
 	      clone->prev_clone->simdclone->next_clone = n;
 	      node->simd_clones->simdclone->prev_clone = n;
 	    }
-	  change_decl_assembler_name (n->decl, id);
+	  symtab->change_decl_assembler_name (n->decl, id);
 	  /* And finally adjust the return type, parameters and for
 	     definitions also function body.  */
 	  if (node->definition)
diff --git a/gcc/passes.c b/gcc/passes.c
index 7e47992..5001c3d 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -333,8 +333,8 @@  execute_all_early_local_passes (void)
      none of the sub-passes are IPA passes and do not create new
      functions, this is ok.  We're setting this value for the benefit
      of IPA passes that follow.  */
-  if (cgraph_state < CGRAPH_STATE_IPA_SSA)
-    cgraph_state = CGRAPH_STATE_IPA_SSA;
+  if (symtab->state < IPA_SSA)
+    symtab->state = IPA_SSA;
   return 0;
 }
 
@@ -1506,7 +1506,7 @@  do_per_function_toporder (void (*callback) (function *, void *data), void *data)
   else
     {
       gcc_assert (!order);
-      order = ggc_vec_alloc<cgraph_node *> (cgraph_n_nodes);
+      order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
       nnodes = ipa_reverse_postorder (order);
       for (i = nnodes - 1; i >= 0; i--)
         order[i]->process = 1;
@@ -1732,7 +1732,7 @@  execute_function_todo (function *fn, void *data)
     rebuild_frequencies ();
 
   if (flags & TODO_rebuild_cgraph_edges)
-    rebuild_cgraph_edges ();
+    cgraph_edge::rebuild_edges ();
 
   /* If we've seen errors do not bother running any verifiers.  */
   if (!seen_error ())
@@ -1814,7 +1814,7 @@  execute_todo (unsigned int flags)
   if (flags & TODO_remove_functions)
     {
       gcc_assert (!cfun);
-      symtab_remove_unreachable_nodes (true, dump_file);
+      symtab->remove_unreachable_nodes (true, dump_file);
     }
 
   if ((flags & TODO_dump_symtab) && dump_file && !current_function_decl)
@@ -2113,7 +2113,7 @@  execute_one_pass (opt_pass *pass)
 		node->get_body ();
 		push_cfun (DECL_STRUCT_FUNCTION (node->decl));
 		execute_all_ipa_transforms ();
-		rebuild_cgraph_edges ();
+		cgraph_edge::rebuild_edges ();
 		free_dominance_info (CDI_DOMINATORS);
 		free_dominance_info (CDI_POST_DOMINATORS);
 		pop_cfun ();
@@ -2121,7 +2121,7 @@  execute_one_pass (opt_pass *pass)
 	      }
 	  }
       if (applied)
-        symtab_remove_unreachable_nodes (false, dump_file);
+	symtab->remove_unreachable_nodes (false, dump_file);
       /* Restore current_pass.  */
       current_pass = pass;
     }
@@ -2176,7 +2176,7 @@  execute_one_pass (opt_pass *pass)
     }
 
   if (!current_function_decl)
-    cgraph_process_new_functions ();
+    symtab->process_new_functions ();
 
   pass_fini_dump_file (pass);
 
@@ -2314,9 +2314,9 @@  ipa_write_summaries (void)
      cgraph_expand_all_functions.  This mostly facilitates debugging,
      since it causes the gimple file to be processed in the same order
      as the source code.  */
-  order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+  order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
   order_pos = ipa_reverse_postorder (order);
-  gcc_assert (order_pos == cgraph_n_nodes);
+  gcc_assert (order_pos == symtab->cgraph_count);
 
   for (i = order_pos - 1; i >= 0; i--)
     {
@@ -2555,7 +2555,7 @@  execute_ipa_pass_list (opt_pass *pass)
 	    gcc_unreachable ();
 	}
       gcc_assert (!current_function_decl);
-      cgraph_process_new_functions ();
+      symtab->process_new_functions ();
       pass = pass->next;
     }
   while (pass);
diff --git a/gcc/predict.c b/gcc/predict.c
index 0fdf9f5..eb5db2a 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -187,31 +187,30 @@  maybe_hot_bb_p (struct function *fun, const_basic_block bb)
 /* Return true if the call can be hot.  */
 
 bool
-cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
+cgraph_edge::maybe_hot_p (void)
 {
   if (profile_info && flag_branch_probabilities
-      && !maybe_hot_count_p (NULL,
-                             edge->count))
+      && !maybe_hot_count_p (NULL, count))
     return false;
-  if (edge->caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
-      || (edge->callee
-	  && edge->callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
+  if (caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
+      || (callee
+	  && callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED))
     return false;
-  if (edge->caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
-      && (edge->callee
-	  && edge->callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
+  if (caller->frequency > NODE_FREQUENCY_UNLIKELY_EXECUTED
+      && (callee
+	  && callee->frequency <= NODE_FREQUENCY_EXECUTED_ONCE))
     return false;
   if (optimize_size)
     return false;
-  if (edge->caller->frequency == NODE_FREQUENCY_HOT)
+  if (caller->frequency == NODE_FREQUENCY_HOT)
     return true;
-  if (edge->caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
-      && edge->frequency < CGRAPH_FREQ_BASE * 3 / 2)
+  if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
+      && frequency < CGRAPH_FREQ_BASE * 3 / 2)
     return false;
   if (flag_guess_branch_prob)
     {
       if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0
-	  || edge->frequency <= (CGRAPH_FREQ_BASE
+	  || frequency <= (CGRAPH_FREQ_BASE
 				 / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
         return false;
     }
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 1c65490..d8302a7 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -298,7 +298,7 @@  finalize_size_functions (void)
       dump_function (TDI_original, fndecl);
       gimplify_function_tree (fndecl);
       dump_function (TDI_generic, fndecl);
-      cgraph_finalize_function (fndecl, false);
+      cgraph_node::finalize_function (fndecl, false);
     }
 
   vec_free (size_functions);
diff --git a/gcc/symtab.c b/gcc/symtab.c
index a93c299..739a8e4 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -61,36 +61,10 @@  const char * const ld_plugin_symbol_resolution_names[]=
   "prevailing_def_ironly_exp"
 };
 
-
-/* Hash table used to hold sectoons.  */
-static GTY((param_is (section_hash_entry))) htab_t section_hash;
-
-/* Hash table used to convert assembler names into nodes.  */
-static GTY((param_is (symtab_node))) htab_t assembler_name_hash;
-
-/* Map from a symbol to initialization/finalization priorities.  */
-struct GTY(()) symbol_priority_map {
-  symtab_node *symbol;
-  priority_type init;
-  priority_type fini;
-};
-
-/* Hash table used to hold init priorities.  */
-static GTY ((param_is (struct symbol_priority_map)))
-  htab_t init_priority_hash;
-
-/* 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;
-
 /* Hash asmnames ignoring the user specified marks.  */
 
-static hashval_t
-decl_assembler_name_hash (const_tree asmname)
+hashval_t
+symbol_table::decl_assembler_name_hash (const_tree asmname)
 {
   if (IDENTIFIER_POINTER (asmname)[0] == '*')
     {
@@ -111,8 +85,8 @@  decl_assembler_name_hash (const_tree asmname)
 
 /* Returns a hash code for P.  */
 
-static hashval_t
-hash_node_by_assembler_name (const void *p)
+hashval_t
+symbol_table::hash_node_by_assembler_name (const void *p)
 {
   const symtab_node *n = (const symtab_node *) p;
   return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
@@ -120,8 +94,8 @@  hash_node_by_assembler_name (const void *p)
 
 /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
 
-static bool
-decl_assembler_name_equal (tree decl, const_tree asmname)
+bool
+symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
 {
   tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
   const char *decl_str;
@@ -176,8 +150,8 @@  decl_assembler_name_equal (tree decl, const_tree asmname)
 
 /* Returns nonzero if P1 and P2 are equal.  */
 
-static int
-eq_assembler_name (const void *p1, const void *p2)
+int
+symbol_table::eq_assembler_name (const void *p1, const void *p2)
 {
   const symtab_node *n1 = (const symtab_node *) p1;
   const_tree name = (const_tree)p2;
@@ -186,8 +160,9 @@  eq_assembler_name (const void *p1, const void *p2)
 
 /* Insert NODE to assembler name hash.  */
 
-static void
-insert_to_assembler_name_hash (symtab_node *node, bool with_clones)
+void
+symbol_table::insert_to_assembler_name_hash (symtab_node *node,
+					     bool with_clones)
 {
   if (is_a <varpool_node *> (node) && DECL_HARD_REGISTER (node->decl))
     return;
@@ -196,7 +171,7 @@  insert_to_assembler_name_hash (symtab_node *node, bool with_clones)
   if (assembler_name_hash)
     {
       void **aslot;
-      struct cgraph_node *cnode;
+      cgraph_node *cnode;
       tree decl = node->decl;
 
       tree name = DECL_ASSEMBLER_NAME (node->decl);
@@ -222,12 +197,13 @@  insert_to_assembler_name_hash (symtab_node *node, bool with_clones)
 
 /* Remove NODE from assembler name hash.  */
 
-static void
-unlink_from_assembler_name_hash (symtab_node *node, bool with_clones)
+void
+symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
+					       bool with_clones)
 {
   if (assembler_name_hash)
     {
-      struct cgraph_node *cnode;
+      cgraph_node *cnode;
       tree decl = node->decl;
 
       if (node->next_sharing_asm_name)
@@ -266,7 +242,7 @@  unlink_from_assembler_name_hash (symtab_node *node, bool with_clones)
 /* Arrange node to be first in its entry of assembler_name_hash.  */
 
 void
-symtab_prevail_in_asm_name_hash (symtab_node *node)
+symbol_table::symtab_prevail_in_asm_name_hash (symtab_node *node)
 {
   unlink_from_assembler_name_hash (node, false);
   insert_to_assembler_name_hash (node, false);
@@ -275,7 +251,7 @@  symtab_prevail_in_asm_name_hash (symtab_node *node)
 /* Initalize asm name hash unless.  */
 
 void
-symtab_initialize_asm_name_hash (void)
+symbol_table::symtab_initialize_asm_name_hash (void)
 {
   symtab_node *node;
   if (!assembler_name_hash)
@@ -288,32 +264,10 @@  symtab_initialize_asm_name_hash (void)
     }
 }
 
-/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
-   Return NULL if there's no such node.  */
-
-symtab_node *
-symtab_node_for_asm (const_tree asmname)
-{
-  symtab_node *node;
-  void **slot;
-
-  symtab_initialize_asm_name_hash ();
-  slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
-				   decl_assembler_name_hash (asmname),
-				   NO_INSERT);
-
-  if (slot)
-    {
-      node = (symtab_node *) *slot;
-      return node;
-    }
-  return NULL;
-}
-
 /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */
 
 void
-change_decl_assembler_name (tree decl, tree name)
+symbol_table::change_decl_assembler_name (tree decl, tree name)
 {
   symtab_node *node = NULL;
 
@@ -391,22 +345,16 @@  eq_sections (const void *p1, const void *p2)
 void
 symtab_node::register_symbol (void)
 {
-  next = symtab_nodes;
-  previous = NULL;
-  if (symtab_nodes)
-    symtab_nodes->previous = this;
-  symtab_nodes = this;
+  symtab->register_symbol (this);
 
   if (!decl->decl_with_vis.symtab_node)
     decl->decl_with_vis.symtab_node = this;
 
   ref_list.clear ();
 
-  order = symtab_order++;
-
   /* Be sure to do this last; C++ FE might create new nodes via
      DECL_ASSEMBLER_NAME langhook!  */
-  insert_to_assembler_name_hash (this, false);
+  symtab->insert_to_assembler_name_hash (this, false);
 }
 
 /* Remove NODE from same comdat group.   */
@@ -444,14 +392,7 @@  symtab_node::unregister (void)
 
   remove_from_same_comdat_group ();
 
-  if (previous)
-    previous->next = next;
-  else
-    symtab_nodes = next;
-  if (next)
-    next->previous = previous;
-  next = NULL;
-  previous = NULL;
+  symtab->unregister (this);
 
   /* During LTO symtab merging we temporarily corrupt decl to symtab node
      hash.  */
@@ -464,16 +405,16 @@  symtab_node::unregister (void)
       decl->decl_with_vis.symtab_node = replacement_node;
     }
   if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
-    unlink_from_assembler_name_hash (this, false);
+    symtab->unlink_from_assembler_name_hash (this, false);
   if (in_init_priority_hash)
     {
-      struct symbol_priority_map in;
+      symbol_priority_map in;
       void **slot;
       in.symbol = this;
 
-      slot = htab_find_slot (init_priority_hash, &in, NO_INSERT);
+      slot = htab_find_slot (symtab->init_priority_hash, &in, NO_INSERT);
       if (slot)
-	htab_clear_slot (init_priority_hash, slot);
+	htab_clear_slot (symtab->init_priority_hash, slot);
     }
 }
 
@@ -560,11 +501,11 @@  symtab_node::name () const
    REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
    of the use.  */
 
-struct ipa_ref *
-symtab_node::add_reference (symtab_node *referred_node,
-			    enum ipa_ref_use use_type)
+ipa_ref *
+symtab_node::create_reference (symtab_node *referred_node,
+			       enum ipa_ref_use use_type)
 {
-  return add_reference (referred_node, use_type, NULL);
+  return create_reference (referred_node, use_type, NULL);
 }
 
 
@@ -572,12 +513,12 @@  symtab_node::add_reference (symtab_node *referred_node,
    REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
    of the use and STMT the statement (if it exists).  */
 
-struct ipa_ref *
-symtab_node::add_reference (symtab_node *referred_node,
-			    enum ipa_ref_use use_type, gimple stmt)
+ipa_ref *
+symtab_node::create_reference (symtab_node *referred_node,
+			       enum ipa_ref_use use_type, gimple stmt)
 {
-  struct ipa_ref *ref = NULL, *ref2 = NULL;
-  struct ipa_ref_list *list, *list2;
+  ipa_ref *ref = NULL, *ref2 = NULL;
+  ipa_ref_list *list, *list2;
   ipa_ref_t *old_references;
 
   gcc_checking_assert (!stmt || is_a <cgraph_node *> (this));
@@ -627,9 +568,9 @@  symtab_node::add_reference (symtab_node *referred_node,
    type of the use and STMT the statement (if it exists).  Return the new
    reference or NULL if none was created.  */
 
-struct ipa_ref *
-symtab_node::maybe_add_reference (tree val, enum ipa_ref_use use_type,
-				  gimple stmt)
+ipa_ref *
+symtab_node::maybe_create_reference (tree val, enum ipa_ref_use use_type,
+				     gimple stmt)
 {
   STRIP_NOPS (val);
   if (TREE_CODE (val) != ADDR_EXPR)
@@ -640,7 +581,7 @@  symtab_node::maybe_add_reference (tree val, enum ipa_ref_use use_type,
     {
       symtab_node *referred = symtab_node::get (val);
       gcc_checking_assert (referred);
-      return add_reference (referred, use_type, stmt);
+      return create_reference (referred, use_type, stmt);
     }
   return NULL;
 }
@@ -648,16 +589,16 @@  symtab_node::maybe_add_reference (tree val, enum ipa_ref_use use_type,
 /* Clone all references from symtab NODE to this symtab_node.  */
 
 void
-symtab_node::clone_references (struct symtab_node *node)
+symtab_node::clone_references (symtab_node *node)
 {
-  struct ipa_ref *ref = NULL, *ref2 = NULL;
+  ipa_ref *ref = NULL, *ref2 = NULL;
   int i;
   for (i = 0; node->iterate_reference (i, ref); i++)
     {
       bool speculative = ref->speculative;
       unsigned int stmt_uid = ref->lto_stmt_uid;
 
-      ref2 = add_reference (ref->referred, ref->use, ref->stmt);
+      ref2 = create_reference (ref->referred, ref->use, ref->stmt);
       ref2->speculative = speculative;
       ref2->lto_stmt_uid = stmt_uid;
     }
@@ -666,16 +607,16 @@  symtab_node::clone_references (struct symtab_node *node)
 /* Clone all referring from symtab NODE to this symtab_node.  */
 
 void
-symtab_node::clone_referring (struct symtab_node *node)
+symtab_node::clone_referring (symtab_node *node)
 {
-  struct ipa_ref *ref = NULL, *ref2 = NULL;
+  ipa_ref *ref = NULL, *ref2 = NULL;
   int i;
   for (i = 0; node->iterate_referring(i, ref); i++)
     {
       bool speculative = ref->speculative;
       unsigned int stmt_uid = ref->lto_stmt_uid;
 
-      ref2 = ref->referring->add_reference (this, ref->use, ref->stmt);
+      ref2 = ref->referring->create_reference (this, ref->use, ref->stmt);
       ref2->speculative = speculative;
       ref2->lto_stmt_uid = stmt_uid;
     }
@@ -683,14 +624,14 @@  symtab_node::clone_referring (struct symtab_node *node)
 
 /* Clone reference REF to this symtab_node and set its stmt to STMT.  */
 
-struct ipa_ref *
-symtab_node::clone_reference (struct ipa_ref *ref, gimple stmt)
+ipa_ref *
+symtab_node::clone_reference (ipa_ref *ref, gimple stmt)
 {
   bool speculative = ref->speculative;
   unsigned int stmt_uid = ref->lto_stmt_uid;
-  struct ipa_ref *ref2;
+  ipa_ref *ref2;
 
-  ref2 = add_reference (ref->referred, ref->use, stmt);
+  ref2 = create_reference (ref->referred, ref->use, stmt);
   ref2->speculative = speculative;
   ref2->lto_stmt_uid = stmt_uid;
   return ref2;
@@ -699,11 +640,11 @@  symtab_node::clone_reference (struct ipa_ref *ref, gimple stmt)
 /* Find the structure describing a reference to REFERRED_NODE
    and associated with statement STMT.  */
 
-struct ipa_ref *
+ipa_ref *
 symtab_node::find_reference (symtab_node *referred_node,
 			     gimple stmt, unsigned int lto_stmt_uid)
 {
-  struct ipa_ref *r = NULL;
+  ipa_ref *r = NULL;
   int i;
 
   for (i = 0; iterate_reference (i, r); i++)
@@ -721,7 +662,7 @@  symtab_node::find_reference (symtab_node *referred_node,
 void
 symtab_node::remove_stmt_references (gimple stmt)
 {
-  struct ipa_ref *r = NULL;
+  ipa_ref *r = NULL;
   int i = 0;
 
   while (iterate_reference (i, r))
@@ -739,7 +680,7 @@  symtab_node::remove_stmt_references (gimple stmt)
 void
 symtab_node::clear_stmts_in_references (void)
 {
-  struct ipa_ref *r = NULL;
+  ipa_ref *r = NULL;
   int i;
 
   for (i = 0; iterate_reference (i, r); i++)
@@ -775,7 +716,7 @@  symtab_node::remove_all_referring (void)
 void
 symtab_node::dump_references (FILE *file)
 {
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
   int i;
   for (i = 0; iterate_reference (i, ref); i++)
     {
@@ -794,7 +735,7 @@  symtab_node::dump_references (FILE *file)
 void
 symtab_node::dump_referring (FILE *file)
 {
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
   int i;
   for (i = 0; iterate_referring(i, ref); i++)
     {
@@ -812,7 +753,7 @@  symtab_node::dump_referring (FILE *file)
 bool
 symtab_node::has_aliases_p (void)
 {
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
   int i;
 
   for (i = 0; iterate_referring (i, ref); i++)
@@ -823,8 +764,8 @@  symtab_node::has_aliases_p (void)
 
 /* Iterates I-th reference in the list, REF is also set.  */
 
-struct ipa_ref *
-symtab_node::iterate_reference (unsigned i, struct ipa_ref *&ref)
+ipa_ref *
+symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
 {
   vec_safe_iterate (ref_list.references, i, &ref);
 
@@ -833,8 +774,8 @@  symtab_node::iterate_reference (unsigned i, struct ipa_ref *&ref)
 
 /* Iterates I-th referring item in the list, REF is also set.  */
 
-struct ipa_ref *
-symtab_node::iterate_referring (unsigned i, struct ipa_ref *&ref)
+ipa_ref *
+symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
 {
   ref_list.referring.iterate (i, &ref);
 
@@ -843,8 +784,8 @@  symtab_node::iterate_referring (unsigned i, struct ipa_ref *&ref)
 
 /* Iterates I-th referring alias item in the list, REF is also set.  */
 
-struct ipa_ref *
-symtab_node::iterate_direct_aliases (unsigned i, struct ipa_ref *&ref)
+ipa_ref *
+symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
 {
   ref_list.referring.iterate (i, &ref);
 
@@ -993,6 +934,29 @@  symtab_node::dump_table (FILE *f)
     node->dump (f);
 }
 
+
+/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
+   Return NULL if there's no such node.  */
+
+symtab_node *
+symtab_node::get_for_asmname (const_tree asmname)
+{
+  symtab_node *node;
+  void **slot;
+
+  symtab->symtab_initialize_asm_name_hash ();
+  slot = htab_find_slot_with_hash (symtab->assembler_name_hash, asmname,
+				   symtab->decl_assembler_name_hash (asmname),
+				   NO_INSERT);
+
+  if (slot)
+    {
+      node = (symtab_node *) *slot;
+      return node;
+    }
+  return NULL;
+}
+
 /* Dump symtab node NODE to stderr.  */
 
 DEBUG_FUNCTION void
@@ -1031,7 +995,7 @@  symtab_node::verify_base (void)
       error_found = true;
     }
    
-  if (cgraph_state != CGRAPH_LTO_STREAMING)
+  if (symtab->state != LTO_STREAMING)
     {
       hashed_node = symtab_node::get (decl);
       if (!hashed_node)
@@ -1048,9 +1012,9 @@  symtab_node::verify_base (void)
 	  error_found = true;
 	}
     }
-  if (assembler_name_hash)
+  if (symtab->assembler_name_hash)
     {
-      hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
+      hashed_node = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (decl));
       if (hashed_node && hashed_node->previous_sharing_asm_name)
 	{
           error ("assembler name hash list corrupted");
@@ -1138,7 +1102,7 @@  symtab_node::verify_base (void)
       while (n != this);
       if (comdat_local_p ())
 	{
-	  struct ipa_ref *ref = NULL;
+	  ipa_ref *ref = NULL;
 
 	  for (int i = 0; iterate_referring (i, ref); ++i)
 	    {
@@ -1436,11 +1400,11 @@  symtab_node::set_section_for_node (const char *section)
       x_section->ref_count--;
       if (!x_section->ref_count)
 	{
-	  slot = htab_find_slot_with_hash (section_hash, x_section->name,
+	  slot = htab_find_slot_with_hash (symtab->section_hash, x_section->name,
 					   htab_hash_string (x_section->name),
 					   INSERT);
 	  ggc_free (x_section);
-	  htab_clear_slot (section_hash, slot);
+	  htab_clear_slot (symtab->section_hash, slot);
 	}
       x_section = NULL;
     }
@@ -1449,10 +1413,10 @@  symtab_node::set_section_for_node (const char *section)
       implicit_section = false;
       return;
     }
-  if (!section_hash)
-    section_hash = htab_create_ggc (10, hash_section_hash_entry,
+  if (!symtab->section_hash)
+    symtab->section_hash = htab_create_ggc (10, hash_section_hash_entry,
 				    eq_sections, NULL);
-  slot = htab_find_slot_with_hash (section_hash, section,
+  slot = htab_find_slot_with_hash (symtab->section_hash, section,
 				   htab_hash_string (section),
 				   INSERT);
   if (*slot)
@@ -1491,13 +1455,14 @@  symtab_node::set_section (const char *section)
 priority_type
 symtab_node::get_init_priority ()
 {
-  struct symbol_priority_map *h;
-  struct symbol_priority_map in;
+  symbol_priority_map *h;
+  symbol_priority_map in;
 
   if (!this->in_init_priority_hash)
     return DEFAULT_INIT_PRIORITY;
   in.symbol = this;
-  h = (struct symbol_priority_map *) htab_find (init_priority_hash, &in);
+  h = (symbol_priority_map *) htab_find (symtab->init_priority_hash,
+						&in);
   return h ? h->init : DEFAULT_INIT_PRIORITY;
 }
 
@@ -1516,13 +1481,14 @@  enum availability symtab_node::get_availability (void)
 priority_type
 cgraph_node::get_fini_priority ()
 {
-  struct symbol_priority_map *h;
-  struct symbol_priority_map in;
+  symbol_priority_map *h;
+  symbol_priority_map in;
 
   if (!this->in_init_priority_hash)
     return DEFAULT_INIT_PRIORITY;
   in.symbol = this;
-  h = (struct symbol_priority_map *) htab_find (init_priority_hash, &in);
+  h = (symbol_priority_map *) htab_find (symtab->init_priority_hash,
+						&in);
   return h ? h->fini : DEFAULT_INIT_PRIORITY;
 }
 
@@ -1531,8 +1497,8 @@  cgraph_node::get_fini_priority ()
 int
 symbol_priority_map_eq (const void *va, const void *vb)
 {
-  const struct symbol_priority_map *const a = (const struct symbol_priority_map *) va,
-    *const b = (const struct symbol_priority_map *) vb;
+  const symbol_priority_map *const a = (const symbol_priority_map *) va,
+    *const b = (const symbol_priority_map *) vb;
   return (a->symbol == b->symbol);
 }
 
@@ -1541,27 +1507,28 @@  symbol_priority_map_eq (const void *va, const void *vb)
 unsigned int
 symbol_priority_map_hash (const void *item)
 {
-  return htab_hash_pointer (((const struct symbol_priority_map *)item)->symbol);
+  return htab_hash_pointer (((const symbol_priority_map *)item)->symbol);
 }
 
 /* Return the initialization and finalization priority information for
    DECL.  If there is no previous priority information, a freshly
    allocated structure is returned.  */
 
-struct symbol_priority_map *
+symbol_priority_map *
 symtab_node::priority_info (void)
 {
-  struct symbol_priority_map in;
-  struct symbol_priority_map *h;
+  symbol_priority_map in;
+  symbol_priority_map *h;
   void **loc;
 
   in.symbol = this;
-  if (!init_priority_hash)
-    init_priority_hash = htab_create_ggc (512, symbol_priority_map_hash,
-                                          symbol_priority_map_eq, 0);
+  if (!symtab->init_priority_hash)
+    symtab->init_priority_hash = htab_create_ggc (512,
+						  symbol_priority_map_hash,
+						  symbol_priority_map_eq, 0);
 
-  loc = htab_find_slot (init_priority_hash, &in, INSERT);
-  h = (struct symbol_priority_map *) *loc;
+  loc = htab_find_slot (symtab->init_priority_hash, &in, INSERT);
+  h = (symbol_priority_map *) *loc;
   if (!h)
     {
       h = ggc_cleared_alloc<symbol_priority_map> ();
@@ -1580,7 +1547,7 @@  symtab_node::priority_info (void)
 void
 symtab_node::set_init_priority (priority_type priority)
 {
-  struct symbol_priority_map *h;
+  symbol_priority_map *h;
 
   if (is_a <cgraph_node *> (this))
     gcc_assert (DECL_STATIC_CONSTRUCTOR (this->decl));
@@ -1599,7 +1566,7 @@  symtab_node::set_init_priority (priority_type priority)
 void
 cgraph_node::set_fini_priority (priority_type priority)
 {
-  struct symbol_priority_map *h;
+  symbol_priority_map *h;
 
   gcc_assert (DECL_STATIC_DESTRUCTOR (this->decl));
 
@@ -1653,7 +1620,7 @@  symtab_node::resolve_alias (symtab_node *target)
   definition = true;
   alias = true;
   analyzed = true;
-  add_reference (target, IPA_REF_ALIAS, NULL);
+  create_reference (target, IPA_REF_ALIAS, NULL);
 
   /* Add alias into the comdat group of its target unless it is already there.  */
   if (same_comdat_group)
@@ -1677,7 +1644,7 @@  symtab_node::resolve_alias (symtab_node *target)
      when renaming symbols.  */
   alias_target = NULL;
 
-  if (cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
+  if (cpp_implicit_alias && symtab->state >= CONSTRUCTION)
     fixup_same_cpp_alias_visibility (target);
 
   /* If alias has address taken, so does the target.  */
@@ -1696,7 +1663,7 @@  symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
 					void *data, bool include_overwritable)
 {
   int i;
-  struct ipa_ref *ref;
+  ipa_ref *ref;
 
   if (callback (this, data))
     return true;
@@ -1926,7 +1893,7 @@  symtab_node::nonzero_address ()
      When parsing, beware the cases when WEAK attribute is added later.  */
   if (!DECL_WEAK (this->decl)
       && flag_delete_null_pointer_checks
-      && cgraph_state > CGRAPH_STATE_PARSING)
+      && symtab->state > PARSING)
     return true;
 
   /* If target is defined and not extern, we know it will be output and thus
@@ -1944,4 +1911,3 @@  symtab_node::nonzero_address ()
     return true;
   return false;
 }
-#include "gt-symtab.h"
diff --git a/gcc/toplev.c b/gcc/toplev.c
index a7f4b58..492a7ef 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,8 @@  along with GCC; see the file COPYING3.  If not see
 				   declarations for e.g. AIX 4.x.  */
 #endif
 
+#include <new>
+
 static void general_init (const char *);
 static void do_compile (void);
 static void process_options (void);
@@ -401,7 +403,7 @@  wrapup_global_declaration_2 (tree decl)
 	needed = false;
       else if (node && node->alias)
 	needed = false;
-      else if (!cgraph_global_info_ready
+      else if (!symtab->global_info_ready
 	       && (TREE_USED (decl)
 		   || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
 	/* needed */;
@@ -1173,6 +1175,7 @@  general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
+  symtab = ggc_cleared_alloc <symbol_table> ();
 
   statistics_early_init ();
   finish_params ();
@@ -1931,7 +1934,7 @@  do_compile (void)
 
           ggc_protect_identifiers = true;
 
-          init_cgraph ();
+	  symtab->initialize ();
           init_final (main_input_filename);
           coverage_init (aux_base_name);
           statistics_init ();
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 3641231..8285796 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4174,7 +4174,7 @@  ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
 
   // ??? copy_bbs should maintain cgraph edges for the blocks as it is
   // copying them, rather than forcing us to do this externally.
-  rebuild_cgraph_edges ();
+  cgraph_edge::rebuild_edges ();
 
   // ??? In ipa_uninstrument_transaction we don't try to update dominators
   // because copy_bbs doesn't return a VEC like iterate_fix_dominators expects.
@@ -4715,7 +4715,7 @@  ipa_tm_diagnose_transaction (struct cgraph_node *node,
 	      if (is_tm_callable (fndecl))
 		continue;
 
-	      if (cgraph_local_info (fndecl)->tm_may_enter_irr)
+	      if (cgraph_node::local_info (fndecl)->tm_may_enter_irr)
 		error_at (gimple_location (stmt),
 			  "unsafe function call %qD within "
 			  "atomic transaction", fndecl);
@@ -4913,7 +4913,7 @@  ipa_tm_create_version (struct cgraph_node *old_node)
 
   record_tm_clone_pair (old_decl, new_decl);
 
-  new_node->call_function_insertion_hooks ();
+  symtab->call_cgraph_insertion_hooks (new_node);
   if (old_node->force_output
       || old_node->ref_list.first_referring ())
     ipa_tm_mark_force_output_node (new_node);
@@ -5134,7 +5134,7 @@  ipa_tm_transform_calls_redirect (struct cgraph_node *node,
       fndecl = new_node->decl;
     }
 
-  cgraph_redirect_edge_callee (e, new_node);
+  e->redirect_callee (new_node);
   gimple_call_set_fndecl (stmt, fndecl);
 }
 
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index 00b27b5..c915e33 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -274,7 +274,7 @@  get_emutls_init_templ_addr (tree decl)
   if (DECL_EXTERNAL (to))
     varpool_node::get_create (to);
   else
-    varpool_add_new_variable (to);
+    varpool_node::add (to);
   return build_fold_addr_expr (to);
 }
 
@@ -344,7 +344,7 @@  new_emutls_decl (tree decl, tree alias_of)
   if (DECL_EXTERNAL (to))
     varpool_node::get_create (to);
   else if (!alias_of)
-    varpool_add_new_variable (to);
+    varpool_node::add (to);
   else 
     varpool_node::create_alias (to,
 				varpool_node::get_for_asmname
@@ -425,7 +425,7 @@  gen_emutls_addr (tree decl, struct lower_emutls_data *d)
 
       /* We may be adding a new reference to a new variable to the function.
          This means we have to play with the ipa-reference web.  */
-      d->cfun_node->add_reference (cvar, IPA_REF_ADDR, x);
+      d->cfun_node->create_reference (cvar, IPA_REF_ADDR, x);
 
       /* Record this ssa_name for possible use later in the basic block.  */
       data->access = addr;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index b6ecaa4..b82a147 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1800,10 +1800,10 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		      int edge_freq = edge->frequency;
 		      int new_freq;
 		      struct cgraph_edge *old_edge = edge;
-		      edge = cgraph_clone_edge (edge, id->dst_node, stmt,
-					        gimple_uid (stmt),
-					        REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
-					        true);
+		      edge = edge->clone (id->dst_node, stmt,
+					  gimple_uid (stmt),
+					  REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
+					  true);
 		      /* We could also just rescale the frequency, but
 		         doing so would introduce roundoff errors and make
 			 verifier unhappy.  */
@@ -1818,11 +1818,11 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 			  struct ipa_ref *ref;
 
 			  gcc_assert (!edge->indirect_unknown_callee);
-			  cgraph_speculative_call_info (old_edge, direct, indirect, ref);
-			  indirect = cgraph_clone_edge (indirect, id->dst_node, stmt,
-							gimple_uid (stmt),
-							REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
-							true);
+			  old_edge->speculative_call_info (direct, indirect, ref);
+			  indirect = indirect->clone (id->dst_node, stmt,
+						      gimple_uid (stmt),
+						      REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
+						      true);
 			  if (old_edge->frequency + indirect->frequency)
 			    {
 			      edge->frequency = MIN (RDIV ((gcov_type)new_freq * old_edge->frequency,
@@ -1865,7 +1865,7 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		case CB_CGE_MOVE:
 		  edge = id->dst_node->get_edge (orig_stmt);
 		  if (edge)
-		    cgraph_set_call_stmt (edge, stmt);
+		    edge->set_call_stmt (stmt);
 		  break;
 
 		default:
@@ -2426,7 +2426,7 @@  redirect_all_calls (copy_body_data * id, basic_block bb)
 	{
 	  struct cgraph_edge *edge = id->dst_node->get_edge (gsi_stmt (si));
 	  if (edge)
-	    cgraph_redirect_edge_call_stmt_to_callee (edge);
+	    edge->redirect_call_stmt_to_callee ();
 	}
     }
 }
@@ -4192,7 +4192,7 @@  expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
 	  && !cg_edge->callee->local.redefined_extern_inline
 	  /* During early inline pass, report only when optimization is
 	     not turned on.  */
-	  && (cgraph_global_info_ready
+	  && (symtab->global_info_ready
 	      || !optimize
 	      || cgraph_inline_failed_type (reason) == CIF_FINAL_ERROR)
 	  /* PR 20090218-1_0.c. Body can be provided by another module. */
@@ -4209,9 +4209,9 @@  expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
 	       && reason != CIF_UNSPECIFIED
 	       && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn))
 	       /* Do not warn about not inlined recursive calls.  */
-	       && !cgraph_edge_recursive_p (cg_edge)
+	       && !cg_edge->recursive_p ()
 	       /* Avoid warnings during early inline pass. */
-	       && cgraph_global_info_ready)
+	       && symtab->global_info_ready)
 	{
 	  warning (OPT_Winline, "inlining failed in call to %q+F: %s",
 		   fn, _(cgraph_inline_failed_string (reason)));
@@ -5216,7 +5216,7 @@  delete_unreachable_blocks_update_callgraph (copy_body_data *id)
 		  if (!e->inline_failed)
 		    e->callee->remove_symbol_and_inline_clones (id->dst_node);
 		  else
-		    cgraph_remove_edge (e);
+		    e->remove ();
 		}
 	      if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
 		  && id->dst_node->clones)
@@ -5229,7 +5229,7 @@  delete_unreachable_blocks_update_callgraph (copy_body_data *id)
 			if (!e->inline_failed)
 			  e->callee->remove_symbol_and_inline_clones (id->dst_node);
 			else
-			  cgraph_remove_edge (e);
+			  e->remove ();
 		      }
 
 		    if (node->clones)
@@ -5535,7 +5535,7 @@  tree_function_versioning (tree old_decl, tree new_decl,
   fold_cond_expr_cond ();
   delete_unreachable_blocks_update_callgraph (&id);
   if (id.dst_node->definition)
-    cgraph_rebuild_references ();
+    cgraph_edge::rebuild_references ();
   update_ssa (TODO_update_ssa);
 
   /* After partial cloning we need to rescale frequencies, so they are
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 07d6c79..82cec96 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -2897,7 +2897,7 @@  unnest_nesting_tree_1 (struct nesting_info *root)
   if (node->origin)
     {
        node->unnest ();
-       cgraph_finalize_function (root->context, true);
+       cgraph_node::finalize_function (root->context, true);
     }
 }
 
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 31d305b..ba90196 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -565,7 +565,7 @@  tree_profiling (void)
 
   /* This is a small-ipa pass that gets called only once, from
      cgraphunit.c:ipa_passes().  */
-  gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
+  gcc_assert (symtab->state == IPA_SSA);
 
   init_node_map (true);
 
@@ -657,7 +657,7 @@  tree_profiling (void)
       cleanup_tree_cfg ();
       update_ssa (TODO_update_ssa);
 
-      rebuild_cgraph_edges ();
+      cgraph_edge::rebuild_edges ();
 
       pop_cfun ();
     }
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 2f80497..8259dba 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -4894,7 +4894,7 @@  modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
   struct cgraph_node *new_node;
   bool cfg_changed;
 
-  rebuild_cgraph_edges ();
+  cgraph_edge::rebuild_edges ();
   free_dominance_info (CDI_DOMINATORS);
   pop_cfun ();
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 44c1ee7..80a3285 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -33,7 +33,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "stor-layout.h"
 #include "stringpool.h"
-#include "gcc-symtab.h"
 #include "varasm.h"
 #include "flags.h"
 #include "function.h"
@@ -856,7 +855,7 @@  set_user_assembler_name (tree decl, const char *name)
   char *starred = (char *) alloca (strlen (name) + 2);
   starred[0] = '*';
   strcpy (starred + 1, name);
-  change_decl_assembler_name (decl, get_identifier (starred));
+  symtab->change_decl_assembler_name (decl, get_identifier (starred));
   SET_DECL_RTL (decl, NULL_RTX);
 }
 
@@ -2332,8 +2331,8 @@  assemble_external (tree decl ATTRIBUTE_UNUSED)
      Ideally, only final.c would be calling this function, but it is
      not clear whether that would break things somehow.  See PR 17982
      for further discussion.  */
-  gcc_assert (cgraph_state == CGRAPH_STATE_EXPANSION
-	      || cgraph_state == CGRAPH_STATE_FINISHED);
+  gcc_assert (state == EXPANSION
+	      || state == FINISHED);
 #endif
 
   if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
@@ -5361,7 +5360,7 @@  weak_finish_1 (tree decl)
 static tree
 find_decl (tree target)
 {
-  symtab_node *node = symtab_node_for_asm (target);
+  symtab_node *node = symtab_node::get_for_asmname (target);
   if (node)
     return node->decl;
   return NULL_TREE;
@@ -5656,12 +5655,12 @@  assemble_alias (tree decl, tree target)
 
   /* If the target has already been emitted, we don't have to queue the
      alias.  This saves a tad of memory.  */
-  if (cgraph_global_info_ready)
+  if (symtab->global_info_ready)
     target_decl = find_decl (target);
   else
     target_decl= NULL;
   if ((target_decl && TREE_ASM_WRITTEN (target_decl))
-      || cgraph_state >= CGRAPH_STATE_EXPANSION)
+      || symtab->state >= EXPANSION)
     do_assemble_alias (decl, target);
   else
     {
@@ -7591,10 +7590,10 @@  default_asm_output_ident_directive (const char *ident_str)
      to asm_out_file.  Instead, add a fake top-level asm statement.
      This allows the front ends to use this hook without actually
      writing to asm_out_file, to handle #ident or Pragma Ident.  */
-  if (cgraph_state == CGRAPH_STATE_PARSING)
+  if (symtab->state == PARSING)
     {
       char *buf = ACONCAT ((ident_asm_op, "\"", ident_str, "\"\n", NULL));
-      add_asm_node (build_string (strlen (buf), buf));
+      symtab->finalize_toplevel_asm (build_string (strlen (buf), buf));
     }
   else
     fprintf (asm_out_file, "%s\"%s\"\n", ident_asm_op, ident_str);
diff --git a/gcc/varpool.c b/gcc/varpool.c
index b5fe71e..9f8676c 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -50,19 +50,14 @@  struct varpool_node_hook_list {
   struct varpool_node_hook_list *next;
 };
 
-/* List of hooks triggered when a node is removed.  */
-struct varpool_node_hook_list *first_varpool_node_removal_hook;
-/* List of hooks triggered when an variable is inserted.  */
-struct varpool_node_hook_list *first_varpool_variable_insertion_hook;
-
 /* Register HOOK to be called with DATA on each removed node.  */
-struct varpool_node_hook_list *
-varpool_add_node_removal_hook (varpool_node_hook hook, void *data)
+varpool_node_hook_list *
+symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
 {
-  struct varpool_node_hook_list *entry;
-  struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
+  varpool_node_hook_list *entry;
+  varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
 
-  entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
+  entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -74,9 +69,9 @@  varpool_add_node_removal_hook (varpool_node_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on removing nodes.  */
 void
-varpool_remove_node_removal_hook (struct varpool_node_hook_list *entry)
+symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
 {
-  struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
+  varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -85,10 +80,10 @@  varpool_remove_node_removal_hook (struct varpool_node_hook_list *entry)
 }
 
 /* Call all node removal hooks.  */
-static void
-varpool_call_node_removal_hooks (varpool_node *node)
+void
+symbol_table::call_varpool_removal_hooks (varpool_node *node)
 {
-  struct varpool_node_hook_list *entry = first_varpool_node_removal_hook;
+  varpool_node_hook_list *entry = m_first_varpool_removal_hook;
   while (entry)
   {
     entry->hook (node, entry->data);
@@ -97,13 +92,13 @@  varpool_call_node_removal_hooks (varpool_node *node)
 }
 
 /* Register HOOK to be called with DATA on each inserted node.  */
-struct varpool_node_hook_list *
-varpool_add_variable_insertion_hook (varpool_node_hook hook, void *data)
+varpool_node_hook_list *
+symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
 {
-  struct varpool_node_hook_list *entry;
-  struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
+  varpool_node_hook_list *entry;
+  varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
 
-  entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
+  entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
   entry->hook = hook;
   entry->data = data;
   entry->next = NULL;
@@ -115,9 +110,9 @@  varpool_add_variable_insertion_hook (varpool_node_hook hook, void *data)
 
 /* Remove ENTRY from the list of hooks called on inserted nodes.  */
 void
-varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *entry)
+symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
 {
-  struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
+  varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
 
   while (*ptr != entry)
     ptr = &(*ptr)->next;
@@ -127,9 +122,9 @@  varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *entry)
 
 /* Call all node insertion hooks.  */
 void
-varpool_call_variable_insertion_hooks (varpool_node *node)
+symbol_table::call_varpool_insertion_hooks (varpool_node *node)
 {
-  struct varpool_node_hook_list *entry = first_varpool_variable_insertion_hook;
+  varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
   while (entry)
   {
     entry->hook (node, entry->data);
@@ -167,11 +162,11 @@  varpool_node::get_create (tree decl)
 void
 varpool_node::remove (void)
 {
-  varpool_call_node_removal_hooks (this);
+  symtab->call_varpool_removal_hooks (this);
   unregister ();
 
   /* When streaming we can have multiple nodes associated with decl.  */
-  if (cgraph_state == CGRAPH_LTO_STREAMING)
+  if (symtab->state == LTO_STREAMING)
     ;
   /* Keep constructor when it may be used for folding. We remove
      references to external variables before final compilation.  */
@@ -195,7 +190,7 @@  varpool_node::remove_initializer (void)
 	 entries for given decl.  Do not attempt to remove
 	 the boides, or we will end up remiving
 	 wrong one.  */
-      && cgraph_state != CGRAPH_LTO_STREAMING)
+      && symtab->state != LTO_STREAMING)
     DECL_INITIAL (decl) = error_mark_node;
 }
 
@@ -205,7 +200,7 @@  varpool_node::dump (FILE *f)
 {
   dump_base (f);
   fprintf (f, "  Availability: %s\n",
-	   cgraph_function_flags_ready
+	   symtab->function_flags_ready
 	   ? cgraph_availability_names[get_availability ()]
 	   : "not-ready");
   fprintf (f, "  Varpool flags:");
@@ -256,7 +251,7 @@  varpool_node::debug_varpool (void)
 varpool_node *
 varpool_node::get_for_asmname (tree asmname)
 {
-  if (symtab_node *node = symtab_node_for_asm (asmname))
+  if (symtab_node *node = symtab_node::get_for_asmname (asmname))
     return dyn_cast <varpool_node *> (node);
   else
     return NULL;
@@ -268,7 +263,7 @@  varpool_node::get_for_asmname (tree asmname)
 tree
 varpool_node::get_constructor (void)
 {
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data *file_data;
   const char *data, *name;
   size_t len;
 
@@ -437,16 +432,16 @@  ctor_for_folding (tree decl)
 }
 
 /* Add the variable DECL to the varpool.
-   Unlike varpool_finalize_decl function is intended to be used
+   Unlike finalize_decl function is intended to be used
    by middle end and allows insertion of new variable at arbitrary point
    of compilation.  */
 void
-varpool_add_new_variable (tree decl)
+varpool_node::add (tree decl)
 {
   varpool_node *node;
   varpool_node::finalize_decl (decl);
   node = varpool_node::get_create (decl);
-  varpool_call_variable_insertion_hooks (node);
+  symtab->call_varpool_insertion_hooks (node);
   if (node->externally_visible_p ())
     node->externally_visible = true;
 }
@@ -487,7 +482,7 @@  varpool_node::analyze (void)
      We however don't want to re-analyze already analyzed nodes.  */
   if (!analyzed)
     {
-      gcc_assert (!in_lto_p || cgraph_function_flags_ready);
+      gcc_assert (!in_lto_p || symtab->function_flags_ready);
       /* Compute the alignment early so function body expanders are
 	 already informed about increased alignment.  */
       align_variable (decl, 0);
@@ -504,7 +499,7 @@  varpool_node::analyze (void)
 void
 varpool_node::assemble_aliases (void)
 {
-  struct ipa_ref *ref;
+  ipa_ref *ref;
 
   FOR_EACH_ALIAS (this, ref)
     {
@@ -578,20 +573,20 @@  enqueue_node (varpool_node *node, varpool_node **first)
    reachability starting from variables that are either externally visible
    or was referred from the asm output routines.  */
 
-static void
-varpool_remove_unreferenced_decls (void)
+void
+symbol_table::remove_unreferenced_decls (void)
 {
   varpool_node *next, *node;
   varpool_node *first = (varpool_node *)(void *)1;
   int i;
-  struct ipa_ref *ref = NULL;
+  ipa_ref *ref = NULL;
   hash_set<varpool_node *> referenced;
 
   if (seen_error ())
     return;
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "Trivially needed variables:");
+  if (dump_file)
+    fprintf (dump_file, "Trivially needed variables:");
   FOR_EACH_DEFINED_VARIABLE (node)
     {
       if (node->analyzed
@@ -601,8 +596,8 @@  varpool_remove_unreferenced_decls (void)
 	      || DECL_RTL_SET_P (node->decl)))
 	{
 	  enqueue_node (node, &first);
-          if (cgraph_dump_file)
-	    fprintf (cgraph_dump_file, " %s", node->asm_name ());
+	  if (dump_file)
+	    fprintf (dump_file, " %s", node->asm_name ());
 	}
     }
   while (first != (varpool_node *)(void *)1)
@@ -635,24 +630,24 @@  varpool_remove_unreferenced_decls (void)
 	    referenced.add (node);
 	}
     }
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "\nRemoving variables:");
-  for (node = varpool_first_defined_variable (); node; node = next)
+  if (dump_file)
+    fprintf (dump_file, "\nRemoving variables:");
+  for (node = symtab->first_defined_variable (); node; node = next)
     {
-      next = varpool_next_defined_variable (node);
+      next = symtab->next_defined_variable (node);
       if (!node->aux)
 	{
-          if (cgraph_dump_file)
-	    fprintf (cgraph_dump_file, " %s", node->asm_name ());
-	  if (referenced.contains (node))
+	  if (dump_file)
+	    fprintf (dump_file, " %s", node->asm_name ());
+	  if (referenced.contains(node))
 	    node->remove_initializer ();
 	  else
 	    node->remove ();
 	}
     }
 
-  if (cgraph_dump_file)
-    fprintf (cgraph_dump_file, "\n");
+  if (dump_file)
+    fprintf (dump_file, "\n");
 }
 
 /* For variables in named sections make sure get_variable_section
@@ -674,7 +669,7 @@  varpool_node::finalize_named_section_flags (void)
 
 /* Output all variables enqueued to be assembled.  */
 bool
-varpool_node::output_variables (void)
+symbol_table::output_variables (void)
 {
   bool changed = false;
   varpool_node *node;
@@ -682,7 +677,7 @@  varpool_node::output_variables (void)
   if (seen_error ())
     return false;
 
-  varpool_remove_unreferenced_decls ();
+  symtab->remove_unreferenced_decls ();
 
   timevar_push (TV_VAROUT);
 
@@ -755,7 +750,7 @@  varpool_node::create_extra_name_alias (tree alias, tree decl)
      via DECL_ASSEMBLER_NAME mechanizm.
      This is unfortunate because they are not going through the
      standard channels.  Ensure they get output.  */
-  if (cpp_implicit_aliases_done)
+  if (symtab->cpp_implicit_aliases_done)
     alias_node->resolve_alias (varpool_node::get_create (decl));
   return alias_node;
 }
@@ -770,7 +765,7 @@  varpool_node::call_for_node_and_aliases (bool (*callback) (varpool_node *,
 					 void *data,
 					 bool include_overwritable)
 {
-  struct ipa_ref *ref;
+  ipa_ref *ref;
 
   if (callback (this, data))
     return true;