diff mbox

Use conditional casting with symtab_node

Message ID CAGqM8fYOu2Z=98QSUdWTsXzPFhWahin3g09nSgMm7kJfhrfnTw@mail.gmail.com
State New
Headers show

Commit Message

Lawrence Crowl Sept. 22, 2012, 2:37 a.m. UTC
Add functions symtab_node_def::try_function and symtab_node_def::try_variable.
These function return a pointer to the more specific type (e.g. cgraph_node*)
if and only if the general type (symtab_node aka symtab_node_def*) is an
instance of the specific type.  These functions are essentially checked down
casts.

These functions reduce compile time and increase type safety when treating a
generic item as a more specific item.  In essence, the code change is from

  if (symtab_function_p (node))
    {
      struct cgraph_node *cnode = cgraph (node);
      ....
    }

to

  if (cgraph_node *cnode = node->try_function ())
    {
      ....
    }

The necessary conditional test defines a variable that holds a known good
pointer to the specific item and avoids subsequent conversion calls and
the assertion checks that may come with them.

When, the property test is embedded within a larger condition, the variable
declaration gets pulled out of the condition.  (This leaves some room for
using the variable inappropritately.)

  if (symtab_variable_p (node)
      && varpool (node)->finalized)
    varpool_analyze_node (varpool (node));

becomes

  varpool_node *vnode = node->try_variable ();
  if (vnode && vnode->finalized)
    varpool_analyze_node (vnode);

Note that we have converted two sets of assertions in the calls to varpool
into safe and efficient use of a variable.


There are remaining calls to symtab_function_p and symtab_variable_p that
do not involve a pointer to a more specific type.  These have been converted
to calls to a member functions symtab_node_def::is_function and
symtab_node_def::is_variable.  The original predicate functions have been
removed.


The cgraph.h header defined both a struct and a function with the name
varpool_node.  This name overloading can cause some unintuitive error messages
when, as is common in C++, one omits the struct keyword when using the type.
I have renamed the function to varpool_node_for_tree.


The new code bootstraps .616% faster with a 99% confidence of being faster.


Tested on x86_64.


Okay for trunk?



 }
@@ -1134,7 +1134,7 @@ lsei_start_function_in_partition (lto_sy

   if (lsei_end_p (lsei))
     return lsei;
-  if (!symtab_function_p (lsei_node (lsei))
+  if (!(lsei_node (lsei)->is_function ())
       || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei)))
     lsei_next_function_in_partition (&lsei);

@@ -1147,7 +1147,7 @@ lsei_next_variable_in_partition (lto_sym
 {
   lsei_next (lsei);
   while (!lsei_end_p (*lsei)
-	 && (!symtab_variable_p (lsei_node (*lsei))
+	 && (!lsei_node (*lsei)->is_variable ()
 	     || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
(*lsei))))
     lsei_next (lsei);
 }
@@ -1160,7 +1160,7 @@ lsei_start_variable_in_partition (lto_sy

   if (lsei_end_p (lsei))
     return lsei;
-  if (!symtab_variable_p (lsei_node (lsei))
+  if (!lsei_node (lsei)->is_variable ()
       || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei)))
     lsei_next_variable_in_partition (&lsei);

Comments

Lawrence Crowl Sept. 25, 2012, 8:19 p.m. UTC | #1
Ping!

On 9/21/12, Lawrence Crowl <crowl@googlers.com> wrote:
> Add functions symtab_node_def::try_function and
> symtab_node_def::try_variable.
> These function return a pointer to the more specific type (e.g.
> cgraph_node*)
> if and only if the general type (symtab_node aka symtab_node_def*) is an
> instance of the specific type.  These functions are essentially checked
> down
> casts.
>
> These functions reduce compile time and increase type safety when treating
> a
> generic item as a more specific item.  In essence, the code change is from
>
>   if (symtab_function_p (node))
>     {
>       struct cgraph_node *cnode = cgraph (node);
>       ....
>     }
>
> to
>
>   if (cgraph_node *cnode = node->try_function ())
>     {
>       ....
>     }
>
> The necessary conditional test defines a variable that holds a known good
> pointer to the specific item and avoids subsequent conversion calls and
> the assertion checks that may come with them.
>
> When, the property test is embedded within a larger condition, the variable
> declaration gets pulled out of the condition.  (This leaves some room for
> using the variable inappropritately.)
>
>   if (symtab_variable_p (node)
>       && varpool (node)->finalized)
>     varpool_analyze_node (varpool (node));
>
> becomes
>
>   varpool_node *vnode = node->try_variable ();
>   if (vnode && vnode->finalized)
>     varpool_analyze_node (vnode);
>
> Note that we have converted two sets of assertions in the calls to varpool
> into safe and efficient use of a variable.
>
>
> There are remaining calls to symtab_function_p and symtab_variable_p that
> do not involve a pointer to a more specific type.  These have been
> converted
> to calls to a member functions symtab_node_def::is_function and
> symtab_node_def::is_variable.  The original predicate functions have been
> removed.
>
>
> The cgraph.h header defined both a struct and a function with the name
> varpool_node.  This name overloading can cause some unintuitive error
> messages
> when, as is common in C++, one omits the struct keyword when using the
> type.
> I have renamed the function to varpool_node_for_tree.
>
>
> The new code bootstraps .616% faster with a 99% confidence of being faster.
>
>
> Tested on x86_64.
>
>
> Okay for trunk?
>
>
>
> Index: gcc/ChangeLog
>
> 2012-09-18  Lawrence Crowl  <crowl@google.com
>
> 	* cgraph.h (varpool_node): Rename to varpool_node_for_tree.
> 	Adjust callers to match.
> 	(symtab_node_def::try_function): New.
> 	Change most calls to symtab_function_p with calls to
> 	symtab_node_def::try_function.
> 	(symtab_node_def::try_variable): New.
> 	Change most calls to symtab_variable_p with calls to
> 	symtab_node_def::try_variable.
> 	(symtab_function_p): Rename to symtab_node_def::is_function.
> 	Adjust remaining callers to match.
> 	(symtab_variable_p): Rename to symtab_node_def::is_variable.
> 	Adjust remaining callers to match.
> 	* cgraph.c (cgraph_node_for_asm): Remove redundant call to
> 	symtab_node_for_asm.
> 	* graphunit.c (symbol_finalized_and_needed): New.
> 	(symbol_finalized): New.
> 	(cgraph_analyze_functions): Split complicated conditionals out into
> 	above new functions.
>
>
>
> Index: gcc/lto-symtab.c
> ===================================================================
> --- gcc/lto-symtab.c	(revision 191403)
> +++ gcc/lto-symtab.c	(working copy)
> @@ -743,7 +743,7 @@ lto_symtab_merge_cgraph_nodes_1 (void **
>  	{
>  	  if (!prevailing->vnode)
>  	    {
> -	      prevailing->vnode = varpool_node (prevailing->decl);
> +	      prevailing->vnode = varpool_node_for_tree (prevailing->decl);
>  	      prevailing->vnode->alias = true;
>  	    }
>  	  lto_varpool_replace_node (e->vnode, prevailing->vnode);
> Index: gcc/cgraphbuild.c
> ===================================================================
> --- gcc/cgraphbuild.c	(revision 191403)
> +++ gcc/cgraphbuild.c	(working copy)
> @@ -84,7 +84,7 @@ record_reference (tree *tp, int *walk_su
>
>        if (TREE_CODE (decl) == VAR_DECL)
>  	{
> -	  struct varpool_node *vnode = varpool_node (decl);
> +	  struct varpool_node *vnode = varpool_node_for_tree (decl);
>  	  ipa_record_reference ((symtab_node)ctx->varpool_node,
>  				(symtab_node)vnode,
>  				IPA_REF_ADDR, NULL);
> @@ -123,7 +123,7 @@ record_type_list (struct cgraph_node *no
>  	  type = TREE_OPERAND (type, 0);
>  	  if (TREE_CODE (type) == VAR_DECL)
>  	    {
> -	      struct varpool_node *vnode = varpool_node (type);
> +	      struct varpool_node *vnode = varpool_node_for_tree (type);
>  	      ipa_record_reference ((symtab_node)node,
>  				    (symtab_node)vnode,
>  				    IPA_REF_ADDR, NULL);
> @@ -233,7 +233,7 @@ mark_address (gimple stmt, tree addr, vo
>    else if (addr && TREE_CODE (addr) == VAR_DECL
>  	   && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
>      {
> -      struct varpool_node *vnode = varpool_node (addr);
> +      struct varpool_node *vnode = varpool_node_for_tree (addr);
>
>        ipa_record_reference ((symtab_node)data,
>  			    (symtab_node)vnode,
> @@ -262,7 +262,7 @@ mark_load (gimple stmt, tree t, void *da
>    else if (t && TREE_CODE (t) == VAR_DECL
>  	   && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
>      {
> -      struct varpool_node *vnode = varpool_node (t);
> +      struct varpool_node *vnode = varpool_node_for_tree (t);
>
>        ipa_record_reference ((symtab_node)data,
>  			    (symtab_node)vnode,
> @@ -280,7 +280,7 @@ mark_store (gimple stmt, tree t, void *d
>    if (t && TREE_CODE (t) == VAR_DECL
>        && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
>      {
> -      struct varpool_node *vnode = varpool_node (t);
> +      struct varpool_node *vnode = varpool_node_for_tree (t);
>
>        ipa_record_reference ((symtab_node)data,
>  			    (symtab_node)vnode,
> @@ -392,7 +392,7 @@ void
>  record_references_in_initializer (tree decl, bool only_vars)
>  {
>    struct pointer_set_t *visited_nodes = pointer_set_create ();
> -  struct varpool_node *node = varpool_node (decl);
> +  struct varpool_node *node = varpool_node_for_tree (decl);
>    struct record_reference_ctx ctx = {false, NULL};
>
>    ctx.varpool_node = node;
> Index: gcc/cgraph.c
> ===================================================================
> --- gcc/cgraph.c	(revision 191403)
> +++ gcc/cgraph.c	(working copy)
> @@ -506,9 +506,12 @@ cgraph_node_for_asm (tree asmname)
>    symtab_node node = symtab_node_for_asm (asmname);
>
>    /* We do not want to look at inline clones.  */
> -  for (node = symtab_node_for_asm (asmname); node; node =
> node->symbol.next_sharing_asm_name)
> -    if (symtab_function_p (node) && !cgraph(node)->global.inlined_to)
> -      return cgraph (node);
> +  for (; node; node = node->symbol.next_sharing_asm_name)
> +    {
> +      cgraph_node *cn = node->try_function ();
> +      if (cn && !cn->global.inlined_to)
> +	return cn;
> +    }
>    return NULL;
>  }
>
> Index: gcc/cgraph.h
> ===================================================================
> --- gcc/cgraph.h	(revision 191403)
> +++ gcc/cgraph.h	(working copy)
> @@ -448,13 +448,46 @@ struct GTY(()) asm_node {
>  /* Symbol table entry.  */
>  union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"),
>  	   chain_prev ("%h.symbol.previous"))) symtab_node_def {
> +  /* Dynamic type testers. */
> +  bool GTY((skip)) is_function ();
> +  bool GTY((skip)) is_variable ();
> +  /* Conditional accessors return null if not the requested type.  */
> +  cgraph_node * GTY((skip)) try_function ();
> +  varpool_node * GTY((skip)) try_variable ();
> +
>    struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol;
> -  /* Use cgraph (symbol) accessor to get cgraph_node.  */
> +  /* To access the following fields,
> +     use the conditional accessors try_function and try_variable above
> +     or the asserting accessor functions cgraph and varpool.  */
>    struct cgraph_node GTY ((tag ("SYMTAB_FUNCTION"))) x_function;
> -  /* Use varpool (symbol) accessor to get varpool_node.  */
>    struct varpool_node GTY ((tag ("SYMTAB_VARIABLE"))) x_variable;
>  };
>
> +inline bool
> +symtab_node_def::is_function ()
> +{
> +  return symbol.type == SYMTAB_FUNCTION;
> +}
> +
> +inline bool
> +symtab_node_def::is_variable ()
> +{
> +  return symbol.type == SYMTAB_VARIABLE;
> +}
> +
> +inline cgraph_node *
> +symtab_node_def::try_function ()
> +{
> +  return is_function () ? &x_function : NULL;
> +}
> +
> +inline varpool_node *
> +symtab_node_def::try_variable()
> +{
> +  return is_variable () ? &x_variable : NULL;
> +}
> +
> +
>  extern GTY(()) symtab_node symtab_nodes;
>  extern GTY(()) int cgraph_n_nodes;
>  extern GTY(()) int cgraph_max_uid;
> @@ -677,7 +710,7 @@ bool cgraph_maybe_hot_edge_p (struct cgr
>  bool cgraph_optimize_for_size_p (struct cgraph_node *);
>
>  /* In varpool.c  */
> -struct varpool_node *varpool_node (tree);
> +struct varpool_node *varpool_node_for_tree (tree);
>  struct varpool_node *varpool_node_for_asm (tree asmname);
>  void varpool_mark_needed_node (struct varpool_node *);
>  void debug_varpool (void);
> @@ -705,19 +738,6 @@ bool varpool_for_node_and_aliases (struc
>  			           void *, bool);
>  void varpool_add_new_variable (tree);
>
> -/* Return true when NODE is function.  */
> -static inline bool
> -symtab_function_p (symtab_node node)
> -{
> -  return node->symbol.type == SYMTAB_FUNCTION;
> -}
> -
> -/* Return true when NODE is variable.  */
> -static inline bool
> -symtab_variable_p (symtab_node node)
> -{
> -  return node->symbol.type == SYMTAB_VARIABLE;
> -}
>
>  /* Return callgraph node for given symbol and check it is a function. */
>  static inline struct cgraph_node *
> @@ -790,10 +810,8 @@ varpool_first_variable (void)
>  {
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
> -    {
> -      if (symtab_variable_p (node))
> -	return varpool (node);
> -    }
> +    if (varpool_node *vnode = node->try_variable ())
> +      return vnode;
>    return NULL;
>  }
>
> @@ -803,10 +821,8 @@ varpool_next_variable (struct varpool_no
>  {
>    symtab_node node1 = (symtab_node) node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
> -    {
> -      if (symtab_variable_p (node1))
> -	return varpool (node1);
> -    }
> +    if (varpool_node *vnode1 = node1->try_variable ())
> +      return vnode1;
>    return NULL;
>  }
>  /* Walk all variables.  */
> @@ -822,9 +838,9 @@ varpool_first_static_initializer (void)
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
>      {
> -      if (symtab_variable_p (node)
> -	  && DECL_INITIAL (node->symbol.decl))
> -	return varpool (node);
> +      varpool_node *vnode = node->try_variable ();
> +      if (vnode && DECL_INITIAL (node->symbol.decl))
> +	return vnode;
>      }
>    return NULL;
>  }
> @@ -836,9 +852,9 @@ varpool_next_static_initializer (struct
>    symtab_node node1 = (symtab_node) node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
>      {
> -      if (symtab_variable_p (node1)
> -	  && DECL_INITIAL (node1->symbol.decl))
> -	return varpool (node1);
> +      varpool_node *vnode1 = node1->try_variable ();
> +      if (vnode1 && DECL_INITIAL (node1->symbol.decl))
> +	return vnode1;
>      }
>    return NULL;
>  }
> @@ -855,8 +871,9 @@ varpool_first_defined_variable (void)
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
>      {
> -      if (symtab_variable_p (node) && varpool (node)->analyzed)
> -	return varpool (node);
> +      varpool_node *vnode = node->try_variable ();
> +      if (vnode && vnode->analyzed)
> +	return vnode;
>      }
>    return NULL;
>  }
> @@ -868,8 +885,9 @@ varpool_next_defined_variable (struct va
>    symtab_node node1 = (symtab_node) node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
>      {
> -      if (symtab_variable_p (node1) && varpool (node1)->analyzed)
> -	return varpool (node1);
> +      varpool_node *vnode1 = node1->try_variable ();
> +      if (vnode1 && vnode1->analyzed)
> +	return vnode1;
>      }
>    return NULL;
>  }
> @@ -885,8 +903,9 @@ cgraph_first_defined_function (void)
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
>      {
> -      if (symtab_function_p (node) && cgraph (node)->analyzed)
> -	return cgraph (node);
> +      cgraph_node *cn = node->try_function ();
> +      if (cn && cn->analyzed)
> +	return cn;
>      }
>    return NULL;
>  }
> @@ -898,8 +917,9 @@ cgraph_next_defined_function (struct cgr
>    symtab_node node1 = (symtab_node) node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
>      {
> -      if (symtab_function_p (node1) && cgraph (node1)->analyzed)
> -	return cgraph (node1);
> +      cgraph_node *cn1 = node1->try_function ();
> +      if (cn1 && cn1->analyzed)
> +	return cn1;
>      }
>    return NULL;
>  }
> @@ -915,10 +935,8 @@ cgraph_first_function (void)
>  {
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
> -    {
> -      if (symtab_function_p (node))
> -	return cgraph (node);
> -    }
> +    if (cgraph_node *cn = node->try_function ())
> +      return cn;
>    return NULL;
>  }
>
> @@ -928,10 +946,8 @@ cgraph_next_function (struct cgraph_node
>  {
>    symtab_node node1 = (symtab_node) node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
> -    {
> -      if (symtab_function_p (node1))
> -	return cgraph (node1);
> -    }
> +    if (cgraph_node *cn1 = node1->try_function ())
> +      return cn1;
>    return NULL;
>  }
>  /* Walk all functions.  */
> @@ -958,9 +974,9 @@ cgraph_first_function_with_gimple_body (
>    symtab_node node;
>    for (node = symtab_nodes; node; node = node->symbol.next)
>      {
> -      if (symtab_function_p (node)
> -	  && cgraph_function_with_gimple_body_p (cgraph (node)))
> -	return cgraph (node);
> +      cgraph_node *cn = node->try_function ();
> +      if (cn && cgraph_function_with_gimple_body_p (cn))
> +	return cn;
>      }
>    return NULL;
>  }
> @@ -972,9 +988,9 @@ cgraph_next_function_with_gimple_body (s
>    symtab_node node1 = node->symbol.next;
>    for (; node1; node1 = node1->symbol.next)
>      {
> -      if (symtab_function_p (node1)
> -	  && cgraph_function_with_gimple_body_p (cgraph (node1)))
> -	return cgraph (node1);
> +      cgraph_node *cn1 = node1->try_function ();
> +      if (cn1 && cgraph_function_with_gimple_body_p (cn1))
> +	return cn1;
>      }
>    return NULL;
>  }
> @@ -1173,7 +1189,7 @@ cgraph_alias_aliased_node (struct cgraph
>
>    ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
>    gcc_checking_assert (ref->use == IPA_REF_ALIAS);
> -  if (symtab_function_p (ref->referred))
> +  if (ref->referred->is_function ())
>      return ipa_ref_node (ref);
>    return NULL;
>  }
> @@ -1187,7 +1203,7 @@ varpool_alias_aliased_node (struct varpo
>
>    ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
>    gcc_checking_assert (ref->use == IPA_REF_ALIAS);
> -  if (symtab_variable_p (ref->referred))
> +  if (ref->referred->is_variable ())
>      return ipa_ref_varpool_node (ref);
>    return NULL;
>  }
> Index: gcc/tree-emutls.c
> ===================================================================
> --- gcc/tree-emutls.c	(revision 191403)
> +++ gcc/tree-emutls.c	(working copy)
> @@ -260,7 +260,7 @@ get_emutls_init_templ_addr (tree decl)
>    /* Create varpool node for the new variable and finalize it if it is
>       not external one.  */
>    if (DECL_EXTERNAL (to))
> -    varpool_node (to);
> +    varpool_node_for_tree (to);
>    else
>      varpool_add_new_variable (to);
>    return build_fold_addr_expr (to);
> @@ -332,7 +332,7 @@ new_emutls_decl (tree decl, tree alias_o
>    /* Create varpool node for the new variable and finalize it if it is
>       not external one.  */
>    if (DECL_EXTERNAL (to))
> -    varpool_node (to);
> +    varpool_node_for_tree (to);
>    else if (!alias_of)
>      varpool_add_new_variable (to);
>    else
> Index: gcc/ipa-reference.c
> ===================================================================
> --- gcc/ipa-reference.c	(revision 191403)
> +++ gcc/ipa-reference.c	(working copy)
> @@ -482,7 +482,7 @@ analyze_function (struct cgraph_node *fn
>    local = init_function_info (fn);
>    for (i = 0; ipa_ref_list_reference_iterate (&fn->symbol.ref_list,
> i, ref); i++)
>      {
> -      if (!symtab_variable_p (ref->referred))
> +      if (!ref->referred->is_variable ())
>  	continue;
>        var = ipa_ref_varpool_node (ref)->symbol.decl;
>        if (!is_proper_for_analysis (var))
> @@ -979,8 +979,6 @@ stream_out_bitmap (struct lto_simple_out
>  static void
>  ipa_reference_write_optimization_summary (void)
>  {
> -  struct cgraph_node *node;
> -  symtab_node snode;
>    struct lto_simple_output_block *ob
>      = lto_create_simple_output_block (LTO_section_ipa_reference);
>    unsigned int count = 0;
> @@ -994,18 +992,16 @@ ipa_reference_write_optimization_summary
>    /* See what variables we are interested in.  */
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      struct varpool_node *vnode;
> -      snode = lto_symtab_encoder_deref (encoder, i);
> -      if (!symtab_variable_p (snode))
> -	continue;
> -      vnode = varpool (snode);
> -      if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      varpool_node *vnode = snode->try_variable ();
> +      if (vnode
> +	  && bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
>  	  && referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder))
>  	{
>  	  tree decl = vnode->symbol.decl;
>  	  bitmap_set_bit (ltrans_statics, DECL_UID (decl));
>  	  splay_tree_insert (reference_vars_to_consider,
> -			     DECL_UID (decl), (splay_tree_value)decl);
> +			 DECL_UID (decl), (splay_tree_value)decl);
>  	  ltrans_statics_bitcount ++;
>  	}
>      }
> @@ -1013,10 +1009,12 @@ ipa_reference_write_optimization_summary
>
>    if (ltrans_statics_bitcount)
>      for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
> -      if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder,
> i))
> -	  && write_node_summary_p (cgraph (snode),
> -				   encoder, ltrans_statics))
> +      {
> +	symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +	cgraph_node *cnode = snode->try_function ();
> +	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
>  	  count++;
> +      }
>
>    streamer_write_uhwi_stream (ob->main_stream, count);
>    if (count)
> @@ -1027,17 +1025,15 @@ ipa_reference_write_optimization_summary
>    if (ltrans_statics_bitcount)
>      for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>        {
> -	snode = lto_symtab_encoder_deref (encoder, i);
> -	if (!symtab_function_p (snode))
> -	  continue;
> -	node = cgraph (snode);
> -	if (write_node_summary_p (node, encoder, ltrans_statics))
> +	symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +	cgraph_node *cnode = snode->try_function ();
> +	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
>  	  {
>  	    ipa_reference_optimization_summary_t info;
>  	    int node_ref;
>
> -	    info = get_reference_optimization_summary (node);
> -	    node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
> +	    info = get_reference_optimization_summary (cnode);
> +	    node_ref = lto_symtab_encoder_encode (encoder, snode);
>  	    streamer_write_uhwi_stream (ob->main_stream, node_ref);
>
>  	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
> Index: gcc/cgraphunit.c
> ===================================================================
> --- gcc/cgraphunit.c	(revision 191403)
> +++ gcc/cgraphunit.c	(working copy)
> @@ -388,7 +388,8 @@ referred_to_p (symtab_node node)
>    if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
>      return true;
>    /* For functions check also calls.  */
> -  if (symtab_function_p (node) && cgraph (node)->callers)
> +  cgraph_node *cn = node->try_function ();
> +  if (cn && cn->callers)
>      return true;
>    return false;
>  }
> @@ -818,7 +819,7 @@ process_function_and_variable_attributes
>  void
>  varpool_finalize_decl (tree decl)
>  {
> -  struct varpool_node *node = varpool_node (decl);
> +  struct varpool_node *node = varpool_node_for_tree (decl);
>
>    gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
>
> @@ -845,6 +846,35 @@ varpool_finalize_decl (tree decl)
>      varpool_assemble_decl (node);
>  }
>
> +
> +/* Determine if a symbol is finalized and needed.  */
> +
> +inline static bool
> +symbol_finalized_and_needed (symtab_node node)
> +{
> +  if (cgraph_node *cnode = node->try_function ())
> +    return cnode->local.finalized
> +	   && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
> +  if (varpool_node *vnode = node->try_variable ())
> +    return vnode->finalized
> +	   && !DECL_EXTERNAL (vnode->symbol.decl)
> +	   && decide_is_variable_needed (vnode, vnode->symbol.decl);
> +  return false;
> +}
> +
> +/* Determine if a symbol is finalized.  */
> +
> +inline static bool
> +symbol_finalized (symtab_node node)
> +{
> +  if (cgraph_node *cnode= node->try_function ())
> +    return cnode->local.finalized;
> +  if (varpool_node *vnode = node->try_variable ())
> +    return vnode->finalized;
> +  return false;
> +}
> +
> +
>  /* Discover all functions and variables that are trivially needed, analyze
>     them as well as all functions and variables referred by them  */
>
> @@ -879,13 +909,7 @@ cgraph_analyze_functions (void)
>  	   node != (symtab_node)first_analyzed
>  	   && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
>  	{
> -	  if ((symtab_function_p (node)
> -	       && cgraph (node)->local.finalized
> -	       && cgraph_decide_is_function_needed (cgraph (node),
> node->symbol.decl))
> -	      || (symtab_variable_p (node)
> -		  && varpool (node)->finalized
> -		  && !DECL_EXTERNAL (node->symbol.decl)
> -		  && decide_is_variable_needed (varpool (node), node->symbol.decl)))
> +	  if (symbol_finalized_and_needed (node))
>  	    {
>  	      enqueue_node (node);
>  	      if (!changed && cgraph_dump_file)
> @@ -912,18 +936,15 @@ cgraph_analyze_functions (void)
>  	  changed = true;
>  	  node = first;
>  	  first = (symtab_node)first->symbol.aux;
> -	  if (symtab_function_p (node) && cgraph (node)->local.finalized)
> +	  cgraph_node *cnode = node->try_function ();
> +	  if (cnode && cnode->local.finalized)
>  	    {
>  	      struct cgraph_edge *edge;
> -	      struct cgraph_node *cnode;
> -	      tree decl;
> -
> -	      cnode = cgraph (node);
> -	      decl = cnode->symbol.decl;
> +	      tree decl = cnode->symbol.decl;
>
> -	      /* ??? It is possible to create extern inline function and later
> using
> -		 weak alias attribute to kill its body. See
> -		 gcc.c-torture/compile/20011119-1.c  */
> +	      /* ??? It is possible to create extern inline function
> +	      and later using weak alias attribute to kill its body.
> +	      See gcc.c-torture/compile/20011119-1.c  */
>  	      if (!DECL_STRUCT_FUNCTION (decl)
>  		  && (!cnode->alias || !cnode->thunk.alias)
>  		  && !cnode->thunk.thunk_p)
> @@ -938,23 +959,25 @@ cgraph_analyze_functions (void)
>
>  	      for (edge = cnode->callees; edge; edge = edge->next_callee)
>  		if (edge->callee->local.finalized)
> -		  enqueue_node ((symtab_node)edge->callee);
> +		   enqueue_node ((symtab_node)edge->callee);
>
> -	      /* If decl is a clone of an abstract function, mark that abstract
> -		 function so that we don't release its body. The DECL_INITIAL() of that
> -		 abstract function declaration will be later needed to output debug
> -		 info.  */
> +	      /* If decl is a clone of an abstract function,
> +	      mark that abstract function so that we don't release its body.
> +	      The DECL_INITIAL() of that abstract function declaration
> +	      will be later needed to output debug info.  */
>  	      if (DECL_ABSTRACT_ORIGIN (decl))
>  		{
> -		  struct cgraph_node *origin_node;
> -		  origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
> +		  struct cgraph_node *origin_node
> +	    	  = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
>  		  origin_node->abstract_and_needed = true;
>  		}
> -
>  	    }
> -	  else if (symtab_variable_p (node)
> -		   && varpool (node)->finalized)
> -	    varpool_analyze_node (varpool (node));
> +	  else
> +	    {
> +	      varpool_node *vnode = node->try_variable ();
> +	      if (vnode && vnode->finalized)
> +		varpool_analyze_node (vnode);
> +	    }
>
>  	  if (node->symbol.same_comdat_group)
>  	    {
> @@ -965,8 +988,7 @@ cgraph_analyze_functions (void)
>  		enqueue_node (next);
>  	    }
>  	  for (i = 0; ipa_ref_list_reference_iterate
> (&node->symbol.ref_list, i, ref); i++)
> -	    if ((symtab_function_p (ref->referred) && cgraph
> (ref->referred)->local.finalized)
> -		|| (symtab_variable_p (ref->referred) && varpool
> (ref->referred)->finalized))
> +	    if (symbol_finalized (ref->referred))
>  	      enqueue_node (ref->referred);
>            cgraph_process_new_functions ();
>  	}
> @@ -994,10 +1016,9 @@ cgraph_analyze_functions (void)
>  	  symtab_remove_node (node);
>  	  continue;
>  	}
> -      if (symtab_function_p (node))
> +      if (cgraph_node *cnode = node->try_function ())
>  	{
>  	  tree decl = node->symbol.decl;
> -	  struct cgraph_node *cnode = cgraph (node);
>
>  	  if (cnode->local.finalized && !gimple_has_body_p (decl)
>  	      && (!cnode->alias || !cnode->thunk.alias)
> @@ -1079,7 +1100,7 @@ handle_alias_pairs (void)
>  	}
>
>        if (TREE_CODE (p->decl) == FUNCTION_DECL
> -          && target_node && symtab_function_p (target_node))
> +          && target_node && target_node->is_function ())
>  	{
>  	  struct cgraph_node *src_node = cgraph_get_node (p->decl);
>  	  if (src_node && src_node->local.finalized)
> @@ -1088,7 +1109,7 @@ handle_alias_pairs (void)
>  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
>  	}
>        else if (TREE_CODE (p->decl) == VAR_DECL
> -	       && target_node && symtab_variable_p (target_node))
> +	       && target_node && target_node->is_variable ())
>  	{
>  	  varpool_create_variable_alias (p->decl, target_node->symbol.decl);
>  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
> Index: gcc/cp/decl2.c
> ===================================================================
> --- gcc/cp/decl2.c	(revision 191403)
> +++ gcc/cp/decl2.c	(working copy)
> @@ -1773,7 +1773,7 @@ import_export_class (tree ctype)
>  static bool
>  var_finalized_p (tree var)
>  {
> -  return varpool_node (var)->finalized;
> +  return varpool_node_for_tree (var)->finalized;
>  }
>
>  /* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
> @@ -1891,7 +1891,7 @@ maybe_emit_vtables (tree ctype)
>  	TREE_ASM_WRITTEN (vtbl) = 1;
>        else if (DECL_ONE_ONLY (vtbl))
>  	{
> -	  current = varpool_node (vtbl);
> +	  current = varpool_node_for_tree (vtbl);
>  	  if (last)
>  	    symtab_add_to_same_comdat_group ((symtab_node) current,
> (symtab_node) last);
>  	  last = current;
> Index: gcc/ipa-ref.c
> ===================================================================
> --- gcc/ipa-ref.c	(revision 191403)
> +++ gcc/ipa-ref.c	(working copy)
> @@ -42,7 +42,7 @@ ipa_record_reference (symtab_node referr
>    struct ipa_ref_list *list, *list2;
>    VEC(ipa_ref_t,gc) *old_references;
>
> -  gcc_checking_assert (!stmt || symtab_function_p (referring_node));
> +  gcc_checking_assert (!stmt || referring_node->is_function ());
>    gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);
>
>    list = &referring_node->symbol.ref_list;
> Index: gcc/lto-cgraph.c
> ===================================================================
> --- gcc/lto-cgraph.c	(revision 191403)
> +++ gcc/lto-cgraph.c	(working copy)
> @@ -665,7 +665,7 @@ add_references (lto_symtab_encoder_t enc
>    int i;
>    struct ipa_ref *ref;
>    for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
> -    if (symtab_function_p (ref->referred))
> +    if (ref->referred->is_function ())
>        add_node_to (encoder, ipa_ref_node (ref), false);
>      else
>        {
> @@ -719,9 +719,8 @@ compute_ltrans_boundary (lto_symtab_enco
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
>        symtab_node node = lto_symtab_encoder_deref (encoder, i);
> -      if (symtab_variable_p (node))
> +      if (varpool_node *vnode = node->try_variable ())
>  	{
> -	  struct varpool_node *vnode = varpool (node);
>  	  if (DECL_INITIAL (vnode->symbol.decl)
>  	      && !lto_symtab_encoder_encode_initializer_p (encoder,
>  							   vnode)
> @@ -785,8 +784,8 @@ output_symtab (void)
>    for (i = 0; i < n_nodes; i++)
>      {
>        symtab_node node = lto_symtab_encoder_deref (encoder, i);
> -      if (symtab_function_p (node))
> -        lto_output_node (ob, cgraph (node), encoder);
> +      if (cgraph_node *cnode = node->try_function ())
> +        lto_output_node (ob, cnode, encoder);
>        else
>          lto_output_varpool_node (ob, varpool (node), encoder);
>  	
> @@ -972,7 +971,7 @@ input_varpool_node (struct lto_file_decl
>    order = streamer_read_hwi (ib) + order_base;
>    decl_index = streamer_read_uhwi (ib);
>    var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
> -  node = varpool_node (var_decl);
> +  node = varpool_node_for_tree (var_decl);
>    node->symbol.order = order;
>    if (order >= symtab_order)
>      symtab_order = order + 1;
> @@ -1133,14 +1132,14 @@ input_cgraph_1 (struct lto_file_decl_dat
>    /* AUX pointers should be all non-zero for function nodes read from
> the stream.  */
>  #ifdef ENABLE_CHECKING
>    FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
> -    gcc_assert (node->symbol.aux || !symtab_function_p (node));
> +    gcc_assert (node->symbol.aux || !node->is_function ());
>  #endif
>    FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
>      {
>        int ref;
> -      if (symtab_function_p (node))
> +      if (cgraph_node *cnode = node->try_function ())
>  	{
> -	  ref = (int) (intptr_t) cgraph (node)->global.inlined_to;
> +	  ref = (int) (intptr_t) cnode->global.inlined_to;
>
>  	  /* We share declaration of builtins, so we may read same node twice.
> */
>  	  if (!node->symbol.aux)
> @@ -1149,9 +1148,9 @@ input_cgraph_1 (struct lto_file_decl_dat
>
>  	  /* Fixup inlined_to from reference to pointer.  */
>  	  if (ref != LCC_NOT_FOUND)
> -	    cgraph (node)->global.inlined_to = cgraph (VEC_index
> (symtab_node, nodes, ref));
> +	    cnode->global.inlined_to = cgraph (VEC_index (symtab_node, nodes,
> ref));
>  	  else
> -	    cgraph (node)->global.inlined_to = NULL;
> +	    cnode->global.inlined_to = NULL;
>  	}
>
>        ref = (int) (intptr_t) node->symbol.same_comdat_group;
> @@ -1163,7 +1162,7 @@ input_cgraph_1 (struct lto_file_decl_dat
>  	node->symbol.same_comdat_group = NULL;
>      }
>    FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
> -    node->symbol.aux = symtab_function_p (node) ? (void *)1 : NULL;
> +    node->symbol.aux = node->is_function () ? (void *)1 : NULL;
>    return nodes;
>  }
>
> @@ -1437,7 +1436,6 @@ output_node_opt_summary (struct output_b
>  static void
>  output_cgraph_opt_summary (void)
>  {
> -  symtab_node node;
>    int i, n_nodes;
>    lto_symtab_encoder_t encoder;
>    struct output_block *ob = create_output_block
> (LTO_section_cgraph_opt_sum);
> @@ -1447,18 +1445,21 @@ output_cgraph_opt_summary (void)
>    encoder = ob->decl_state->symtab_node_encoder;
>    n_nodes = lto_symtab_encoder_size (encoder);
>    for (i = 0; i < n_nodes; i++)
> -    if (symtab_function_p (node = lto_symtab_encoder_deref (encoder, i))
> -	&& output_cgraph_opt_summary_p (cgraph (node)))
> -      count++;
> +    {
> +      symtab_node node = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = node->try_function ();
> +      if (cnode && output_cgraph_opt_summary_p (cnode))
> +	count++;
> +    }
>    streamer_write_uhwi (ob, count);
>    for (i = 0; i < n_nodes; i++)
>      {
> -      node = lto_symtab_encoder_deref (encoder, i);
> -      if (symtab_function_p (node)
> -	  && output_cgraph_opt_summary_p (cgraph (node)))
> +      symtab_node node = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = node->try_function ();
> +      if (cnode && output_cgraph_opt_summary_p (cnode))
>  	{
>  	  streamer_write_uhwi (ob, i);
> -	  output_node_opt_summary (ob, cgraph (node), encoder);
> +	  output_node_opt_summary (ob, cnode, encoder);
>  	}
>      }
>    produce_asm (ob, NULL);
> Index: gcc/lto-streamer-out.c
> ===================================================================
> --- gcc/lto-streamer-out.c	(revision 191403)
> +++ gcc/lto-streamer-out.c	(working copy)
> @@ -975,7 +975,6 @@ copy_function (struct cgraph_node *node)
>  static void
>  lto_output (void)
>  {
> -  struct cgraph_node *node;
>    struct lto_out_decl_state *decl_state;
>  #ifdef ENABLE_CHECKING
>    bitmap output = lto_bitmap_alloc ();
> @@ -991,10 +990,9 @@ lto_output (void)
>    for (i = 0; i < n_nodes; i++)
>      {
>        symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> -      if (!symtab_function_p (snode))
> -	continue;
> -      node = cgraph (snode);
> -      if (lto_symtab_encoder_encode_body_p (encoder, node)
> +      cgraph_node *node = snode->try_function ();
> +      if (node
> +	  && lto_symtab_encoder_encode_body_p (encoder, node)
>  	  && !node->alias
>  	  && !node->thunk.thunk_p)
>  	{
> @@ -1288,8 +1286,6 @@ produce_symtab (struct output_block *ob)
>    struct streamer_tree_cache_d *cache = ob->writer_cache;
>    char *section_name = lto_get_section_name (LTO_section_symtab, NULL,
> NULL);
>    struct pointer_set_t *seen;
> -  struct cgraph_node *node;
> -  struct varpool_node *vnode;
>    struct lto_output_stream stream;
>    lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
>    int i;
> @@ -1305,49 +1301,52 @@ produce_symtab (struct output_block *ob)
>       This is done so only to handle duplicated symbols in cgraph.  */
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = snode->try_function ();
> +      if (!cnode)
>  	continue;
> -      node = cgraph (lto_symtab_encoder_deref (encoder, i));
> -      if (DECL_EXTERNAL (node->symbol.decl))
> +      if (DECL_EXTERNAL (cnode->symbol.decl))
>  	continue;
> -      if (DECL_COMDAT (node->symbol.decl)
> -	  && cgraph_comdat_can_be_unshared_p (node))
> +      if (DECL_COMDAT (cnode->symbol.decl)
> +	  && cgraph_comdat_can_be_unshared_p (cnode))
>  	continue;
> -      if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
> +      if ((cnode->alias && !cnode->thunk.alias) ||
> cnode->global.inlined_to)
>  	continue;
> -      write_symbol (cache, &stream, node->symbol.decl, seen, false);
> +      write_symbol (cache, &stream, cnode->symbol.decl, seen, false);
>      }
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = snode->try_function ();
> +      if (!cnode)
>  	continue;
> -      node = cgraph (lto_symtab_encoder_deref (encoder, i));
> -      if (!DECL_EXTERNAL (node->symbol.decl))
> +      if (!DECL_EXTERNAL (cnode->symbol.decl))
>  	continue;
>        /* We keep around unused extern inlines in order to be able to
> inline
>  	 them indirectly or via vtables.  Do not output them to symbol
>  	 table: they end up being undefined and just consume space.  */
> -      if (!node->symbol.address_taken && !node->callers)
> +      if (!cnode->symbol.address_taken && !cnode->callers)
>  	continue;
> -      if (DECL_COMDAT (node->symbol.decl)
> -	  && cgraph_comdat_can_be_unshared_p (node))
> +      if (DECL_COMDAT (cnode->symbol.decl)
> +	  && cgraph_comdat_can_be_unshared_p (cnode))
>  	continue;
> -      if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
> +      if ((cnode->alias && !cnode->thunk.alias) ||
> cnode->global.inlined_to)
>  	continue;
> -      write_symbol (cache, &stream, node->symbol.decl, seen, false);
> +      write_symbol (cache, &stream, cnode->symbol.decl, seen, false);
>      }
>
>    /* Write all variables.  */
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      varpool_node *vnode = snode->try_variable ();
> +      if (!vnode)
>  	continue;
> -      vnode = varpool (lto_symtab_encoder_deref (encoder, i));
>        if (DECL_EXTERNAL (vnode->symbol.decl))
>  	continue;
>        /* COMDAT virtual tables can be unshared.  Do not declare them
> -	 in the LTO symbol table to prevent linker from forcing them
> -	 into the output. */
> +	in the LTO symbol table to prevent linker from forcing them
> +	into the output. */
>        if (DECL_COMDAT (vnode->symbol.decl)
>  	  && !vnode->symbol.force_output
>  	  && vnode->finalized
> @@ -1359,9 +1358,10 @@ produce_symtab (struct output_block *ob)
>      }
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      varpool_node *vnode = snode->try_variable ();
> +      if (!vnode)
>  	continue;
> -      vnode = varpool (lto_symtab_encoder_deref (encoder, i));
>        if (!DECL_EXTERNAL (vnode->symbol.decl))
>  	continue;
>        if (DECL_COMDAT (vnode->symbol.decl)
> Index: gcc/ada/gcc-interface/utils.c
> ===================================================================
> --- gcc/ada/gcc-interface/utils.c	(revision 191403)
> +++ gcc/ada/gcc-interface/utils.c	(working copy)
> @@ -5582,7 +5582,7 @@ gnat_write_global_declarations (void)
>  		      void_type_node);
>        TREE_STATIC (dummy_global) = 1;
>        TREE_ASM_WRITTEN (dummy_global) = 1;
> -      node = varpool_node (dummy_global);
> +      node = varpool_node_for_tree (dummy_global);
>        node->symbol.force_output = 1;
>
>        while (!VEC_empty (tree, types_used_by_cur_var_decl))
> Index: gcc/ipa.c
> ===================================================================
> --- gcc/ipa.c	(revision 191403)
> +++ gcc/ipa.c	(working copy)
> @@ -84,7 +84,7 @@ process_references (struct ipa_ref_list
>    struct ipa_ref *ref;
>    for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
>      {
> -      if (symtab_function_p (ref->referred))
> +      if (ref->referred->is_function ())
>  	{
>  	  struct cgraph_node *node = ipa_ref_node (ref);
>
> @@ -290,10 +290,8 @@ symtab_remove_unreachable_nodes (bool be
>  			      before_inlining_p, reachable);
>  	}
>
> -      if (symtab_function_p (node))
> +      if (cgraph_node *cnode = node->try_function ())
>  	{
> -	  struct cgraph_node *cnode = cgraph (node);
> -
>  	  /* Mark the callees reachable unless they are direct calls to extern
>   	     inline functions we decided to not inline.  */
>  	  if (!in_boundary_p)
> @@ -332,18 +330,18 @@ symtab_remove_unreachable_nodes (bool be
>  	    }
>  	}
>        /* When we see constructor of external variable, keep referred
> nodes in the
> -	 boundary.  This will also hold initializers of the external vars NODE
> -	 reffers to.  */
> -      if (symtab_variable_p (node)
> +	boundary.  This will also hold initializers of the external vars NODE
> +	refers to.  */
> +      varpool_node *vnode = node->try_variable ();
> +      if (vnode
>  	  && DECL_EXTERNAL (node->symbol.decl)
> -	  && !varpool (node)->alias
> +	  && !vnode->alias
>  	  && in_boundary_p)
> -        {
> -	  int i;
> +	{
>  	  struct ipa_ref *ref;
> -	  for (i = 0; ipa_ref_list_reference_iterate
> (&node->symbol.ref_list, i, ref); i++)
> +	  for (int i = 0; ipa_ref_list_reference_iterate
> (&node->symbol.ref_list, i, ref); i++)
>  	    enqueue_node (ref->referred, &first, reachable);
> -        }
> +	}
>      }
>
>    /* Remove unreachable functions.   */
> @@ -526,7 +524,7 @@ cgraph_address_taken_from_non_vtable_p (
>      if (ref->use == IPA_REF_ADDR)
>        {
>  	struct varpool_node *node;
> -	if (symtab_function_p (ref->referring))
> +	if (ref->referring->is_function ())
>  	  return true;
>  	node = ipa_ref_referring_varpool_node (ref);
>  	if (!DECL_VIRTUAL_P (node->symbol.decl))
> Index: gcc/ipa-inline-analysis.c
> ===================================================================
> --- gcc/ipa-inline-analysis.c	(revision 191403)
> +++ gcc/ipa-inline-analysis.c	(working copy)
> @@ -3816,22 +3816,25 @@ void
>  inline_write_summary (void)
>  {
>    struct cgraph_node *node;
> -  symtab_node snode;
>    struct output_block *ob = create_output_block
> (LTO_section_inline_summary);
>    lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
>    unsigned int count = 0;
>    int i;
>
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
> -    if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i))
> -	&& cgraph (snode)->analyzed)
> -      count++;
> +    {
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = snode->try_function ();
> +      if (cnode && cnode->analyzed)
> +	count++;
> +    }
>    streamer_write_uhwi (ob, count);
>
>    for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
>      {
> -      if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder,
> i))
> -	  && (node = cgraph (snode))->analyzed)
> +      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
> +      cgraph_node *cnode = snode->try_function ();
> +      if (cnode && (node = cnode)->analyzed)
>  	{
>  	  struct inline_summary *info = inline_summary (node);
>  	  struct bitpack_d bp;
> @@ -3839,7 +3842,7 @@ inline_write_summary (void)
>  	  int i;
>  	  size_time_entry *e;
>  	  struct condition *c;
> -
> +
>  	  streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder,
> (symtab_node)node));
>  	  streamer_write_hwi (ob, info->estimated_self_stack_size);
>  	  streamer_write_hwi (ob, info->self_size);
> @@ -3858,7 +3861,7 @@ inline_write_summary (void)
>  	      bp_pack_value (&bp, c->by_ref, 1);
>  	      streamer_write_bitpack (&bp);
>  	      if (c->agg_contents)
> -		streamer_write_uhwi (ob, c->offset);
> +	        streamer_write_uhwi (ob, c->offset);
>  	    }
>  	  streamer_write_uhwi (ob, VEC_length (size_time_entry, info->entry));
>  	  for (i = 0;
> Index: gcc/lto/lto.c
> ===================================================================
> --- gcc/lto/lto.c	(revision 191403)
> +++ gcc/lto/lto.c	(working copy)
> @@ -2619,12 +2619,17 @@ lto_wpa_write_files (void)
>  	      if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
>  		{
>  	          fprintf (cgraph_dump_file, "%s ", symtab_node_asm_name (node));
> -		  if (symtab_function_p (node)
> -		      && lto_symtab_encoder_encode_body_p (part->encoder, cgraph
> (node)))
> +		  cgraph_node *cnode = node->try_function ();
> +		  if (cnode
> +		      && lto_symtab_encoder_encode_body_p (part->encoder, cnode))
>  		    fprintf (cgraph_dump_file, "(body included)");
> -		  else if (symtab_variable_p (node)
> -		           && lto_symtab_encoder_encode_initializer_p
> (part->encoder, varpool (node)))
> -		    fprintf (cgraph_dump_file, "(initializer included)");
> +		  else
> +		    {
> +		      varpool_node *vnode = node->try_variable ();
> +		      if (vnode
> +			  && lto_symtab_encoder_encode_initializer_p (part->encoder, vnode))
> +			fprintf (cgraph_dump_file, "(initializer included)");
> +		    }
>  		}
>  	    }
>  	  fprintf (cgraph_dump_file, "\n");
> Index: gcc/lto/lto-partition.c
> ===================================================================
> --- gcc/lto/lto-partition.c	(revision 191403)
> +++ gcc/lto/lto-partition.c	(working copy)
> @@ -55,22 +55,22 @@ get_symbol_class (symtab_node node)
>  {
>    /* Inline clones are always duplicated.
>       This include external delcarations.   */
> -  if (symtab_function_p (node)
> -      && cgraph (node)->global.inlined_to)
> +  cgraph_node *cnode = node->try_function ();
> +  if (cnode && cnode->global.inlined_to)
>      return SYMBOL_DUPLICATE;
>
>    /* External declarations are external.  */
>    if (DECL_EXTERNAL (node->symbol.decl))
>      return SYMBOL_EXTERNAL;
>
> -  if (symtab_variable_p (node))
> +  if (varpool_node *vnode = node->try_variable ())
>      {
>        /* Constant pool references use local symbol names that can not
>           be promoted global.  We should never put into a constant pool
>           objects that can not be duplicated across partitions.  */
>        if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
>  	return SYMBOL_DUPLICATE;
> -      gcc_checking_assert (varpool (node)->analyzed);
> +      gcc_checking_assert (vnode->analyzed);
>      }
>    /* Functions that are cloned may stay in callgraph even if they are
> unused.
>       Handle them as external; compute_ltrans_boundary take care to make
> @@ -145,7 +145,7 @@ add_references_to_partition (ltrans_part
>      /* References to a readonly variable may be constant foled into its
> value.
>         Recursively look into the initializers of the constant variable and
> add
>         references, too.  */
> -    else if (symtab_variable_p (ref->referred)
> +    else if (ref->referred->is_variable ()
>  	     && const_value_known_p (ref->referred->symbol.decl)
>  	     && !lto_symtab_encoder_in_partition_p (part->encoder,
> ref->referred))
>        {
> @@ -196,9 +196,8 @@ add_symbol_to_partition_1 (ltrans_partit
>      }
>    node->symbol.aux = (void *)((size_t)node->symbol.aux + 1);
>
> -  if (symtab_function_p (node))
> +  if (cgraph_node *cnode = node->try_function ())
>      {
> -      struct cgraph_node *cnode = cgraph (node);
>        struct cgraph_edge *e;
>        part->insns += inline_summary (cnode)->self_size;
>
> @@ -247,15 +246,15 @@ contained_in_symbol (symtab_node node)
>    if (lookup_attribute ("weakref",
>  			DECL_ATTRIBUTES (node->symbol.decl)))
>      return node;
> -  if (symtab_function_p (node))
> +  if (cgraph_node *cnode = node->try_function ())
>      {
> -      struct cgraph_node *cnode = cgraph_function_node (cgraph (node),
> NULL);
> +      cnode = cgraph_function_node (cnode, NULL);
>        if (cnode->global.inlined_to)
>  	cnode = cnode->global.inlined_to;
>        return (symtab_node) cnode;
>      }
> -  else if (symtab_variable_p (node))
> -    return (symtab_node) varpool_variable_node (varpool (node), NULL);
> +  else if (varpool_node *vnode = node->try_variable ())
> +    return (symtab_node) varpool_variable_node (vnode, NULL);
>    return node;
>  }
>
> @@ -302,8 +301,8 @@ undo_partition (ltrans_partition partiti
>  	pointer_set_destroy (partition->initializers_visited);
>        partition->initializers_visited = NULL;
>
> -      if (symtab_function_p (node))
> -        partition->insns -= inline_summary (cgraph (node))->self_size;
> +      if (cgraph_node *cnode = node->try_function ())
> +        partition->insns -= inline_summary (cnode)->self_size;
>        lto_symtab_encoder_delete_node (partition->encoder, node);
>        node->symbol.aux = (void *)((size_t)node->symbol.aux - 1);
>      }
> @@ -555,11 +554,10 @@ lto_balanced_map (void)
>  	  symtab_node snode = lto_symtab_encoder_deref (partition->encoder,
>  							last_visited_node);
>
> -	  if (symtab_function_p (snode))
> +	  if (cgraph_node *node = snode->try_function ())
>  	    {
>  	      struct cgraph_edge *edge;
>
> -	      node = cgraph (snode);
>  	      refs = &node->symbol.ref_list;
>
>  	      last_visited_node++;
> @@ -611,7 +609,7 @@ lto_balanced_map (void)
>  	  /* Compute boundary cost of IPA REF edges and at the same time look
> into
>  	     variables referenced from current partition and try to add them.  */
>  	  for (j = 0; ipa_ref_list_reference_iterate (refs, j, ref); j++)
> -	    if (symtab_variable_p (ref->referred))
> +	    if (ref->referred->is_variable ())
>  	      {
>  		int index;
>
> @@ -645,7 +643,7 @@ lto_balanced_map (void)
>  		  cost++;
>  	      }
>  	  for (j = 0; ipa_ref_list_referring_iterate (refs, j, ref); j++)
> -	    if (symtab_variable_p (ref->referring))
> +	    if (ref->referring->is_variable ())
>  	      {
>  		int index;
>
> Index: gcc/varasm.c
> ===================================================================
> --- gcc/varasm.c	(revision 191403)
> +++ gcc/varasm.c	(working copy)
> @@ -2221,7 +2221,7 @@ mark_decl_referenced (tree decl)
>      }
>    else if (TREE_CODE (decl) == VAR_DECL)
>      {
> -      struct varpool_node *node = varpool_node (decl);
> +      struct varpool_node *node = varpool_node_for_tree (decl);
>        /* C++ frontend use mark_decl_references to force COMDAT variables
>           to be output that might appear dead otherwise.  */
>        node->symbol.force_output = true;
> @@ -5549,7 +5549,7 @@ assemble_alias (tree decl, tree target)
>    if (TREE_CODE (decl) == FUNCTION_DECL)
>      cgraph_get_create_node (decl)->alias = true;
>    else
> -    varpool_node (decl)->alias = true;
> +    varpool_node_for_tree (decl)->alias = true;
>
>    /* If the target has already been emitted, we don't have to queue the
>       alias.  This saves a tad of memory.  */
> Index: gcc/symtab.c
> ===================================================================
> --- gcc/symtab.c	(revision 191403)
> +++ gcc/symtab.c	(working copy)
> @@ -239,8 +239,8 @@ symtab_unregister_node (symtab_node node
>    if (*slot == node)
>      {
>        symtab_node replacement_node = NULL;
> -      if (symtab_function_p (node))
> -	replacement_node = (symtab_node)cgraph_find_replacement_node (cgraph
> (node));
> +      if (cgraph_node *cnode = node->try_function ())
> +	replacement_node = (symtab_node)cgraph_find_replacement_node (cnode);
>        if (!replacement_node)
>  	htab_clear_slot (symtab_hash, slot);
>        else
> @@ -281,10 +281,10 @@ symtab_get_node (const_tree decl)
>  void
>  symtab_remove_node (symtab_node node)
>  {
> -  if (symtab_function_p (node))
> -    cgraph_remove_node (cgraph (node));
> -  else if (symtab_variable_p (node))
> -    varpool_remove_node (varpool (node));
> +  if (cgraph_node *cnode = node->try_function ())
> +    cgraph_remove_node (cnode);
> +  else if (varpool_node *vnode = node->try_variable ())
> +    varpool_remove_node (vnode);
>  }
>
>  /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
> @@ -514,10 +514,10 @@ dump_symtab_base (FILE *f, symtab_node n
>  void
>  dump_symtab_node (FILE *f, symtab_node node)
>  {
> -  if (symtab_function_p (node))
> -    dump_cgraph_node (f, cgraph (node));
> -  else if (symtab_variable_p (node))
> -    dump_varpool_node (f, varpool (node));
> +  if (cgraph_node *cnode = node->try_function ())
> +    dump_cgraph_node (f, cnode);
> +  else if (varpool_node *vnode = node->try_variable ())
> +    dump_varpool_node (f, vnode);
>  }
>
>  /* Dump symbol table.  */
> @@ -555,7 +555,7 @@ verify_symtab_base (symtab_node node)
>    bool error_found = false;
>    symtab_node hashed_node;
>
> -  if (symtab_function_p (node))
> +  if (node->is_function ())
>      {
>        if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL)
>  	{
> @@ -563,7 +563,7 @@ verify_symtab_base (symtab_node node)
>            error_found = true;
>  	}
>      }
> -  else if (symtab_variable_p (node))
> +  else if (node->is_variable ())
>      {
>        if (TREE_CODE (node->symbol.decl) != VAR_DECL)
>  	{
> @@ -651,8 +651,8 @@ verify_symtab_node (symtab_node node)
>      return;
>
>    timevar_push (TV_CGRAPH_VERIFY);
> -  if (symtab_function_p (node))
> -    verify_cgraph_node (cgraph (node));
> +  if (cgraph_node *cnode = node->try_function ())
> +    verify_cgraph_node (cnode);
>    else
>      if (verify_symtab_base (node))
>        {
> Index: gcc/passes.c
> ===================================================================
> --- gcc/passes.c	(revision 191403)
> +++ gcc/passes.c	(working copy)
> @@ -201,7 +201,7 @@ rest_of_decl_compilation (tree decl,
>      ;
>    else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
>  	   && TREE_STATIC (decl))
> -    varpool_node (decl);
> +    varpool_node_for_tree (decl);
>  }
>
>  /* Called after finishing a record, union or enumeral type.  */
> Index: gcc/varpool.c
> ===================================================================
> --- gcc/varpool.c	(revision 191403)
> +++ gcc/varpool.c	(working copy)
> @@ -39,7 +39,7 @@ along with GCC; see the file COPYING3.
>
>  /* Return varpool node assigned to DECL.  Create new one when needed.  */
>  struct varpool_node *
> -varpool_node (tree decl)
> +varpool_node_for_tree (tree decl)
>  {
>    struct varpool_node *node = varpool_get_node (decl);
>    gcc_assert (TREE_CODE (decl) == VAR_DECL
> @@ -114,9 +114,9 @@ debug_varpool (void)
>  struct varpool_node *
>  varpool_node_for_asm (tree asmname)
>  {
> -  symtab_node node = symtab_node_for_asm (asmname);
> -  if (node && symtab_variable_p (node))
> -    return varpool (node);
> +  if (symtab_node node = symtab_node_for_asm (asmname))
> +    if (varpool_node *vnode = node->try_variable ())
> +      return vnode;
>    return NULL;
>  }
>
> @@ -192,7 +192,7 @@ varpool_add_new_variable (tree decl)
>  {
>    struct varpool_node *node;
>    varpool_finalize_decl (decl);
> -  node = varpool_node (decl);
> +  node = varpool_node_for_tree (decl);
>    if (varpool_externally_visible_p (node, false))
>      node->symbol.externally_visible = true;
>  }
> @@ -232,7 +232,7 @@ varpool_analyze_node (struct varpool_nod
>      }
>    if (node->alias && node->alias_of)
>      {
> -      struct varpool_node *tgt = varpool_node (node->alias_of);
> +      struct varpool_node *tgt = varpool_node_for_tree (node->alias_of);
>        struct varpool_node *n;
>
>        for (n = tgt; n && n->alias;
> @@ -374,16 +374,21 @@ varpool_remove_unreferenced_decls (void)
>  	  for (next = node->symbol.same_comdat_group;
>  	       next != (symtab_node)node;
>  	       next = next->symbol.same_comdat_group)
> -	    if (symtab_variable_p (next)
> -		&& varpool (next)->analyzed)
> -	      enqueue_node (varpool (next), &first);
> +	    {
> +	      varpool_node *vnext = next->try_variable ();
> +	      if (vnext && vnext->analyzed)
> +		enqueue_node (vnext, &first);
> +	    }
>  	}
>        for (i = 0; ipa_ref_list_reference_iterate
> (&node->symbol.ref_list, i, ref); i++)
> -	if (symtab_variable_p (ref->referred)
> -	    && (!DECL_EXTERNAL (ref->referred->symbol.decl)
> -		|| varpool (ref->referred)->alias)
> -	    && varpool (ref->referred)->analyzed)
> -	  enqueue_node (varpool (ref->referred), &first);
> +	{
> +	  varpool_node *vnode = ref->referred->try_variable ();
> +	  if (vnode
> +	      && (!DECL_EXTERNAL (ref->referred->symbol.decl)
> +		  || vnode->alias)
> +	      && vnode->analyzed)
> +	    enqueue_node (vnode, &first);
> +	}
>      }
>    if (cgraph_dump_file)
>      fprintf (cgraph_dump_file, "\nRemoving variables:");
> @@ -457,7 +462,7 @@ add_new_static_var (tree type)
>    DECL_CONTEXT (new_decl) = NULL_TREE;
>    DECL_ABSTRACT (new_decl) = 0;
>    lang_hooks.dup_lang_specific_decl (new_decl);
> -  new_node = varpool_node (new_decl);
> +  new_node = varpool_node_for_tree (new_decl);
>    varpool_finalize_decl (new_decl);
>
>    return new_node->symbol.decl;
> @@ -473,7 +478,7 @@ varpool_create_variable_alias (tree alia
>
>    gcc_assert (TREE_CODE (decl) == VAR_DECL);
>    gcc_assert (TREE_CODE (alias) == VAR_DECL);
> -  alias_node = varpool_node (alias);
> +  alias_node = varpool_node_for_tree (alias);
>    alias_node->alias = 1;
>    alias_node->finalized = 1;
>    alias_node->alias_of = decl;
> Index: gcc/lto-streamer.h
> ===================================================================
> --- gcc/lto-streamer.h	(revision 191403)
> +++ gcc/lto-streamer.h	(working copy)
> @@ -1121,7 +1121,7 @@ lsei_next_function_in_partition (lto_sym
>  {
>    lsei_next (lsei);
>    while (!lsei_end_p (*lsei)
> -	 && (!symtab_function_p (lsei_node (*lsei))
> +	 && (!lsei_node (*lsei)->is_function ()
>  	     || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
> (*lsei))))
>      lsei_next (lsei);
>  }
> @@ -1134,7 +1134,7 @@ lsei_start_function_in_partition (lto_sy
>
>    if (lsei_end_p (lsei))
>      return lsei;
> -  if (!symtab_function_p (lsei_node (lsei))
> +  if (!(lsei_node (lsei)->is_function ())
>        || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei)))
>      lsei_next_function_in_partition (&lsei);
>
> @@ -1147,7 +1147,7 @@ lsei_next_variable_in_partition (lto_sym
>  {
>    lsei_next (lsei);
>    while (!lsei_end_p (*lsei)
> -	 && (!symtab_variable_p (lsei_node (*lsei))
> +	 && (!lsei_node (*lsei)->is_variable ()
>  	     || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
> (*lsei))))
>      lsei_next (lsei);
>  }
> @@ -1160,7 +1160,7 @@ lsei_start_variable_in_partition (lto_sy
>
>    if (lsei_end_p (lsei))
>      return lsei;
> -  if (!symtab_variable_p (lsei_node (lsei))
> +  if (!lsei_node (lsei)->is_variable ()
>        || !lto_symtab_encoder_in_partition_p (encoder, lsei_node (lsei)))
>      lsei_next_variable_in_partition (&lsei);
>
>
> --
> Lawrence Crowl
>
diff mbox

Patch

Index: gcc/ChangeLog

2012-09-18  Lawrence Crowl  <crowl@google.com

	* cgraph.h (varpool_node): Rename to varpool_node_for_tree.
	Adjust callers to match.
	(symtab_node_def::try_function): New.
	Change most calls to symtab_function_p with calls to
	symtab_node_def::try_function.
	(symtab_node_def::try_variable): New.
	Change most calls to symtab_variable_p with calls to
	symtab_node_def::try_variable.
	(symtab_function_p): Rename to symtab_node_def::is_function.
	Adjust remaining callers to match.
	(symtab_variable_p): Rename to symtab_node_def::is_variable.
	Adjust remaining callers to match.
	* cgraph.c (cgraph_node_for_asm): Remove redundant call to
	symtab_node_for_asm.
	* graphunit.c (symbol_finalized_and_needed): New.
	(symbol_finalized): New.
	(cgraph_analyze_functions): Split complicated conditionals out into
	above new functions.



Index: gcc/lto-symtab.c
===================================================================
--- gcc/lto-symtab.c	(revision 191403)
+++ gcc/lto-symtab.c	(working copy)
@@ -743,7 +743,7 @@  lto_symtab_merge_cgraph_nodes_1 (void **
 	{
 	  if (!prevailing->vnode)
 	    {
-	      prevailing->vnode = varpool_node (prevailing->decl);
+	      prevailing->vnode = varpool_node_for_tree (prevailing->decl);
 	      prevailing->vnode->alias = true;
 	    }
 	  lto_varpool_replace_node (e->vnode, prevailing->vnode);
Index: gcc/cgraphbuild.c
===================================================================
--- gcc/cgraphbuild.c	(revision 191403)
+++ gcc/cgraphbuild.c	(working copy)
@@ -84,7 +84,7 @@  record_reference (tree *tp, int *walk_su

       if (TREE_CODE (decl) == VAR_DECL)
 	{
-	  struct varpool_node *vnode = varpool_node (decl);
+	  struct varpool_node *vnode = varpool_node_for_tree (decl);
 	  ipa_record_reference ((symtab_node)ctx->varpool_node,
 				(symtab_node)vnode,
 				IPA_REF_ADDR, NULL);
@@ -123,7 +123,7 @@  record_type_list (struct cgraph_node *no
 	  type = TREE_OPERAND (type, 0);
 	  if (TREE_CODE (type) == VAR_DECL)
 	    {
-	      struct varpool_node *vnode = varpool_node (type);
+	      struct varpool_node *vnode = varpool_node_for_tree (type);
 	      ipa_record_reference ((symtab_node)node,
 				    (symtab_node)vnode,
 				    IPA_REF_ADDR, NULL);
@@ -233,7 +233,7 @@  mark_address (gimple stmt, tree addr, vo
   else if (addr && TREE_CODE (addr) == VAR_DECL
 	   && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
     {
-      struct varpool_node *vnode = varpool_node (addr);
+      struct varpool_node *vnode = varpool_node_for_tree (addr);

       ipa_record_reference ((symtab_node)data,
 			    (symtab_node)vnode,
@@ -262,7 +262,7 @@  mark_load (gimple stmt, tree t, void *da
   else if (t && TREE_CODE (t) == VAR_DECL
 	   && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
-      struct varpool_node *vnode = varpool_node (t);
+      struct varpool_node *vnode = varpool_node_for_tree (t);

       ipa_record_reference ((symtab_node)data,
 			    (symtab_node)vnode,
@@ -280,7 +280,7 @@  mark_store (gimple stmt, tree t, void *d
   if (t && TREE_CODE (t) == VAR_DECL
       && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
-      struct varpool_node *vnode = varpool_node (t);
+      struct varpool_node *vnode = varpool_node_for_tree (t);

       ipa_record_reference ((symtab_node)data,
 			    (symtab_node)vnode,
@@ -392,7 +392,7 @@  void
 record_references_in_initializer (tree decl, bool only_vars)
 {
   struct pointer_set_t *visited_nodes = pointer_set_create ();
-  struct varpool_node *node = varpool_node (decl);
+  struct varpool_node *node = varpool_node_for_tree (decl);
   struct record_reference_ctx ctx = {false, NULL};

   ctx.varpool_node = node;
Index: gcc/cgraph.c
===================================================================
--- gcc/cgraph.c	(revision 191403)
+++ gcc/cgraph.c	(working copy)
@@ -506,9 +506,12 @@  cgraph_node_for_asm (tree asmname)
   symtab_node node = symtab_node_for_asm (asmname);

   /* We do not want to look at inline clones.  */
-  for (node = symtab_node_for_asm (asmname); node; node =
node->symbol.next_sharing_asm_name)
-    if (symtab_function_p (node) && !cgraph(node)->global.inlined_to)
-      return cgraph (node);
+  for (; node; node = node->symbol.next_sharing_asm_name)
+    {
+      cgraph_node *cn = node->try_function ();
+      if (cn && !cn->global.inlined_to)
+	return cn;
+    }
   return NULL;
 }

Index: gcc/cgraph.h
===================================================================
--- gcc/cgraph.h	(revision 191403)
+++ gcc/cgraph.h	(working copy)
@@ -448,13 +448,46 @@  struct GTY(()) asm_node {
 /* Symbol table entry.  */
 union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"),
 	   chain_prev ("%h.symbol.previous"))) symtab_node_def {
+  /* Dynamic type testers. */
+  bool GTY((skip)) is_function ();
+  bool GTY((skip)) is_variable ();
+  /* Conditional accessors return null if not the requested type.  */
+  cgraph_node * GTY((skip)) try_function ();
+  varpool_node * GTY((skip)) try_variable ();
+
   struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol;
-  /* Use cgraph (symbol) accessor to get cgraph_node.  */
+  /* To access the following fields,
+     use the conditional accessors try_function and try_variable above
+     or the asserting accessor functions cgraph and varpool.  */
   struct cgraph_node GTY ((tag ("SYMTAB_FUNCTION"))) x_function;
-  /* Use varpool (symbol) accessor to get varpool_node.  */
   struct varpool_node GTY ((tag ("SYMTAB_VARIABLE"))) x_variable;
 };

+inline bool
+symtab_node_def::is_function ()
+{
+  return symbol.type == SYMTAB_FUNCTION;
+}
+
+inline bool
+symtab_node_def::is_variable ()
+{
+  return symbol.type == SYMTAB_VARIABLE;
+}
+
+inline cgraph_node *
+symtab_node_def::try_function ()
+{
+  return is_function () ? &x_function : NULL;
+}
+
+inline varpool_node *
+symtab_node_def::try_variable()
+{
+  return is_variable () ? &x_variable : NULL;
+}
+
+
 extern GTY(()) symtab_node symtab_nodes;
 extern GTY(()) int cgraph_n_nodes;
 extern GTY(()) int cgraph_max_uid;
@@ -677,7 +710,7 @@  bool cgraph_maybe_hot_edge_p (struct cgr
 bool cgraph_optimize_for_size_p (struct cgraph_node *);

 /* In varpool.c  */
-struct varpool_node *varpool_node (tree);
+struct varpool_node *varpool_node_for_tree (tree);
 struct varpool_node *varpool_node_for_asm (tree asmname);
 void varpool_mark_needed_node (struct varpool_node *);
 void debug_varpool (void);
@@ -705,19 +738,6 @@  bool varpool_for_node_and_aliases (struc
 			           void *, bool);
 void varpool_add_new_variable (tree);

-/* Return true when NODE is function.  */
-static inline bool
-symtab_function_p (symtab_node node)
-{
-  return node->symbol.type == SYMTAB_FUNCTION;
-}
-
-/* Return true when NODE is variable.  */
-static inline bool
-symtab_variable_p (symtab_node node)
-{
-  return node->symbol.type == SYMTAB_VARIABLE;
-}

 /* Return callgraph node for given symbol and check it is a function. */
 static inline struct cgraph_node *
@@ -790,10 +810,8 @@  varpool_first_variable (void)
 {
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
-    {
-      if (symtab_variable_p (node))
-	return varpool (node);
-    }
+    if (varpool_node *vnode = node->try_variable ())
+      return vnode;
   return NULL;
 }

@@ -803,10 +821,8 @@  varpool_next_variable (struct varpool_no
 {
   symtab_node node1 = (symtab_node) node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
-    {
-      if (symtab_variable_p (node1))
-	return varpool (node1);
-    }
+    if (varpool_node *vnode1 = node1->try_variable ())
+      return vnode1;
   return NULL;
 }
 /* Walk all variables.  */
@@ -822,9 +838,9 @@  varpool_first_static_initializer (void)
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
     {
-      if (symtab_variable_p (node)
-	  && DECL_INITIAL (node->symbol.decl))
-	return varpool (node);
+      varpool_node *vnode = node->try_variable ();
+      if (vnode && DECL_INITIAL (node->symbol.decl))
+	return vnode;
     }
   return NULL;
 }
@@ -836,9 +852,9 @@  varpool_next_static_initializer (struct
   symtab_node node1 = (symtab_node) node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
     {
-      if (symtab_variable_p (node1)
-	  && DECL_INITIAL (node1->symbol.decl))
-	return varpool (node1);
+      varpool_node *vnode1 = node1->try_variable ();
+      if (vnode1 && DECL_INITIAL (node1->symbol.decl))
+	return vnode1;
     }
   return NULL;
 }
@@ -855,8 +871,9 @@  varpool_first_defined_variable (void)
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
     {
-      if (symtab_variable_p (node) && varpool (node)->analyzed)
-	return varpool (node);
+      varpool_node *vnode = node->try_variable ();
+      if (vnode && vnode->analyzed)
+	return vnode;
     }
   return NULL;
 }
@@ -868,8 +885,9 @@  varpool_next_defined_variable (struct va
   symtab_node node1 = (symtab_node) node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
     {
-      if (symtab_variable_p (node1) && varpool (node1)->analyzed)
-	return varpool (node1);
+      varpool_node *vnode1 = node1->try_variable ();
+      if (vnode1 && vnode1->analyzed)
+	return vnode1;
     }
   return NULL;
 }
@@ -885,8 +903,9 @@  cgraph_first_defined_function (void)
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
     {
-      if (symtab_function_p (node) && cgraph (node)->analyzed)
-	return cgraph (node);
+      cgraph_node *cn = node->try_function ();
+      if (cn && cn->analyzed)
+	return cn;
     }
   return NULL;
 }
@@ -898,8 +917,9 @@  cgraph_next_defined_function (struct cgr
   symtab_node node1 = (symtab_node) node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
     {
-      if (symtab_function_p (node1) && cgraph (node1)->analyzed)
-	return cgraph (node1);
+      cgraph_node *cn1 = node1->try_function ();
+      if (cn1 && cn1->analyzed)
+	return cn1;
     }
   return NULL;
 }
@@ -915,10 +935,8 @@  cgraph_first_function (void)
 {
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
-    {
-      if (symtab_function_p (node))
-	return cgraph (node);
-    }
+    if (cgraph_node *cn = node->try_function ())
+      return cn;
   return NULL;
 }

@@ -928,10 +946,8 @@  cgraph_next_function (struct cgraph_node
 {
   symtab_node node1 = (symtab_node) node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
-    {
-      if (symtab_function_p (node1))
-	return cgraph (node1);
-    }
+    if (cgraph_node *cn1 = node1->try_function ())
+      return cn1;
   return NULL;
 }
 /* Walk all functions.  */
@@ -958,9 +974,9 @@  cgraph_first_function_with_gimple_body (
   symtab_node node;
   for (node = symtab_nodes; node; node = node->symbol.next)
     {
-      if (symtab_function_p (node)
-	  && cgraph_function_with_gimple_body_p (cgraph (node)))
-	return cgraph (node);
+      cgraph_node *cn = node->try_function ();
+      if (cn && cgraph_function_with_gimple_body_p (cn))
+	return cn;
     }
   return NULL;
 }
@@ -972,9 +988,9 @@  cgraph_next_function_with_gimple_body (s
   symtab_node node1 = node->symbol.next;
   for (; node1; node1 = node1->symbol.next)
     {
-      if (symtab_function_p (node1)
-	  && cgraph_function_with_gimple_body_p (cgraph (node1)))
-	return cgraph (node1);
+      cgraph_node *cn1 = node1->try_function ();
+      if (cn1 && cgraph_function_with_gimple_body_p (cn1))
+	return cn1;
     }
   return NULL;
 }
@@ -1173,7 +1189,7 @@  cgraph_alias_aliased_node (struct cgraph

   ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
   gcc_checking_assert (ref->use == IPA_REF_ALIAS);
-  if (symtab_function_p (ref->referred))
+  if (ref->referred->is_function ())
     return ipa_ref_node (ref);
   return NULL;
 }
@@ -1187,7 +1203,7 @@  varpool_alias_aliased_node (struct varpo

   ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
   gcc_checking_assert (ref->use == IPA_REF_ALIAS);
-  if (symtab_variable_p (ref->referred))
+  if (ref->referred->is_variable ())
     return ipa_ref_varpool_node (ref);
   return NULL;
 }
Index: gcc/tree-emutls.c
===================================================================
--- gcc/tree-emutls.c	(revision 191403)
+++ gcc/tree-emutls.c	(working copy)
@@ -260,7 +260,7 @@  get_emutls_init_templ_addr (tree decl)
   /* Create varpool node for the new variable and finalize it if it is
      not external one.  */
   if (DECL_EXTERNAL (to))
-    varpool_node (to);
+    varpool_node_for_tree (to);
   else
     varpool_add_new_variable (to);
   return build_fold_addr_expr (to);
@@ -332,7 +332,7 @@  new_emutls_decl (tree decl, tree alias_o
   /* Create varpool node for the new variable and finalize it if it is
      not external one.  */
   if (DECL_EXTERNAL (to))
-    varpool_node (to);
+    varpool_node_for_tree (to);
   else if (!alias_of)
     varpool_add_new_variable (to);
   else
Index: gcc/ipa-reference.c
===================================================================
--- gcc/ipa-reference.c	(revision 191403)
+++ gcc/ipa-reference.c	(working copy)
@@ -482,7 +482,7 @@  analyze_function (struct cgraph_node *fn
   local = init_function_info (fn);
   for (i = 0; ipa_ref_list_reference_iterate (&fn->symbol.ref_list,
i, ref); i++)
     {
-      if (!symtab_variable_p (ref->referred))
+      if (!ref->referred->is_variable ())
 	continue;
       var = ipa_ref_varpool_node (ref)->symbol.decl;
       if (!is_proper_for_analysis (var))
@@ -979,8 +979,6 @@  stream_out_bitmap (struct lto_simple_out
 static void
 ipa_reference_write_optimization_summary (void)
 {
-  struct cgraph_node *node;
-  symtab_node snode;
   struct lto_simple_output_block *ob
     = lto_create_simple_output_block (LTO_section_ipa_reference);
   unsigned int count = 0;
@@ -994,18 +992,16 @@  ipa_reference_write_optimization_summary
   /* See what variables we are interested in.  */
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      struct varpool_node *vnode;
-      snode = lto_symtab_encoder_deref (encoder, i);
-      if (!symtab_variable_p (snode))
-	continue;
-      vnode = varpool (snode);
-      if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      varpool_node *vnode = snode->try_variable ();
+      if (vnode
+	  && bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
 	  && referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder))
 	{
 	  tree decl = vnode->symbol.decl;
 	  bitmap_set_bit (ltrans_statics, DECL_UID (decl));
 	  splay_tree_insert (reference_vars_to_consider,
-			     DECL_UID (decl), (splay_tree_value)decl);
+			 DECL_UID (decl), (splay_tree_value)decl);
 	  ltrans_statics_bitcount ++;
 	}
     }
@@ -1013,10 +1009,12 @@  ipa_reference_write_optimization_summary

   if (ltrans_statics_bitcount)
     for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
-      if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i))
-	  && write_node_summary_p (cgraph (snode),
-				   encoder, ltrans_statics))
+      {
+	symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+	cgraph_node *cnode = snode->try_function ();
+	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
 	  count++;
+      }

   streamer_write_uhwi_stream (ob->main_stream, count);
   if (count)
@@ -1027,17 +1025,15 @@  ipa_reference_write_optimization_summary
   if (ltrans_statics_bitcount)
     for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
       {
-	snode = lto_symtab_encoder_deref (encoder, i);
-	if (!symtab_function_p (snode))
-	  continue;
-	node = cgraph (snode);
-	if (write_node_summary_p (node, encoder, ltrans_statics))
+	symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+	cgraph_node *cnode = snode->try_function ();
+	if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
 	  {
 	    ipa_reference_optimization_summary_t info;
 	    int node_ref;

-	    info = get_reference_optimization_summary (node);
-	    node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
+	    info = get_reference_optimization_summary (cnode);
+	    node_ref = lto_symtab_encoder_encode (encoder, snode);
 	    streamer_write_uhwi_stream (ob->main_stream, node_ref);

 	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c	(revision 191403)
+++ gcc/cgraphunit.c	(working copy)
@@ -388,7 +388,8 @@  referred_to_p (symtab_node node)
   if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
     return true;
   /* For functions check also calls.  */
-  if (symtab_function_p (node) && cgraph (node)->callers)
+  cgraph_node *cn = node->try_function ();
+  if (cn && cn->callers)
     return true;
   return false;
 }
@@ -818,7 +819,7 @@  process_function_and_variable_attributes
 void
 varpool_finalize_decl (tree decl)
 {
-  struct varpool_node *node = varpool_node (decl);
+  struct varpool_node *node = varpool_node_for_tree (decl);

   gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));

@@ -845,6 +846,35 @@  varpool_finalize_decl (tree decl)
     varpool_assemble_decl (node);
 }

+
+/* Determine if a symbol is finalized and needed.  */
+
+inline static bool
+symbol_finalized_and_needed (symtab_node node)
+{
+  if (cgraph_node *cnode = node->try_function ())
+    return cnode->local.finalized
+	   && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
+  if (varpool_node *vnode = node->try_variable ())
+    return vnode->finalized
+	   && !DECL_EXTERNAL (vnode->symbol.decl)
+	   && decide_is_variable_needed (vnode, vnode->symbol.decl);
+  return false;
+}
+
+/* Determine if a symbol is finalized.  */
+
+inline static bool
+symbol_finalized (symtab_node node)
+{
+  if (cgraph_node *cnode= node->try_function ())
+    return cnode->local.finalized;
+  if (varpool_node *vnode = node->try_variable ())
+    return vnode->finalized;
+  return false;
+}
+
+
 /* Discover all functions and variables that are trivially needed, analyze
    them as well as all functions and variables referred by them  */

@@ -879,13 +909,7 @@  cgraph_analyze_functions (void)
 	   node != (symtab_node)first_analyzed
 	   && node != (symtab_node)first_analyzed_var; node = node->symbol.next)
 	{
-	  if ((symtab_function_p (node)
-	       && cgraph (node)->local.finalized
-	       && cgraph_decide_is_function_needed (cgraph (node), node->symbol.decl))
-	      || (symtab_variable_p (node)
-		  && varpool (node)->finalized
-		  && !DECL_EXTERNAL (node->symbol.decl)
-		  && decide_is_variable_needed (varpool (node), node->symbol.decl)))
+	  if (symbol_finalized_and_needed (node))
 	    {
 	      enqueue_node (node);
 	      if (!changed && cgraph_dump_file)
@@ -912,18 +936,15 @@  cgraph_analyze_functions (void)
 	  changed = true;
 	  node = first;
 	  first = (symtab_node)first->symbol.aux;
-	  if (symtab_function_p (node) && cgraph (node)->local.finalized)
+	  cgraph_node *cnode = node->try_function ();
+	  if (cnode && cnode->local.finalized)
 	    {
 	      struct cgraph_edge *edge;
-	      struct cgraph_node *cnode;
-	      tree decl;
-
-	      cnode = cgraph (node);
-	      decl = cnode->symbol.decl;
+	      tree decl = cnode->symbol.decl;

-	      /* ??? It is possible to create extern inline function and later using
-		 weak alias attribute to kill its body. See
-		 gcc.c-torture/compile/20011119-1.c  */
+	      /* ??? It is possible to create extern inline function
+	      and later using weak alias attribute to kill its body.
+	      See gcc.c-torture/compile/20011119-1.c  */
 	      if (!DECL_STRUCT_FUNCTION (decl)
 		  && (!cnode->alias || !cnode->thunk.alias)
 		  && !cnode->thunk.thunk_p)
@@ -938,23 +959,25 @@  cgraph_analyze_functions (void)

 	      for (edge = cnode->callees; edge; edge = edge->next_callee)
 		if (edge->callee->local.finalized)
-		  enqueue_node ((symtab_node)edge->callee);
+		   enqueue_node ((symtab_node)edge->callee);

-	      /* If decl is a clone of an abstract function, mark that abstract
-		 function so that we don't release its body. The DECL_INITIAL() of that
-		 abstract function declaration will be later needed to output debug
-		 info.  */
+	      /* If decl is a clone of an abstract function,
+	      mark that abstract function so that we don't release its body.
+	      The DECL_INITIAL() of that abstract function declaration
+	      will be later needed to output debug info.  */
 	      if (DECL_ABSTRACT_ORIGIN (decl))
 		{
-		  struct cgraph_node *origin_node;
-		  origin_node = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
+		  struct cgraph_node *origin_node
+	    	  = cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
 		  origin_node->abstract_and_needed = true;
 		}
-
 	    }
-	  else if (symtab_variable_p (node)
-		   && varpool (node)->finalized)
-	    varpool_analyze_node (varpool (node));
+	  else
+	    {
+	      varpool_node *vnode = node->try_variable ();
+	      if (vnode && vnode->finalized)
+		varpool_analyze_node (vnode);
+	    }

 	  if (node->symbol.same_comdat_group)
 	    {
@@ -965,8 +988,7 @@  cgraph_analyze_functions (void)
 		enqueue_node (next);
 	    }
 	  for (i = 0; ipa_ref_list_reference_iterate
(&node->symbol.ref_list, i, ref); i++)
-	    if ((symtab_function_p (ref->referred) && cgraph
(ref->referred)->local.finalized)
-		|| (symtab_variable_p (ref->referred) && varpool (ref->referred)->finalized))
+	    if (symbol_finalized (ref->referred))
 	      enqueue_node (ref->referred);
           cgraph_process_new_functions ();
 	}
@@ -994,10 +1016,9 @@  cgraph_analyze_functions (void)
 	  symtab_remove_node (node);
 	  continue;
 	}
-      if (symtab_function_p (node))
+      if (cgraph_node *cnode = node->try_function ())
 	{
 	  tree decl = node->symbol.decl;
-	  struct cgraph_node *cnode = cgraph (node);

 	  if (cnode->local.finalized && !gimple_has_body_p (decl)
 	      && (!cnode->alias || !cnode->thunk.alias)
@@ -1079,7 +1100,7 @@  handle_alias_pairs (void)
 	}

       if (TREE_CODE (p->decl) == FUNCTION_DECL
-          && target_node && symtab_function_p (target_node))
+          && target_node && target_node->is_function ())
 	{
 	  struct cgraph_node *src_node = cgraph_get_node (p->decl);
 	  if (src_node && src_node->local.finalized)
@@ -1088,7 +1109,7 @@  handle_alias_pairs (void)
 	  VEC_unordered_remove (alias_pair, alias_pairs, i);
 	}
       else if (TREE_CODE (p->decl) == VAR_DECL
-	       && target_node && symtab_variable_p (target_node))
+	       && target_node && target_node->is_variable ())
 	{
 	  varpool_create_variable_alias (p->decl, target_node->symbol.decl);
 	  VEC_unordered_remove (alias_pair, alias_pairs, i);
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 191403)
+++ gcc/cp/decl2.c	(working copy)
@@ -1773,7 +1773,7 @@  import_export_class (tree ctype)
 static bool
 var_finalized_p (tree var)
 {
-  return varpool_node (var)->finalized;
+  return varpool_node_for_tree (var)->finalized;
 }

 /* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
@@ -1891,7 +1891,7 @@  maybe_emit_vtables (tree ctype)
 	TREE_ASM_WRITTEN (vtbl) = 1;
       else if (DECL_ONE_ONLY (vtbl))
 	{
-	  current = varpool_node (vtbl);
+	  current = varpool_node_for_tree (vtbl);
 	  if (last)
 	    symtab_add_to_same_comdat_group ((symtab_node) current,
(symtab_node) last);
 	  last = current;
Index: gcc/ipa-ref.c
===================================================================
--- gcc/ipa-ref.c	(revision 191403)
+++ gcc/ipa-ref.c	(working copy)
@@ -42,7 +42,7 @@  ipa_record_reference (symtab_node referr
   struct ipa_ref_list *list, *list2;
   VEC(ipa_ref_t,gc) *old_references;

-  gcc_checking_assert (!stmt || symtab_function_p (referring_node));
+  gcc_checking_assert (!stmt || referring_node->is_function ());
   gcc_checking_assert (use_type != IPA_REF_ALIAS || !stmt);

   list = &referring_node->symbol.ref_list;
Index: gcc/lto-cgraph.c
===================================================================
--- gcc/lto-cgraph.c	(revision 191403)
+++ gcc/lto-cgraph.c	(working copy)
@@ -665,7 +665,7 @@  add_references (lto_symtab_encoder_t enc
   int i;
   struct ipa_ref *ref;
   for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
-    if (symtab_function_p (ref->referred))
+    if (ref->referred->is_function ())
       add_node_to (encoder, ipa_ref_node (ref), false);
     else
       {
@@ -719,9 +719,8 @@  compute_ltrans_boundary (lto_symtab_enco
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
       symtab_node node = lto_symtab_encoder_deref (encoder, i);
-      if (symtab_variable_p (node))
+      if (varpool_node *vnode = node->try_variable ())
 	{
-	  struct varpool_node *vnode = varpool (node);
 	  if (DECL_INITIAL (vnode->symbol.decl)
 	      && !lto_symtab_encoder_encode_initializer_p (encoder,
 							   vnode)
@@ -785,8 +784,8 @@  output_symtab (void)
   for (i = 0; i < n_nodes; i++)
     {
       symtab_node node = lto_symtab_encoder_deref (encoder, i);
-      if (symtab_function_p (node))
-        lto_output_node (ob, cgraph (node), encoder);
+      if (cgraph_node *cnode = node->try_function ())
+        lto_output_node (ob, cnode, encoder);
       else
         lto_output_varpool_node (ob, varpool (node), encoder);
 	
@@ -972,7 +971,7 @@  input_varpool_node (struct lto_file_decl
   order = streamer_read_hwi (ib) + order_base;
   decl_index = streamer_read_uhwi (ib);
   var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
-  node = varpool_node (var_decl);
+  node = varpool_node_for_tree (var_decl);
   node->symbol.order = order;
   if (order >= symtab_order)
     symtab_order = order + 1;
@@ -1133,14 +1132,14 @@  input_cgraph_1 (struct lto_file_decl_dat
   /* AUX pointers should be all non-zero for function nodes read from
the stream.  */
 #ifdef ENABLE_CHECKING
   FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
-    gcc_assert (node->symbol.aux || !symtab_function_p (node));
+    gcc_assert (node->symbol.aux || !node->is_function ());
 #endif
   FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
     {
       int ref;
-      if (symtab_function_p (node))
+      if (cgraph_node *cnode = node->try_function ())
 	{
-	  ref = (int) (intptr_t) cgraph (node)->global.inlined_to;
+	  ref = (int) (intptr_t) cnode->global.inlined_to;

 	  /* We share declaration of builtins, so we may read same node twice.  */
 	  if (!node->symbol.aux)
@@ -1149,9 +1148,9 @@  input_cgraph_1 (struct lto_file_decl_dat

 	  /* Fixup inlined_to from reference to pointer.  */
 	  if (ref != LCC_NOT_FOUND)
-	    cgraph (node)->global.inlined_to = cgraph (VEC_index
(symtab_node, nodes, ref));
+	    cnode->global.inlined_to = cgraph (VEC_index (symtab_node, nodes, ref));
 	  else
-	    cgraph (node)->global.inlined_to = NULL;
+	    cnode->global.inlined_to = NULL;
 	}

       ref = (int) (intptr_t) node->symbol.same_comdat_group;
@@ -1163,7 +1162,7 @@  input_cgraph_1 (struct lto_file_decl_dat
 	node->symbol.same_comdat_group = NULL;
     }
   FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
-    node->symbol.aux = symtab_function_p (node) ? (void *)1 : NULL;
+    node->symbol.aux = node->is_function () ? (void *)1 : NULL;
   return nodes;
 }

@@ -1437,7 +1436,6 @@  output_node_opt_summary (struct output_b
 static void
 output_cgraph_opt_summary (void)
 {
-  symtab_node node;
   int i, n_nodes;
   lto_symtab_encoder_t encoder;
   struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum);
@@ -1447,18 +1445,21 @@  output_cgraph_opt_summary (void)
   encoder = ob->decl_state->symtab_node_encoder;
   n_nodes = lto_symtab_encoder_size (encoder);
   for (i = 0; i < n_nodes; i++)
-    if (symtab_function_p (node = lto_symtab_encoder_deref (encoder, i))
-	&& output_cgraph_opt_summary_p (cgraph (node)))
-      count++;
+    {
+      symtab_node node = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = node->try_function ();
+      if (cnode && output_cgraph_opt_summary_p (cnode))
+	count++;
+    }
   streamer_write_uhwi (ob, count);
   for (i = 0; i < n_nodes; i++)
     {
-      node = lto_symtab_encoder_deref (encoder, i);
-      if (symtab_function_p (node)
-	  && output_cgraph_opt_summary_p (cgraph (node)))
+      symtab_node node = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = node->try_function ();
+      if (cnode && output_cgraph_opt_summary_p (cnode))
 	{
 	  streamer_write_uhwi (ob, i);
-	  output_node_opt_summary (ob, cgraph (node), encoder);
+	  output_node_opt_summary (ob, cnode, encoder);
 	}
     }
   produce_asm (ob, NULL);
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c	(revision 191403)
+++ gcc/lto-streamer-out.c	(working copy)
@@ -975,7 +975,6 @@  copy_function (struct cgraph_node *node)
 static void
 lto_output (void)
 {
-  struct cgraph_node *node;
   struct lto_out_decl_state *decl_state;
 #ifdef ENABLE_CHECKING
   bitmap output = lto_bitmap_alloc ();
@@ -991,10 +990,9 @@  lto_output (void)
   for (i = 0; i < n_nodes; i++)
     {
       symtab_node snode = lto_symtab_encoder_deref (encoder, i);
-      if (!symtab_function_p (snode))
-	continue;
-      node = cgraph (snode);
-      if (lto_symtab_encoder_encode_body_p (encoder, node)
+      cgraph_node *node = snode->try_function ();
+      if (node
+	  && lto_symtab_encoder_encode_body_p (encoder, node)
 	  && !node->alias
 	  && !node->thunk.thunk_p)
 	{
@@ -1288,8 +1286,6 @@  produce_symtab (struct output_block *ob)
   struct streamer_tree_cache_d *cache = ob->writer_cache;
   char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
   struct pointer_set_t *seen;
-  struct cgraph_node *node;
-  struct varpool_node *vnode;
   struct lto_output_stream stream;
   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
   int i;
@@ -1305,49 +1301,52 @@  produce_symtab (struct output_block *ob)
      This is done so only to handle duplicated symbols in cgraph.  */
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = snode->try_function ();
+      if (!cnode)
 	continue;
-      node = cgraph (lto_symtab_encoder_deref (encoder, i));
-      if (DECL_EXTERNAL (node->symbol.decl))
+      if (DECL_EXTERNAL (cnode->symbol.decl))
 	continue;
-      if (DECL_COMDAT (node->symbol.decl)
-	  && cgraph_comdat_can_be_unshared_p (node))
+      if (DECL_COMDAT (cnode->symbol.decl)
+	  && cgraph_comdat_can_be_unshared_p (cnode))
 	continue;
-      if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
+      if ((cnode->alias && !cnode->thunk.alias) || cnode->global.inlined_to)
 	continue;
-      write_symbol (cache, &stream, node->symbol.decl, seen, false);
+      write_symbol (cache, &stream, cnode->symbol.decl, seen, false);
     }
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = snode->try_function ();
+      if (!cnode)
 	continue;
-      node = cgraph (lto_symtab_encoder_deref (encoder, i));
-      if (!DECL_EXTERNAL (node->symbol.decl))
+      if (!DECL_EXTERNAL (cnode->symbol.decl))
 	continue;
       /* We keep around unused extern inlines in order to be able to inline
 	 them indirectly or via vtables.  Do not output them to symbol
 	 table: they end up being undefined and just consume space.  */
-      if (!node->symbol.address_taken && !node->callers)
+      if (!cnode->symbol.address_taken && !cnode->callers)
 	continue;
-      if (DECL_COMDAT (node->symbol.decl)
-	  && cgraph_comdat_can_be_unshared_p (node))
+      if (DECL_COMDAT (cnode->symbol.decl)
+	  && cgraph_comdat_can_be_unshared_p (cnode))
 	continue;
-      if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
+      if ((cnode->alias && !cnode->thunk.alias) || cnode->global.inlined_to)
 	continue;
-      write_symbol (cache, &stream, node->symbol.decl, seen, false);
+      write_symbol (cache, &stream, cnode->symbol.decl, seen, false);
     }

   /* Write all variables.  */
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      varpool_node *vnode = snode->try_variable ();
+      if (!vnode)
 	continue;
-      vnode = varpool (lto_symtab_encoder_deref (encoder, i));
       if (DECL_EXTERNAL (vnode->symbol.decl))
 	continue;
       /* COMDAT virtual tables can be unshared.  Do not declare them
-	 in the LTO symbol table to prevent linker from forcing them
-	 into the output. */
+	in the LTO symbol table to prevent linker from forcing them
+	into the output. */
       if (DECL_COMDAT (vnode->symbol.decl)
 	  && !vnode->symbol.force_output
 	  && vnode->finalized
@@ -1359,9 +1358,10 @@  produce_symtab (struct output_block *ob)
     }
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      varpool_node *vnode = snode->try_variable ();
+      if (!vnode)
 	continue;
-      vnode = varpool (lto_symtab_encoder_deref (encoder, i));
       if (!DECL_EXTERNAL (vnode->symbol.decl))
 	continue;
       if (DECL_COMDAT (vnode->symbol.decl)
Index: gcc/ada/gcc-interface/utils.c
===================================================================
--- gcc/ada/gcc-interface/utils.c	(revision 191403)
+++ gcc/ada/gcc-interface/utils.c	(working copy)
@@ -5582,7 +5582,7 @@  gnat_write_global_declarations (void)
 		      void_type_node);
       TREE_STATIC (dummy_global) = 1;
       TREE_ASM_WRITTEN (dummy_global) = 1;
-      node = varpool_node (dummy_global);
+      node = varpool_node_for_tree (dummy_global);
       node->symbol.force_output = 1;

       while (!VEC_empty (tree, types_used_by_cur_var_decl))
Index: gcc/ipa.c
===================================================================
--- gcc/ipa.c	(revision 191403)
+++ gcc/ipa.c	(working copy)
@@ -84,7 +84,7 @@  process_references (struct ipa_ref_list
   struct ipa_ref *ref;
   for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
     {
-      if (symtab_function_p (ref->referred))
+      if (ref->referred->is_function ())
 	{
 	  struct cgraph_node *node = ipa_ref_node (ref);

@@ -290,10 +290,8 @@  symtab_remove_unreachable_nodes (bool be
 			      before_inlining_p, reachable);
 	}

-      if (symtab_function_p (node))
+      if (cgraph_node *cnode = node->try_function ())
 	{
-	  struct cgraph_node *cnode = cgraph (node);
-
 	  /* Mark the callees reachable unless they are direct calls to extern
  	     inline functions we decided to not inline.  */
 	  if (!in_boundary_p)
@@ -332,18 +330,18 @@  symtab_remove_unreachable_nodes (bool be
 	    }
 	}
       /* When we see constructor of external variable, keep referred
nodes in the
-	 boundary.  This will also hold initializers of the external vars NODE
-	 reffers to.  */
-      if (symtab_variable_p (node)
+	boundary.  This will also hold initializers of the external vars NODE
+	refers to.  */
+      varpool_node *vnode = node->try_variable ();
+      if (vnode
 	  && DECL_EXTERNAL (node->symbol.decl)
-	  && !varpool (node)->alias
+	  && !vnode->alias
 	  && in_boundary_p)
-        {
-	  int i;
+	{
 	  struct ipa_ref *ref;
-	  for (i = 0; ipa_ref_list_reference_iterate
(&node->symbol.ref_list, i, ref); i++)
+	  for (int i = 0; ipa_ref_list_reference_iterate
(&node->symbol.ref_list, i, ref); i++)
 	    enqueue_node (ref->referred, &first, reachable);
-        }
+	}
     }

   /* Remove unreachable functions.   */
@@ -526,7 +524,7 @@  cgraph_address_taken_from_non_vtable_p (
     if (ref->use == IPA_REF_ADDR)
       {
 	struct varpool_node *node;
-	if (symtab_function_p (ref->referring))
+	if (ref->referring->is_function ())
 	  return true;
 	node = ipa_ref_referring_varpool_node (ref);
 	if (!DECL_VIRTUAL_P (node->symbol.decl))
Index: gcc/ipa-inline-analysis.c
===================================================================
--- gcc/ipa-inline-analysis.c	(revision 191403)
+++ gcc/ipa-inline-analysis.c	(working copy)
@@ -3816,22 +3816,25 @@  void
 inline_write_summary (void)
 {
   struct cgraph_node *node;
-  symtab_node snode;
   struct output_block *ob = create_output_block (LTO_section_inline_summary);
   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
   unsigned int count = 0;
   int i;

   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
-    if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i))
-	&& cgraph (snode)->analyzed)
-      count++;
+    {
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = snode->try_function ();
+      if (cnode && cnode->analyzed)
+	count++;
+    }
   streamer_write_uhwi (ob, count);

   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      if (symtab_function_p (snode = lto_symtab_encoder_deref (encoder, i))
-	  && (node = cgraph (snode))->analyzed)
+      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = snode->try_function ();
+      if (cnode && (node = cnode)->analyzed)
 	{
 	  struct inline_summary *info = inline_summary (node);
 	  struct bitpack_d bp;
@@ -3839,7 +3842,7 @@  inline_write_summary (void)
 	  int i;
 	  size_time_entry *e;
 	  struct condition *c;
-
+
 	  streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder,
(symtab_node)node));
 	  streamer_write_hwi (ob, info->estimated_self_stack_size);
 	  streamer_write_hwi (ob, info->self_size);
@@ -3858,7 +3861,7 @@  inline_write_summary (void)
 	      bp_pack_value (&bp, c->by_ref, 1);
 	      streamer_write_bitpack (&bp);
 	      if (c->agg_contents)
-		streamer_write_uhwi (ob, c->offset);
+	        streamer_write_uhwi (ob, c->offset);
 	    }
 	  streamer_write_uhwi (ob, VEC_length (size_time_entry, info->entry));
 	  for (i = 0;
Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c	(revision 191403)
+++ gcc/lto/lto.c	(working copy)
@@ -2619,12 +2619,17 @@  lto_wpa_write_files (void)
 	      if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
 		{
 	          fprintf (cgraph_dump_file, "%s ", symtab_node_asm_name (node));
-		  if (symtab_function_p (node)
-		      && lto_symtab_encoder_encode_body_p (part->encoder, cgraph (node)))
+		  cgraph_node *cnode = node->try_function ();
+		  if (cnode
+		      && lto_symtab_encoder_encode_body_p (part->encoder, cnode))
 		    fprintf (cgraph_dump_file, "(body included)");
-		  else if (symtab_variable_p (node)
-		           && lto_symtab_encoder_encode_initializer_p
(part->encoder, varpool (node)))
-		    fprintf (cgraph_dump_file, "(initializer included)");
+		  else
+		    {
+		      varpool_node *vnode = node->try_variable ();
+		      if (vnode
+			  && lto_symtab_encoder_encode_initializer_p (part->encoder, vnode))
+			fprintf (cgraph_dump_file, "(initializer included)");
+		    }
 		}
 	    }
 	  fprintf (cgraph_dump_file, "\n");
Index: gcc/lto/lto-partition.c
===================================================================
--- gcc/lto/lto-partition.c	(revision 191403)
+++ gcc/lto/lto-partition.c	(working copy)
@@ -55,22 +55,22 @@  get_symbol_class (symtab_node node)
 {
   /* Inline clones are always duplicated.
      This include external delcarations.   */
-  if (symtab_function_p (node)
-      && cgraph (node)->global.inlined_to)
+  cgraph_node *cnode = node->try_function ();
+  if (cnode && cnode->global.inlined_to)
     return SYMBOL_DUPLICATE;

   /* External declarations are external.  */
   if (DECL_EXTERNAL (node->symbol.decl))
     return SYMBOL_EXTERNAL;

-  if (symtab_variable_p (node))
+  if (varpool_node *vnode = node->try_variable ())
     {
       /* Constant pool references use local symbol names that can not
          be promoted global.  We should never put into a constant pool
          objects that can not be duplicated across partitions.  */
       if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
 	return SYMBOL_DUPLICATE;
-      gcc_checking_assert (varpool (node)->analyzed);
+      gcc_checking_assert (vnode->analyzed);
     }
   /* Functions that are cloned may stay in callgraph even if they are unused.
      Handle them as external; compute_ltrans_boundary take care to make
@@ -145,7 +145,7 @@  add_references_to_partition (ltrans_part
     /* References to a readonly variable may be constant foled into its value.
        Recursively look into the initializers of the constant variable and add
        references, too.  */
-    else if (symtab_variable_p (ref->referred)
+    else if (ref->referred->is_variable ()
 	     && const_value_known_p (ref->referred->symbol.decl)
 	     && !lto_symtab_encoder_in_partition_p (part->encoder, ref->referred))
       {
@@ -196,9 +196,8 @@  add_symbol_to_partition_1 (ltrans_partit
     }
   node->symbol.aux = (void *)((size_t)node->symbol.aux + 1);

-  if (symtab_function_p (node))
+  if (cgraph_node *cnode = node->try_function ())
     {
-      struct cgraph_node *cnode = cgraph (node);
       struct cgraph_edge *e;
       part->insns += inline_summary (cnode)->self_size;

@@ -247,15 +246,15 @@  contained_in_symbol (symtab_node node)
   if (lookup_attribute ("weakref",
 			DECL_ATTRIBUTES (node->symbol.decl)))
     return node;
-  if (symtab_function_p (node))
+  if (cgraph_node *cnode = node->try_function ())
     {
-      struct cgraph_node *cnode = cgraph_function_node (cgraph (node), NULL);
+      cnode = cgraph_function_node (cnode, NULL);
       if (cnode->global.inlined_to)
 	cnode = cnode->global.inlined_to;
       return (symtab_node) cnode;
     }
-  else if (symtab_variable_p (node))
-    return (symtab_node) varpool_variable_node (varpool (node), NULL);
+  else if (varpool_node *vnode = node->try_variable ())
+    return (symtab_node) varpool_variable_node (vnode, NULL);
   return node;
 }

@@ -302,8 +301,8 @@  undo_partition (ltrans_partition partiti
 	pointer_set_destroy (partition->initializers_visited);
       partition->initializers_visited = NULL;

-      if (symtab_function_p (node))
-        partition->insns -= inline_summary (cgraph (node))->self_size;
+      if (cgraph_node *cnode = node->try_function ())
+        partition->insns -= inline_summary (cnode)->self_size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->symbol.aux = (void *)((size_t)node->symbol.aux - 1);
     }
@@ -555,11 +554,10 @@  lto_balanced_map (void)
 	  symtab_node snode = lto_symtab_encoder_deref (partition->encoder,
 							last_visited_node);

-	  if (symtab_function_p (snode))
+	  if (cgraph_node *node = snode->try_function ())
 	    {
 	      struct cgraph_edge *edge;

-	      node = cgraph (snode);
 	      refs = &node->symbol.ref_list;

 	      last_visited_node++;
@@ -611,7 +609,7 @@  lto_balanced_map (void)
 	  /* Compute boundary cost of IPA REF edges and at the same time look into
 	     variables referenced from current partition and try to add them.  */
 	  for (j = 0; ipa_ref_list_reference_iterate (refs, j, ref); j++)
-	    if (symtab_variable_p (ref->referred))
+	    if (ref->referred->is_variable ())
 	      {
 		int index;

@@ -645,7 +643,7 @@  lto_balanced_map (void)
 		  cost++;
 	      }
 	  for (j = 0; ipa_ref_list_referring_iterate (refs, j, ref); j++)
-	    if (symtab_variable_p (ref->referring))
+	    if (ref->referring->is_variable ())
 	      {
 		int index;

Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 191403)
+++ gcc/varasm.c	(working copy)
@@ -2221,7 +2221,7 @@  mark_decl_referenced (tree decl)
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     {
-      struct varpool_node *node = varpool_node (decl);
+      struct varpool_node *node = varpool_node_for_tree (decl);
       /* C++ frontend use mark_decl_references to force COMDAT variables
          to be output that might appear dead otherwise.  */
       node->symbol.force_output = true;
@@ -5549,7 +5549,7 @@  assemble_alias (tree decl, tree target)
   if (TREE_CODE (decl) == FUNCTION_DECL)
     cgraph_get_create_node (decl)->alias = true;
   else
-    varpool_node (decl)->alias = true;
+    varpool_node_for_tree (decl)->alias = true;

   /* If the target has already been emitted, we don't have to queue the
      alias.  This saves a tad of memory.  */
Index: gcc/symtab.c
===================================================================
--- gcc/symtab.c	(revision 191403)
+++ gcc/symtab.c	(working copy)
@@ -239,8 +239,8 @@  symtab_unregister_node (symtab_node node
   if (*slot == node)
     {
       symtab_node replacement_node = NULL;
-      if (symtab_function_p (node))
-	replacement_node = (symtab_node)cgraph_find_replacement_node (cgraph (node));
+      if (cgraph_node *cnode = node->try_function ())
+	replacement_node = (symtab_node)cgraph_find_replacement_node (cnode);
       if (!replacement_node)
 	htab_clear_slot (symtab_hash, slot);
       else
@@ -281,10 +281,10 @@  symtab_get_node (const_tree decl)
 void
 symtab_remove_node (symtab_node node)
 {
-  if (symtab_function_p (node))
-    cgraph_remove_node (cgraph (node));
-  else if (symtab_variable_p (node))
-    varpool_remove_node (varpool (node));
+  if (cgraph_node *cnode = node->try_function ())
+    cgraph_remove_node (cnode);
+  else if (varpool_node *vnode = node->try_variable ())
+    varpool_remove_node (vnode);
 }

 /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
@@ -514,10 +514,10 @@  dump_symtab_base (FILE *f, symtab_node n
 void
 dump_symtab_node (FILE *f, symtab_node node)
 {
-  if (symtab_function_p (node))
-    dump_cgraph_node (f, cgraph (node));
-  else if (symtab_variable_p (node))
-    dump_varpool_node (f, varpool (node));
+  if (cgraph_node *cnode = node->try_function ())
+    dump_cgraph_node (f, cnode);
+  else if (varpool_node *vnode = node->try_variable ())
+    dump_varpool_node (f, vnode);
 }

 /* Dump symbol table.  */
@@ -555,7 +555,7 @@  verify_symtab_base (symtab_node node)
   bool error_found = false;
   symtab_node hashed_node;

-  if (symtab_function_p (node))
+  if (node->is_function ())
     {
       if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL)
 	{
@@ -563,7 +563,7 @@  verify_symtab_base (symtab_node node)
           error_found = true;
 	}
     }
-  else if (symtab_variable_p (node))
+  else if (node->is_variable ())
     {
       if (TREE_CODE (node->symbol.decl) != VAR_DECL)
 	{
@@ -651,8 +651,8 @@  verify_symtab_node (symtab_node node)
     return;

   timevar_push (TV_CGRAPH_VERIFY);
-  if (symtab_function_p (node))
-    verify_cgraph_node (cgraph (node));
+  if (cgraph_node *cnode = node->try_function ())
+    verify_cgraph_node (cnode);
   else
     if (verify_symtab_base (node))
       {
Index: gcc/passes.c
===================================================================
--- gcc/passes.c	(revision 191403)
+++ gcc/passes.c	(working copy)
@@ -201,7 +201,7 @@  rest_of_decl_compilation (tree decl,
     ;
   else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
 	   && TREE_STATIC (decl))
-    varpool_node (decl);
+    varpool_node_for_tree (decl);
 }

 /* Called after finishing a record, union or enumeral type.  */
Index: gcc/varpool.c
===================================================================
--- gcc/varpool.c	(revision 191403)
+++ gcc/varpool.c	(working copy)
@@ -39,7 +39,7 @@  along with GCC; see the file COPYING3.

 /* Return varpool node assigned to DECL.  Create new one when needed.  */
 struct varpool_node *
-varpool_node (tree decl)
+varpool_node_for_tree (tree decl)
 {
   struct varpool_node *node = varpool_get_node (decl);
   gcc_assert (TREE_CODE (decl) == VAR_DECL
@@ -114,9 +114,9 @@  debug_varpool (void)
 struct varpool_node *
 varpool_node_for_asm (tree asmname)
 {
-  symtab_node node = symtab_node_for_asm (asmname);
-  if (node && symtab_variable_p (node))
-    return varpool (node);
+  if (symtab_node node = symtab_node_for_asm (asmname))
+    if (varpool_node *vnode = node->try_variable ())
+      return vnode;
   return NULL;
 }

@@ -192,7 +192,7 @@  varpool_add_new_variable (tree decl)
 {
   struct varpool_node *node;
   varpool_finalize_decl (decl);
-  node = varpool_node (decl);
+  node = varpool_node_for_tree (decl);
   if (varpool_externally_visible_p (node, false))
     node->symbol.externally_visible = true;
 }
@@ -232,7 +232,7 @@  varpool_analyze_node (struct varpool_nod
     }
   if (node->alias && node->alias_of)
     {
-      struct varpool_node *tgt = varpool_node (node->alias_of);
+      struct varpool_node *tgt = varpool_node_for_tree (node->alias_of);
       struct varpool_node *n;

       for (n = tgt; n && n->alias;
@@ -374,16 +374,21 @@  varpool_remove_unreferenced_decls (void)
 	  for (next = node->symbol.same_comdat_group;
 	       next != (symtab_node)node;
 	       next = next->symbol.same_comdat_group)
-	    if (symtab_variable_p (next)
-		&& varpool (next)->analyzed)
-	      enqueue_node (varpool (next), &first);
+	    {
+	      varpool_node *vnext = next->try_variable ();
+	      if (vnext && vnext->analyzed)
+		enqueue_node (vnext, &first);
+	    }
 	}
       for (i = 0; ipa_ref_list_reference_iterate
(&node->symbol.ref_list, i, ref); i++)
-	if (symtab_variable_p (ref->referred)
-	    && (!DECL_EXTERNAL (ref->referred->symbol.decl)
-		|| varpool (ref->referred)->alias)
-	    && varpool (ref->referred)->analyzed)
-	  enqueue_node (varpool (ref->referred), &first);
+	{
+	  varpool_node *vnode = ref->referred->try_variable ();
+	  if (vnode
+	      && (!DECL_EXTERNAL (ref->referred->symbol.decl)
+		  || vnode->alias)
+	      && vnode->analyzed)
+	    enqueue_node (vnode, &first);
+	}
     }
   if (cgraph_dump_file)
     fprintf (cgraph_dump_file, "\nRemoving variables:");
@@ -457,7 +462,7 @@  add_new_static_var (tree type)
   DECL_CONTEXT (new_decl) = NULL_TREE;
   DECL_ABSTRACT (new_decl) = 0;
   lang_hooks.dup_lang_specific_decl (new_decl);
-  new_node = varpool_node (new_decl);
+  new_node = varpool_node_for_tree (new_decl);
   varpool_finalize_decl (new_decl);

   return new_node->symbol.decl;
@@ -473,7 +478,7 @@  varpool_create_variable_alias (tree alia

   gcc_assert (TREE_CODE (decl) == VAR_DECL);
   gcc_assert (TREE_CODE (alias) == VAR_DECL);
-  alias_node = varpool_node (alias);
+  alias_node = varpool_node_for_tree (alias);
   alias_node->alias = 1;
   alias_node->finalized = 1;
   alias_node->alias_of = decl;
Index: gcc/lto-streamer.h
===================================================================
--- gcc/lto-streamer.h	(revision 191403)
+++ gcc/lto-streamer.h	(working copy)
@@ -1121,7 +1121,7 @@  lsei_next_function_in_partition (lto_sym
 {
   lsei_next (lsei);
   while (!lsei_end_p (*lsei)
-	 && (!symtab_function_p (lsei_node (*lsei))
+	 && (!lsei_node (*lsei)->is_function ()
 	     || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
(*lsei))))
     lsei_next (lsei);