This patch implements generic type query and conversion functions,
and applies them to the use of cgraph_node, varpool_node, and symtab_node.

The functions are:

bool is_a <TYPE> (pointer)
  Tests whether the pointer actually points to a more derived TYPE.

TYPE *as_a <TYPE> (pointer)
  Converts pointer to a TYPE*.

TYPE *dyn_cast <TYPE> (pointer)
  Converts pointer to TYPE* if and only if "is_a <TYPE> pointer".
  Otherwise, returns NULL.
  This function is essentially a checked down cast.

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 = dyn_cast <cgraph_node> (node))
    {
      ....
    }

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 = dyn_cast <varpool_node> (node);
  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 functions is_a <cgraph_node> and is_a <varpool_node>.  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.

Tested on x86_64.

Okay for trunk?


Index: gcc/ChangeLog

2012-10-26  Lawrence Crowl  <cr...@google.com

        * is-a.h: New.
        (is_a <T> (U*)): New.  Test for is-a relationship.
        (as_a <T> (U*)): New.  Treat as a derived type.
        (dyn_cast <T> (U*)): New.  Conditionally cast based on is_a.
        * cgraph.h (varpool_node): Rename to varpool_node_for_decl.
        Adjust callers to match.
        (is_a_helper <cgraph_node>::test (symtab_node_def *)): New.
        (is_a_helper <varpool_node>::test (symtab_node_def *)): New.
        (symtab_node_def::try_function): New.  Change most calls to
        symtab_function_p with calls to dyn_cast <cgraph_node> (p).
        (symtab_node_def::try_variable): New.  Change most calls to
        symtab_variable_p with calls to dyn_cast <varpool_node> (p).
        (symtab_function_p): Remove.  Change callers to use
        is_a <cgraph_node> (p) instead.
        (symtab_variable_p): Remove.  Change callers to use
        is_a <varpool_node> (p) instead.
        * 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.
        * Makefile.in (CGRAPH_H): Add is-a.h as used by cgraph.h.

Index: gcc/lto-symtab.c
===================================================================
--- gcc/lto-symtab.c    (revision 192862)
+++ gcc/lto-symtab.c    (working copy)
@@ -532,11 +532,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 = dyn_cast <cgraph_node> (e);
+      if (ce && !DECL_BUILT_IN (e->symbol.decl))
+       lto_cgraph_replace_node (ce, cgraph (prevailing));
+      if (varpool_node *ve = dyn_cast <varpool_node> (e))
+       lto_varpool_replace_node (ve, varpool (prevailing));
     }

   return;
Index: gcc/cgraphbuild.c
===================================================================
--- gcc/cgraphbuild.c   (revision 192862)
+++ 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 192862)
+++ 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 = dyn_cast <cgraph_node> (node);
+      if (cn && !cn->global.inlined_to)
+       return cn;
+    }
   return NULL;
 }

Index: gcc/cgraph.h
===================================================================
--- gcc/cgraph.h        (revision 192862)
+++ gcc/cgraph.h        (working copy)
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.
 #ifndef GCC_CGRAPH_H
 #define GCC_CGRAPH_H

+#include "is-a.h"
 #include "plugin-api.h"
 #include "vec.h"
 #include "tree.h"
@@ -457,12 +458,32 @@ struct GTY(()) asm_node {
 union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"),
           chain_prev ("%h.symbol.previous"))) symtab_node_def {
   struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol;
-  /* Use cgraph (symbol) accessor to get cgraph_node.  */
+  /* To access the following fields,
+     use the use dyn_cast or as_a to obtain the concrete type.  */
   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.  */
+
+template <>
+template <>
+inline bool
+is_a_helper <cgraph_node>::test (symtab_node_def *p)
+{
+  return p->symbol.type == SYMTAB_FUNCTION;
+}
+
+/* Report whether or not THIS symtab node is a vriable, aka varpool_node.  */
+
+template <>
+template <>
+inline bool
+is_a_helper <varpool_node>::test (symtab_node_def *p)
+{
+  return p->symbol.type == SYMTAB_VARIABLE;
+}
+
 extern GTY(()) symtab_node symtab_nodes;
 extern GTY(()) int cgraph_n_nodes;
 extern GTY(()) int cgraph_max_uid;
@@ -685,7 +706,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 +736,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 +808,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 = dyn_cast <varpool_node> (node))
+      return vnode;
   return NULL;
 }

@@ -813,10 +819,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 = dyn_cast <varpool_node> (node1))
+      return vnode1;
   return NULL;
 }
 /* Walk all variables.  */
@@ -832,9 +836,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 = dyn_cast <varpool_node> (node);
+      if (vnode && DECL_INITIAL (node->symbol.decl))
+       return vnode;
     }
   return NULL;
 }
@@ -846,9 +850,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 = dyn_cast <varpool_node> (node1);
+      if (vnode1 && DECL_INITIAL (node1->symbol.decl))
+       return vnode1;
     }
   return NULL;
 }
@@ -865,8 +869,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 = dyn_cast <varpool_node> (node);
+      if (vnode && vnode->analyzed)
+       return vnode;
     }
   return NULL;
 }
@@ -878,8 +883,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 = dyn_cast <varpool_node> (node1);
+      if (vnode1 && vnode1->analyzed)
+       return vnode1;
     }
   return NULL;
 }
@@ -895,8 +901,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 = dyn_cast <cgraph_node> (node);
+      if (cn && cn->analyzed)
+       return cn;
     }
   return NULL;
 }
@@ -908,8 +915,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 = dyn_cast <cgraph_node> (node1);
+      if (cn1 && cn1->analyzed)
+       return cn1;
     }
   return NULL;
 }
@@ -925,10 +933,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 = dyn_cast <cgraph_node> (node))
+      return cn;
   return NULL;
 }

@@ -938,10 +944,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 = dyn_cast <cgraph_node> (node1))
+      return cn1;
   return NULL;
 }
 /* Walk all functions.  */
@@ -968,9 +972,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 = dyn_cast <cgraph_node> (node);
+      if (cn && cgraph_function_with_gimple_body_p (cn))
+       return cn;
     }
   return NULL;
 }
@@ -982,9 +986,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 = dyn_cast <cgraph_node> (node1);
+      if (cn1 && cgraph_function_with_gimple_body_p (cn1))
+       return cn1;
     }
   return NULL;
 }
@@ -1183,7 +1187,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 (is_a <cgraph_node> (ref->referred))
     return ipa_ref_node (ref);
   return NULL;
 }
@@ -1197,7 +1201,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 (is_a <varpool_node> (ref->referred))
     return ipa_ref_varpool_node (ref);
   return NULL;
 }
@@ -1328,7 +1332,7 @@ symtab_real_symbol_p (symtab_node node)
   struct cgraph_node *cnode;
   struct ipa_ref *ref;

-  if (!symtab_function_p (node))
+  if (!is_a <cgraph_node> (node))
     return true;
   cnode = cgraph (node);
   if (cnode->global.inlined_to)
Index: gcc/tree-emutls.c
===================================================================
--- gcc/tree-emutls.c   (revision 192862)
+++ 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 192862)
+++ 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 (!is_a <varpool_node> (ref->referred))
        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 = dyn_cast <varpool_node> (snode);
+      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 = dyn_cast <cgraph_node> (snode);
+       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 = dyn_cast <cgraph_node> (snode);
+       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 192862)
+++ 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 = dyn_cast <cgraph_node> (node);
+  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 = dyn_cast <cgraph_node> (node))
+    return cnode->local.finalized
+          && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
+  if (varpool_node *vnode = dyn_cast <varpool_node> (node))
+    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= dyn_cast <cgraph_node> (node))
+    return cnode->local.finalized;
+  if (varpool_node *vnode = dyn_cast <varpool_node> (node))
+    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 = dyn_cast <cgraph_node> (node);
+         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 = dyn_cast <varpool_node> (node);
+             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 = dyn_cast <cgraph_node> (node))
        {
          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 && is_a <cgraph_node> (target_node))
        {
          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 && is_a <varpool_node> (target_node))
        {
          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 192862)
+++ gcc/cp/decl2.c      (working copy)
@@ -1775,7 +1775,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,
@@ -1893,7 +1893,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 192862)
+++ 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 || is_a <cgraph_node> (referring_node));
   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 192862)
+++ gcc/lto-cgraph.c    (working copy)
@@ -679,7 +679,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 (is_a <cgraph_node> (ref->referred))
       add_node_to (encoder, ipa_ref_node (ref), false);
     else
       lto_symtab_encoder_encode (encoder, ref->referred);
@@ -730,9 +730,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 = dyn_cast <varpool_node> (node))
        {
-         struct varpool_node *vnode = varpool (node);
          if (DECL_INITIAL (vnode->symbol.decl)
              && !lto_symtab_encoder_encode_initializer_p (encoder,
                                                           vnode)
@@ -796,8 +795,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 = dyn_cast <cgraph_node> (node))
+        lto_output_node (ob, cnode, encoder);
       else
         lto_output_varpool_node (ob, varpool (node), encoder);
        
@@ -983,7 +982,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;
@@ -1144,14 +1143,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 || !is_a <cgraph_node> (node));
 #endif
   FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
     {
       int ref;
-      if (symtab_function_p (node))
+      if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
        {
-         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)
@@ -1160,9 +1159,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;
@@ -1174,7 +1173,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 = is_a <cgraph_node> (node) ? (void *)1 : NULL;
   return nodes;
 }

@@ -1449,7 +1448,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);
@@ -1459,18 +1457,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 = dyn_cast <cgraph_node> (node);
+      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 = dyn_cast <cgraph_node> (node);
+      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 192862)
+++ gcc/lto-streamer-out.c      (working copy)
@@ -956,7 +956,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 ();
@@ -972,10 +971,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 = dyn_cast <cgraph_node> (snode);
+      if (node
+         && lto_symtab_encoder_encode_body_p (encoder, node)
          && !node->alias
          && !node->thunk.thunk_p)
        {
Index: gcc/ada/gcc-interface/utils.c
===================================================================
--- gcc/ada/gcc-interface/utils.c       (revision 192862)
+++ gcc/ada/gcc-interface/utils.c       (working copy)
@@ -5586,7 +5586,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 192862)
+++ 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 (is_a <cgraph_node> (ref->referred))
        {
          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 = dyn_cast <cgraph_node> (node))
        {
-         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 = dyn_cast <varpool_node> (node);
+      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 (is_a <cgraph_node> (ref->referring))
          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 192862)
+++ 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 = dyn_cast <cgraph_node> (snode);
+      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 = dyn_cast <cgraph_node> (snode);
+      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 192862)
+++ gcc/lto/lto.c       (working copy)
@@ -2671,12 +2671,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 = dyn_cast <cgraph_node> (node);
+                 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 = dyn_cast <varpool_node> (node);
+                     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 192862)
+++ 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 = dyn_cast <cgraph_node> (node);
+  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 = dyn_cast <varpool_node> (node))
     {
       /* 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 (is_a <varpool_node> (ref->referred)
             && 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 = dyn_cast <cgraph_node> (node))
     {
-      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 = dyn_cast <cgraph_node> (node))
     {
-      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 = dyn_cast <varpool_node> (node))
+    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 = dyn_cast <cgraph_node> (node))
+        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 = dyn_cast <cgraph_node> (snode))
            {
              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 (is_a <varpool_node> (ref->referred))
              {
                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 (is_a <varpool_node> (ref->referring))
              {
                int index;

Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c        (revision 192862)
+++ 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 192862)
+++ 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 (is_a <varpool_node> (node) && 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 = dyn_cast <cgraph_node> (node))
+       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 = dyn_cast <cgraph_node> (node))
+    cgraph_remove_node (cnode);
+  else if (varpool_node *vnode = dyn_cast <varpool_node> (node))
+    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 = dyn_cast <cgraph_node> (node))
+    dump_cgraph_node (f, cnode);
+  else if (varpool_node *vnode = dyn_cast <varpool_node> (node))
+    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 (is_a <cgraph_node> (node))
     {
       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 (is_a <varpool_node> (node))
     {
       if (TREE_CODE (node->symbol.decl) != VAR_DECL)
        {
@@ -622,7 +622,8 @@ 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)))
+          && !(is_a <varpool_node> (node)
+              || DECL_HARD_REGISTER (node->symbol.decl)))
        {
           error ("node not found in symtab assembler name hash");
           error_found = true;
@@ -676,8 +677,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 = dyn_cast <cgraph_node> (node))
+    verify_cgraph_node (cnode);
   else
     if (verify_symtab_base (node))
       {
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in     (revision 192862)
+++ gcc/Makefile.in     (working copy)
@@ -886,7 +886,7 @@ CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) v
 IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
 IPA_REFERENCE_H = ipa-reference.h $(BITMAP_H) $(TREE_H)
 CGRAPH_H = cgraph.h $(VEC_H) $(TREE_H) $(BASIC_BLOCK_H) $(FUNCTION_H) \
-       cif-code.def ipa-ref.h ipa-ref-inline.h $(LINKER_PLUGIN_API_H)
+       cif-code.def ipa-ref.h ipa-ref-inline.h $(LINKER_PLUGIN_API_H) is-a.h
 DF_H = df.h $(BITMAP_H) $(REGSET_H) sbitmap.h $(BASIC_BLOCK_H) \
        alloc-pool.h $(TIMEVAR_H)
 VALTRACK_H = valtrack.h $(BITMAP_H) $(DF_H) $(RTL_H) $(BASIC_BLOCK_H) \
Index: gcc/passes.c
===================================================================
--- gcc/passes.c        (revision 192862)
+++ 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 192862)
+++ 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 = dyn_cast <varpool_node> (node))
+      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 = dyn_cast <varpool_node> (next);
+             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 = dyn_cast <varpool_node> (ref->referred);
+         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 192862)
+++ gcc/lto-streamer.h  (working copy)
@@ -1115,7 +1115,7 @@ lsei_next_function_in_partition (lto_sym
 {
   lsei_next (lsei);
   while (!lsei_end_p (*lsei)
-        && (!symtab_function_p (lsei_node (*lsei))
+        && (!is_a <cgraph_node> (lsei_node (*lsei))
             || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
(*lsei))))
     lsei_next (lsei);
 }
@@ -1128,7 +1128,7 @@ lsei_start_function_in_partition (lto_sy

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

@@ -1141,7 +1141,7 @@ lsei_next_variable_in_partition (lto_sym
 {
   lsei_next (lsei);
   while (!lsei_end_p (*lsei)
-        && (!symtab_variable_p (lsei_node (*lsei))
+        && (!is_a <varpool_node> (lsei_node (*lsei))
             || !lto_symtab_encoder_in_partition_p (lsei->encoder, lsei_node
(*lsei))))
     lsei_next (lsei);
 }
@@ -1154,7 +1154,7 @@ lsei_start_variable_in_partition (lto_sy

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


-- 
Lawrence Crowl

Reply via email to