This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Use conditional casting with symtab_node


Hi,

On Tue, Oct 02, 2012 at 05:32:38PM -0700, Lawrence Crowl wrote:
> Updated Patch
> 
> Add functions symtab_node_def::try_function and symtab_node_def::try_variable.

Even though I hate to be bikeshedding, I must say I really dislike the
names, especially try_function.  Not only I believe it should be
consistent with the name of the type it returns but, more importantly,
it looks as if it had something to do with struct function which is an
entirely different thing.

I understand the names cgraph_node and varpool_node are slightly
anachronistic in the symtab world, but still I think that they are
perfectly usable, do not present a real obstacle to newcomers
(cgraph_nodes do form the call graph, after all) and we are all used
to them.  Therefore I'd be in favor of keeping them and changing the
try_stuff function names accordingly.

Thanks,

Martin

> 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 inappropriately.)
> 
>   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_decl.
> 
> 
> The new code bootstraps .616% faster with a 99% confidence of being faster.
> 
> 
> Tested on x86_64.
> 
> 
> Okay for trunk?
> 
> 
> Index: gcc/ChangeLog
> 
> 2012-10-02  Lawrence Crowl  <crowl@google.com
> 
> 	* cgraph.h (varpool_node): Rename to varpool_node_for_decl.
> 	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.
> 	* cgraphunit.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 192010)
> +++ gcc/lto-symtab.c	(working copy)
> @@ -566,11 +566,11 @@ lto_symtab_merge_cgraph_nodes_1 (symtab_
> 
>        if (!symtab_real_symbol_p (e))
>  	continue;
> -      if (symtab_function_p (e)
> -	  && !DECL_BUILT_IN (e->symbol.decl))
> -	lto_cgraph_replace_node (cgraph (e), cgraph (prevailing));
> -      if (symtab_variable_p (e))
> -	lto_varpool_replace_node (varpool (e), varpool (prevailing));
> +      cgraph_node *ce = e->try_function ();
> +      if (ce && !DECL_BUILT_IN (e->symbol.decl))
> +	lto_cgraph_replace_node (ce, cgraph (prevailing));
> +      if (varpool_node *ve = e->try_variable ())
> +	lto_varpool_replace_node (ve, varpool (prevailing));
>      }
> 
>    return;
> Index: gcc/cgraphbuild.c
> ===================================================================
> --- gcc/cgraphbuild.c	(revision 192010)
> +++ 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_decl (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_decl (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_decl (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_decl (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_decl (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_decl (decl);
>    struct record_reference_ctx ctx = {false, NULL};
> 
>    ctx.varpool_node = node;
> Index: gcc/cgraph.c
> ===================================================================
> --- gcc/cgraph.c	(revision 192010)
> +++ gcc/cgraph.c	(working copy)
> @@ -503,12 +503,15 @@ cgraph_add_thunk (struct cgraph_node *de
>  struct cgraph_node *
>  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 (symtab_node node = symtab_node_for_asm (asmname);
> +       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 192010)
> +++ gcc/cgraph.h	(working copy)
> @@ -456,13 +456,56 @@ 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;
>  };
> 
> +/* Report whether or not THIS symtab node is a function, aka cgraph_node.  */
> +
> +inline bool
> +symtab_node_def::is_function ()
> +{
> +  return symbol.type == SYMTAB_FUNCTION;
> +}
> +
> +/* Report whether or not THIS symtab node is a vriable, aka varpool_node.  */
> +
> +inline bool
> +symtab_node_def::is_variable ()
> +{
> +  return symbol.type == SYMTAB_VARIABLE;
> +}
> +
> +/* If THIS symtab node is a function, return a pointer to the cgraph_node,
> +   otherwise return NULL.  */
> +
> +inline cgraph_node *
> +symtab_node_def::try_function ()
> +{
> +  return is_function () ? &x_function : NULL;
> +}
> +
> +/* If THIS symtab node is a variable, return a pointer to the varpool_node,
> +   otherwise return 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;
> @@ -685,7 +728,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_decl (tree);
>  struct varpool_node *varpool_node_for_asm (tree asmname);
>  void varpool_mark_needed_node (struct varpool_node *);
>  void debug_varpool (void);
> @@ -715,19 +758,6 @@ void varpool_add_new_variable (tree);
>  void symtab_initialize_asm_name_hash (void);
>  void symtab_prevail_in_asm_name_hash (symtab_node node);
> 
> -/* 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 *
> @@ -800,10 +830,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;
>  }
> 
> @@ -813,10 +841,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.  */
> @@ -832,9 +858,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;
>  }
> @@ -846,9 +872,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;
>  }
> @@ -865,8 +891,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;
>  }
> @@ -878,8 +905,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;
>  }
> @@ -895,8 +923,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;
>  }
> @@ -908,8 +937,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;
>  }
> @@ -925,10 +955,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;
>  }
> 
> @@ -938,10 +966,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.  */
> @@ -968,9 +994,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;
>  }
> @@ -982,9 +1008,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;
>  }
> @@ -1183,7 +1209,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;
>  }
> @@ -1197,7 +1223,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;
>  }
> @@ -1328,7 +1354,7 @@ symtab_real_symbol_p (symtab_node node)
>    struct cgraph_node *cnode;
>    struct ipa_ref *ref;
> 
> -  if (!symtab_function_p (node))
> +  if (!node->is_function ())
>      return true;
>    cnode = cgraph (node);
>    if (cnode->global.inlined_to)
> Index: gcc/tree-emutls.c
> ===================================================================
> --- gcc/tree-emutls.c	(revision 192010)
> +++ 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_decl (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_decl (to);
>    else if (!alias_of)
>      varpool_add_new_variable (to);
>    else
> Index: gcc/ipa-reference.c
> ===================================================================
> --- gcc/ipa-reference.c	(revision 192010)
> +++ 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,12 +992,10 @@ 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;
> @@ -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 192010)
> +++ gcc/cgraphunit.c	(working copy)
> @@ -386,7 +386,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;
>  }
> @@ -809,7 +810,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_decl (decl);
> 
>    gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
> 
> @@ -836,6 +837,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  */
> 
> @@ -870,13 +900,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)
> @@ -903,18 +927,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)
> @@ -929,23 +950,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)
>  	    {
> @@ -956,8 +979,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 ();
>  	}
> @@ -985,10 +1007,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)
> @@ -1070,7 +1091,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)
> @@ -1079,7 +1100,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 192010)
> +++ gcc/cp/decl2.c	(working copy)
> @@ -1778,7 +1778,7 @@ import_export_class (tree ctype)
>  static bool
>  var_finalized_p (tree var)
>  {
> -  return varpool_node (var)->finalized;
> +  return varpool_node_for_decl (var)->finalized;
>  }
> 
>  /* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
> @@ -1896,7 +1896,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_decl (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 192010)
> +++ 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 192010)
> +++ 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
>        lto_symtab_encoder_encode (encoder, ref->referred);
> @@ -716,9 +716,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)
> @@ -782,8 +781,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);
>  	
> @@ -969,7 +968,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_decl (var_decl);
>    node->symbol.order = order;
>    if (order >= symtab_order)
>      symtab_order = order + 1;
> @@ -1130,14 +1129,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)
> @@ -1146,9 +1145,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;
> @@ -1160,7 +1159,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;
>  }
> 
> @@ -1435,7 +1434,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);
> @@ -1445,18 +1443,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 192010)
> +++ gcc/lto-streamer-out.c	(working copy)
> @@ -972,7 +972,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 ();
> @@ -988,10 +987,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)
>  	{
> @@ -1285,8 +1283,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;
> @@ -1302,49 +1298,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
> @@ -1356,9 +1355,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 192010)
> +++ 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_decl (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 192010)
> +++ 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 192010)
> +++ gcc/ipa-inline-analysis.c	(working copy)
> @@ -3811,22 +3811,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;
> @@ -3834,7 +3837,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);
> @@ -3853,7 +3856,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 192010)
> +++ gcc/lto/lto.c	(working copy)
> @@ -2620,12 +2620,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 192010)
> +++ 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 192010)
> +++ 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_decl (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_decl (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 192010)
> +++ gcc/symtab.c	(working copy)
> @@ -104,7 +104,7 @@ eq_assembler_name (const void *p1, const
>  static void
>  insert_to_assembler_name_hash (symtab_node node)
>  {
> -  if (symtab_variable_p (node) && DECL_HARD_REGISTER (node->symbol.decl))
> +  if (node->is_variable () && DECL_HARD_REGISTER (node->symbol.decl))
>      return;
>    gcc_checking_assert (!node->symbol.previous_sharing_asm_name
>  		       && !node->symbol.next_sharing_asm_name);
> @@ -252,8 +252,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
> @@ -294,10 +294,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);
>  }
> 
>  /* Initalize asm name hash unless.  */
> @@ -538,10 +538,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.  */
> @@ -579,7 +579,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)
>  	{
> @@ -587,7 +587,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)
>  	{
> @@ -622,7 +622,7 @@ verify_symtab_base (symtab_node node)
>  	  hashed_node = hashed_node->symbol.next_sharing_asm_name;
>  	}
>        if (!hashed_node
> -          && !(symtab_variable_p (node) || DECL_HARD_REGISTER
> (node->symbol.decl)))
> +          && !(node->is_variable () || DECL_HARD_REGISTER (node->symbol.decl)))
>  	{
>            error ("node not found in symtab assembler name hash");
>            error_found = true;
> @@ -676,8 +676,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 192010)
> +++ 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_decl (decl);
>  }
> 
>  /* Called after finishing a record, union or enumeral type.  */
> Index: gcc/varpool.c
> ===================================================================
> --- gcc/varpool.c	(revision 192010)
> +++ 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_decl (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_decl (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_decl (node->alias_of);
>        struct varpool_node *n;
> 
>        for (n = tgt; n && n->alias;
> @@ -378,16 +378,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:");
> @@ -461,7 +466,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_decl (new_decl);
>    varpool_finalize_decl (new_decl);
> 
>    return new_node->symbol.decl;
> @@ -477,7 +482,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_decl (alias);
>    alias_node->alias = 1;
>    alias_node->finalized = 1;
>    alias_node->alias_of = decl;
> Index: gcc/lto-streamer.h
> ===================================================================
> --- gcc/lto-streamer.h	(revision 192010)
> +++ gcc/lto-streamer.h	(working copy)
> @@ -1120,7 +1120,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);
>  }
> @@ -1133,7 +1133,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);
> 
> @@ -1146,7 +1146,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);
>  }
> @@ -1159,7 +1159,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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]