Merge varpool and cgraph encoders into symtab encoders

Jan Hubicka hubicka@ucw.cz
Fri Aug 10 15:57:00 GMT 2012


Hi,
this patch does the boring job of merging varpool and cgraph encoders into
single symtab encoder.  This has some snowballing effect. Because the IDs of
cgraphs and varpools now use single space, the cgraph and varpool sections
needs to be merged. Also reference lists output code is simplified.  The
uses of encoders needs to be updated to expect all kinds of symtab nodes in
the encoder lists.

I broke out all subsequent changes from this renaming happy patch to make them
more readable.

Bootstrapped/regtested x86_64-linux and tested with Mozilla build. I will
commit it after bit of further testing. The mozilla binarry differs (due to
different UIDs) but has same size.

Honza

	* cgraph.h (vector types for symtab_node): Add.
	* ipa-reference.c (ipa_reference_write_optimization_summary): Update
	for new symtab encoder.
	(ipa_reference_read_optimization_summary): Likewise.
	* lto-cgraph.c (output_varpool): Remove.
	(input_cgraph_opt_summary): Take symtab nodes vector as argument.
	(LTO_cgraph_tags): Rename to ...
	(LTO_symtab_tags): ... this one; add LTO_symtab_variable.
	(lto_cgraph_encoder_new): Rename to ...
	(lto_symtab_encoder_new): ... this on.
	(lto_cgraph_encoder_encode): Rename to ...
	(lto_symtab_encoder_encode): ... this one.
	(lto_cgraph_encoder_delete): Rename to ...
	(lto_symtab_encoder_delete): ... this one.
	(lto_cgraph_encoder_deref): Rename to ...
	(lto_symtab_encoder_deref): ... this one.
	(lto_cgraph_encoder_encode_body_p): Rename to ...
	(lto_symtab_encoder_encode_body_p): ... this one.
	(lto_varpool_encoder_new, lto_varpool_encoder_delete,
	lto_varpool_encoder_encode, lto_varpool_encoder_lookup,
	lto_varpool_encoder_deref): Remove.
	(lto_varpool_encoder_encode_initializer_p): Rename to ...
	(lto_symtab_encoder_encode_initializer_p): ... this one.
	(lto_set_varpool_encoder_encode_initializer): Rename to ...
	(lto_set_symtab_encoder_encode_initializer): ... this one.
	(lto_output_edge): Update.
	(lto_output_node): Update.
	(lto_output_varpool_node): Update; stream out LTO_symtab_variable tag.
	(lto_output_ref): Drop varpool_encoder; update.
	(add_node_to): Update.
	(add_references): Update.
	(output_outgoing_cgraph_edges): Update.
	(output_refs): Update.	
	(compute_ltrans_boundary): Update.
	(output_cgraph): Update; output varpools too.
	(input_overwrite_node): Update.
	(output_varpool): Remove.
	(input_node): Update.
	(input_ref): Update.
	(input_edge): Update.
	(input_cgraph_1): Update; input varpool too; unify fixup code.
	(input_varpool_1): Remove.
	(input_refs): Update.
	(input_cgraph): Update.
	(output_node_opt_summary): Update.
	(input_cgraph_opt_section): Update.
	(input_cgraph_opt_summary): Update.
	* ipa-pure-const.c (pure_const_write_summary): Update.
	(pure_const_read_summary): Update.
	* lto-streamer-out.c (lto_write_tree): Update.
	(lto_output): Likewise.
	(produce_symtab): Update.
	(produce_asm_for_decls): Update.
	* ipa-inline-analysis.c (inline_read_section): Update.
	(inline_write_summary): Update.
	* ipa-prop.c (ipa_write_node_info): Update.
	(ipa_prop_read_section): Update.
	* lto-streamer.h (lto_cgraph_encoder_d): Rename to ...
	(lto_symtab_encoder_d): ... this one;  add initializer.
	(lto_cgraph_encoder_t): Rename to ...
	(lto_symtab_encoder_t): ... this one.
	(lto_cgraph_encoder_size): Rename to ...
	(lto_symtab_encoder_size): ... this one.
	(lto_varpool_encoder_d): ... remove.
	(lto_varpool_encoder_t): Remove.
	(lto_out_decl_state): Remove cgraph_node_encoder, varpool_node_encoder
	add symtab_node_encoder.
	(lto_file_decl_data): Likewise.
	(lto_cgraph_encoder_deref, lto_cgraph_encoder_lookup,
	lto_cgraph_encoder_new, lto_cgraph_encoder_encode, lto_cgraph_encoder_delete,
	lto_cgraph_encoder_encode_body_p, lto_varpool_encoder_encode_body_p,
	lto_varpool_encoder_deref, lto_varpool_encoder_lookup, lto_varpool_encoder_new,
	lto_varpool_encoder_encode, lto_varpool_encoder_delete,
	lto_varpool_encoder_encode_initializer_p): Remove.
	(lto_symtab_encoder_deref, lto_symtab_encoder_lookup,
	lto_symtab_encoder_t, lto_symtab_encoder_encode, lto_symtab_encoder_delete,
	lto_symtab_encoder_encode_body_p, lto_symtab_encoder_encode_initializer_p):
	New.
Index: cgraph.h
===================================================================
*** cgraph.h	(revision 190283)
--- cgraph.h	(working copy)
*************** struct GTY(()) cgraph_node {
*** 273,278 ****
--- 273,282 ----
    unsigned tm_clone : 1;
  };
  
+ DEF_VEC_P(symtab_node);
+ DEF_VEC_ALLOC_P(symtab_node,heap);
+ DEF_VEC_ALLOC_P(symtab_node,gc);
+ 
  typedef struct cgraph_node *cgraph_node_ptr;
  
  DEF_VEC_P(cgraph_node_ptr);
Index: ipa-reference.c
===================================================================
*** ipa-reference.c	(revision 190283)
--- ipa-reference.c	(working copy)
*************** ipa_reference_write_optimization_summary
*** 1029,1049 ****
  					  varpool_node_set vset)
  {
    struct cgraph_node *node;
    struct lto_simple_output_block *ob
      = lto_create_simple_output_block (LTO_section_ipa_reference);
    unsigned int count = 0;
    int ltrans_statics_bitcount = 0;
!   lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
!   lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
    bitmap ltrans_statics = BITMAP_ALLOC (NULL);
    int i;
  
    reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
  
    /* See what variables we are interested in.  */
!   for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
      {
!       struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
        if (bitmap_bit_p (all_module_statics, DECL_UID (vnode->symbol.decl))
  	  && referenced_from_this_partition_p (&vnode->symbol.ref_list, set, vset))
  	{
--- 1029,1053 ----
  					  varpool_node_set vset)
  {
    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;
    int ltrans_statics_bitcount = 0;
!   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
    bitmap ltrans_statics = BITMAP_ALLOC (NULL);
    int i;
  
    reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
  
    /* 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))
  	  && referenced_from_this_partition_p (&vnode->symbol.ref_list, set, vset))
  	{
*************** ipa_reference_write_optimization_summary
*** 1057,1064 ****
  
  
    if (ltrans_statics_bitcount)
!     for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
!       if (write_node_summary_p (lto_cgraph_encoder_deref (encoder, i),
  				set, vset, ltrans_statics))
  	  count++;
  
--- 1061,1069 ----
  
  
    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),
  				set, vset, ltrans_statics))
  	  count++;
  
*************** ipa_reference_write_optimization_summary
*** 1069,1084 ****
  
    /* Process all of the functions.  */
    if (ltrans_statics_bitcount)
!     for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
        {
! 	node = lto_cgraph_encoder_deref (encoder, i);
  	if (write_node_summary_p (node, set, vset, ltrans_statics))
  	  {
  	    ipa_reference_optimization_summary_t info;
  	    int node_ref;
  
  	    info = get_reference_optimization_summary (node);
! 	    node_ref = lto_cgraph_encoder_encode (encoder, node);
  	    streamer_write_uhwi_stream (ob->main_stream, node_ref);
  
  	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
--- 1074,1092 ----
  
    /* Process all of the functions.  */
    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, set, vset, 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);
  	    streamer_write_uhwi_stream (ob->main_stream, node_ref);
  
  	    stream_out_bitmap (ob, info->statics_not_read, ltrans_statics,
*************** ipa_reference_read_optimization_summary 
*** 1144,1154 ****
  	      struct cgraph_node *node;
  	      ipa_reference_optimization_summary_t info;
  	      int v_count;
! 	      lto_cgraph_encoder_t encoder;
  
  	      index = streamer_read_uhwi (ib);
! 	      encoder = file_data->cgraph_node_encoder;
! 	      node = lto_cgraph_encoder_deref (encoder, index);
  	      info = XCNEW (struct ipa_reference_optimization_summary_d);
  	      set_reference_optimization_summary (node, info);
  	      info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
--- 1152,1162 ----
  	      struct cgraph_node *node;
  	      ipa_reference_optimization_summary_t info;
  	      int v_count;
! 	      lto_symtab_encoder_t encoder;
  
  	      index = streamer_read_uhwi (ib);
! 	      encoder = file_data->symtab_node_encoder;
! 	      node = cgraph (lto_symtab_encoder_deref (encoder, index));
  	      info = XCNEW (struct ipa_reference_optimization_summary_d);
  	      set_reference_optimization_summary (node, info);
  	      info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
Index: lto-cgraph.c
===================================================================
*** lto-cgraph.c	(revision 190283)
--- lto-cgraph.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 46,54 ****
  #include "tree-streamer.h"
  #include "gcov-io.h"
  
- static void output_varpool (cgraph_node_set, varpool_node_set);
  static void output_cgraph_opt_summary (cgraph_node_set set);
! static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes);
  
  /* Number of LDPR values known to GCC.  */
  #define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1)
--- 46,53 ----
  #include "tree-streamer.h"
  #include "gcov-io.h"
  
  static void output_cgraph_opt_summary (cgraph_node_set set);
! static void input_cgraph_opt_summary (VEC (symtab_node, heap) * nodes);
  
  /* Number of LDPR values known to GCC.  */
  #define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1)
*************** static int order_base;
*** 58,86 ****
  
  /* Cgraph streaming is organized as set of record whose type
     is indicated by a tag.  */
! enum LTO_cgraph_tags
  {
    /* Must leave 0 for the stopper.  */
  
    /* Cgraph node without body available.  */
!   LTO_cgraph_unavail_node = 1,
    /* Cgraph node with function body.  */
!   LTO_cgraph_analyzed_node,
    /* Cgraph edges.  */
!   LTO_cgraph_edge,
!   LTO_cgraph_indirect_edge,
!   LTO_cgraph_last_tag
  };
  
! /* Create a new cgraph encoder.  */
  
! lto_cgraph_encoder_t
! lto_cgraph_encoder_new (void)
  {
!   lto_cgraph_encoder_t encoder = XCNEW (struct lto_cgraph_encoder_d);
    encoder->map = pointer_map_create ();
    encoder->nodes = NULL;
    encoder->body = pointer_set_create ();
    return encoder;
  }
  
--- 57,87 ----
  
  /* Cgraph streaming is organized as set of record whose type
     is indicated by a tag.  */
! enum LTO_symtab_tags
  {
    /* Must leave 0 for the stopper.  */
  
    /* Cgraph node without body available.  */
!   LTO_symtab_unavail_node = 1,
    /* Cgraph node with function body.  */
!   LTO_symtab_analyzed_node,
    /* Cgraph edges.  */
!   LTO_symtab_edge,
!   LTO_symtab_indirect_edge,
!   LTO_symtab_variable,
!   LTO_symtab_last_tag
  };
  
! /* Create a new symtab encoder.  */
  
! lto_symtab_encoder_t
! lto_symtab_encoder_new (void)
  {
!   lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
    encoder->map = pointer_map_create ();
    encoder->nodes = NULL;
    encoder->body = pointer_set_create ();
+   encoder->initializer = pointer_set_create ();
    return encoder;
  }
  
*************** lto_cgraph_encoder_new (void)
*** 88,109 ****
  /* Delete ENCODER and its components.  */
  
  void
! lto_cgraph_encoder_delete (lto_cgraph_encoder_t encoder)
  {
!    VEC_free (cgraph_node_ptr, heap, encoder->nodes);
     pointer_map_destroy (encoder->map);
     pointer_set_destroy (encoder->body);
     free (encoder);
  }
  
  
! /* Return the existing reference number of NODE in the cgraph encoder in
     output block OB.  Assign a new reference if this is the first time
     NODE is encoded.  */
  
  int
! lto_cgraph_encoder_encode (lto_cgraph_encoder_t encoder,
! 			   struct cgraph_node *node)
  {
    int ref;
    void **slot;
--- 89,111 ----
  /* Delete ENCODER and its components.  */
  
  void
! lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
  {
!    VEC_free (symtab_node, heap, encoder->nodes);
     pointer_map_destroy (encoder->map);
     pointer_set_destroy (encoder->body);
+    pointer_set_destroy (encoder->initializer);
     free (encoder);
  }
  
  
! /* Return the existing reference number of NODE in the symtab encoder in
     output block OB.  Assign a new reference if this is the first time
     NODE is encoded.  */
  
  int
! lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
! 			   symtab_node node)
  {
    int ref;
    void **slot;
*************** lto_cgraph_encoder_encode (lto_cgraph_en
*** 111,120 ****
    slot = pointer_map_contains (encoder->map, node);
    if (!slot)
      {
!       ref = VEC_length (cgraph_node_ptr, encoder->nodes);
        slot = pointer_map_insert (encoder->map, node);
        *slot = (void *) (intptr_t) ref;
!       VEC_safe_push (cgraph_node_ptr, heap, encoder->nodes, node);
      }
    else
      ref = (int) (intptr_t) *slot;
--- 113,122 ----
    slot = pointer_map_contains (encoder->map, node);
    if (!slot)
      {
!       ref = VEC_length (symtab_node, encoder->nodes);
        slot = pointer_map_insert (encoder->map, node);
        *slot = (void *) (intptr_t) ref;
!       VEC_safe_push (symtab_node, heap, encoder->nodes, node);
      }
    else
      ref = (int) (intptr_t) *slot;
*************** lto_cgraph_encoder_encode (lto_cgraph_en
*** 128,135 ****
     or LCC_NOT_FOUND if it is not there.  */
  
  int
! lto_cgraph_encoder_lookup (lto_cgraph_encoder_t encoder,
! 			   struct cgraph_node *node)
  {
    void **slot = pointer_map_contains (encoder->map, node);
    return (slot ? (int) (intptr_t) *slot : LCC_NOT_FOUND);
--- 130,137 ----
     or LCC_NOT_FOUND if it is not there.  */
  
  int
! lto_symtab_encoder_lookup (lto_symtab_encoder_t encoder,
! 			   symtab_node node)
  {
    void **slot = pointer_map_contains (encoder->map, node);
    return (slot ? (int) (intptr_t) *slot : LCC_NOT_FOUND);
*************** lto_cgraph_encoder_lookup (lto_cgraph_en
*** 138,157 ****
  
  /* Return the cgraph node corresponding to REF using ENCODER.  */
  
! struct cgraph_node *
! lto_cgraph_encoder_deref (lto_cgraph_encoder_t encoder, int ref)
  {
    if (ref == LCC_NOT_FOUND)
      return NULL;
  
!   return VEC_index (cgraph_node_ptr, encoder->nodes, ref);
  }
  
  
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  bool
! lto_cgraph_encoder_encode_body_p (lto_cgraph_encoder_t encoder,
  				  struct cgraph_node *node)
  {
    return pointer_set_contains (encoder->body, node);
--- 140,159 ----
  
  /* Return the cgraph node corresponding to REF using ENCODER.  */
  
! symtab_node
! lto_symtab_encoder_deref (lto_symtab_encoder_t encoder, int ref)
  {
    if (ref == LCC_NOT_FOUND)
      return NULL;
  
!   return VEC_index (symtab_node, encoder->nodes, ref);
  }
  
  
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  bool
! lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t encoder,
  				  struct cgraph_node *node)
  {
    return pointer_set_contains (encoder->body, node);
*************** lto_cgraph_encoder_encode_body_p (lto_cg
*** 160,250 ****
  /* Return TRUE if we should encode body of NODE (if any).  */
  
  static void
! lto_set_cgraph_encoder_encode_body (lto_cgraph_encoder_t encoder,
  				    struct cgraph_node *node)
  {
    pointer_set_insert (encoder->body, node);
  }
  
- /* Create a new varpool encoder.  */
- 
- lto_varpool_encoder_t
- lto_varpool_encoder_new (void)
- {
-   lto_varpool_encoder_t encoder = XCNEW (struct lto_varpool_encoder_d);
-   encoder->map = pointer_map_create ();
-   encoder->initializer = pointer_set_create ();
-   encoder->nodes = NULL;
-   return encoder;
- }
- 
- 
- /* Delete ENCODER and its components.  */
- 
- void
- lto_varpool_encoder_delete (lto_varpool_encoder_t encoder)
- {
-    VEC_free (varpool_node_ptr, heap, encoder->nodes);
-    pointer_map_destroy (encoder->map);
-    pointer_set_destroy (encoder->initializer);
-    free (encoder);
- }
- 
- 
- /* Return the existing reference number of NODE in the varpool encoder in
-    output block OB.  Assign a new reference if this is the first time
-    NODE is encoded.  */
- 
- int
- lto_varpool_encoder_encode (lto_varpool_encoder_t encoder,
- 			   struct varpool_node *node)
- {
-   int ref;
-   void **slot;
- 
-   slot = pointer_map_contains (encoder->map, node);
-   if (!slot)
-     {
-       ref = VEC_length (varpool_node_ptr, encoder->nodes);
-       slot = pointer_map_insert (encoder->map, node);
-       *slot = (void *) (intptr_t) ref;
-       VEC_safe_push (varpool_node_ptr, heap, encoder->nodes, node);
-     }
-   else
-     ref = (int) (intptr_t) *slot;
- 
-   return ref;
- }
- 
- /* Look up NODE in encoder.  Return NODE's reference if it has been encoded
-    or LCC_NOT_FOUND if it is not there.  */
- 
- int
- lto_varpool_encoder_lookup (lto_varpool_encoder_t encoder,
- 			   struct varpool_node *node)
- {
-   void **slot = pointer_map_contains (encoder->map, node);
-   return (slot ? (int) (intptr_t) *slot : LCC_NOT_FOUND);
- }
- 
- 
- /* Return the varpool node corresponding to REF using ENCODER.  */
- 
- struct varpool_node *
- lto_varpool_encoder_deref (lto_varpool_encoder_t encoder, int ref)
- {
-   if (ref == LCC_NOT_FOUND)
-     return NULL;
- 
-   return VEC_index (varpool_node_ptr, encoder->nodes, ref);
- }
- 
- 
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  bool
! lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t encoder,
! 					  struct varpool_node *node)
  {
    return pointer_set_contains (encoder->initializer, node);
  }
--- 162,178 ----
  /* Return TRUE if we should encode body of NODE (if any).  */
  
  static void
! lto_set_symtab_encoder_encode_body (lto_symtab_encoder_t encoder,
  				    struct cgraph_node *node)
  {
    pointer_set_insert (encoder->body, node);
  }
  
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  bool
! lto_symtab_encoder_encode_initializer_p (lto_symtab_encoder_t encoder,
! 					 struct varpool_node *node)
  {
    return pointer_set_contains (encoder->initializer, node);
  }
*************** lto_varpool_encoder_encode_initializer_p
*** 252,259 ****
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  static void
! lto_set_varpool_encoder_encode_initializer (lto_varpool_encoder_t encoder,
! 					    struct varpool_node *node)
  {
    pointer_set_insert (encoder->initializer, node);
  }
--- 180,187 ----
  /* Return TRUE if we should encode initializer of NODE (if any).  */
  
  static void
! lto_set_symtab_encoder_encode_initializer (lto_symtab_encoder_t encoder,
! 					   struct varpool_node *node)
  {
    pointer_set_insert (encoder->initializer, node);
  }
*************** lto_set_varpool_encoder_encode_initializ
*** 262,287 ****
  
  static void
  lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
! 		 lto_cgraph_encoder_t encoder)
  {
    unsigned int uid;
    intptr_t ref;
    struct bitpack_d bp;
  
    if (edge->indirect_unknown_callee)
!     streamer_write_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag,
! 			 LTO_cgraph_indirect_edge);
    else
!     streamer_write_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag,
! 			 LTO_cgraph_edge);
  
!   ref = lto_cgraph_encoder_lookup (encoder, edge->caller);
    gcc_assert (ref != LCC_NOT_FOUND);
    streamer_write_hwi_stream (ob->main_stream, ref);
  
    if (!edge->indirect_unknown_callee)
      {
!       ref = lto_cgraph_encoder_lookup (encoder, edge->callee);
        gcc_assert (ref != LCC_NOT_FOUND);
        streamer_write_hwi_stream (ob->main_stream, ref);
      }
--- 190,215 ----
  
  static void
  lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
! 		 lto_symtab_encoder_t encoder)
  {
    unsigned int uid;
    intptr_t ref;
    struct bitpack_d bp;
  
    if (edge->indirect_unknown_callee)
!     streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
! 			 LTO_symtab_indirect_edge);
    else
!     streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
! 			 LTO_symtab_edge);
  
!   ref = lto_symtab_encoder_lookup (encoder, (symtab_node)edge->caller);
    gcc_assert (ref != LCC_NOT_FOUND);
    streamer_write_hwi_stream (ob->main_stream, ref);
  
    if (!edge->indirect_unknown_callee)
      {
!       ref = lto_symtab_encoder_lookup (encoder, (symtab_node)edge->callee);
        gcc_assert (ref != LCC_NOT_FOUND);
        streamer_write_hwi_stream (ob->main_stream, ref);
      }
*************** reachable_from_this_partition_p (struct 
*** 408,414 ****
  
  static void
  lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
! 		 lto_cgraph_encoder_t encoder, cgraph_node_set set,
  		 varpool_node_set vset)
  {
    unsigned int tag;
--- 336,342 ----
  
  static void
  lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
! 		 lto_symtab_encoder_t encoder, cgraph_node_set set,
  		 varpool_node_set vset)
  {
    unsigned int tag;
*************** lto_output_node (struct lto_simple_outpu
*** 421,431 ****
    boundary_p = !cgraph_node_in_set_p (node, set);
  
    if (node->analyzed && !boundary_p)
!     tag = LTO_cgraph_analyzed_node;
    else
!     tag = LTO_cgraph_unavail_node;
  
!   streamer_write_enum (ob->main_stream, LTO_cgraph_tags, LTO_cgraph_last_tag,
  		       tag);
    streamer_write_hwi_stream (ob->main_stream, node->symbol.order);
  
--- 349,359 ----
    boundary_p = !cgraph_node_in_set_p (node, set);
  
    if (node->analyzed && !boundary_p)
!     tag = LTO_symtab_analyzed_node;
    else
!     tag = LTO_symtab_unavail_node;
  
!   streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
  		       tag);
    streamer_write_hwi_stream (ob->main_stream, node->symbol.order);
  
*************** lto_output_node (struct lto_simple_outpu
*** 454,466 ****
  
    clone_of = node->clone_of;
    while (clone_of
! 	 && (ref = lto_cgraph_encoder_lookup (encoder, clone_of)) == LCC_NOT_FOUND)
      if (clone_of->prev_sibling_clone)
        clone_of = clone_of->prev_sibling_clone;
      else
        clone_of = clone_of->clone_of;
  
!   if (LTO_cgraph_analyzed_node)
      gcc_assert (clone_of || !node->clone_of);
    if (!clone_of)
      streamer_write_hwi_stream (ob->main_stream, LCC_NOT_FOUND);
--- 382,394 ----
  
    clone_of = node->clone_of;
    while (clone_of
! 	 && (ref = lto_symtab_encoder_lookup (encoder, (symtab_node)clone_of)) == LCC_NOT_FOUND)
      if (clone_of->prev_sibling_clone)
        clone_of = clone_of->prev_sibling_clone;
      else
        clone_of = clone_of->clone_of;
  
!   if (LTO_symtab_analyzed_node)
      gcc_assert (clone_of || !node->clone_of);
    if (!clone_of)
      streamer_write_hwi_stream (ob->main_stream, LCC_NOT_FOUND);
*************** lto_output_node (struct lto_simple_outpu
*** 472,482 ****
    streamer_write_hwi_stream (ob->main_stream, node->count);
    streamer_write_hwi_stream (ob->main_stream, node->count_materialization_scale);
  
!   if (tag == LTO_cgraph_analyzed_node)
      {
        if (node->global.inlined_to)
  	{
! 	  ref = lto_cgraph_encoder_lookup (encoder, node->global.inlined_to);
  	  gcc_assert (ref != LCC_NOT_FOUND);
  	}
        else
--- 400,410 ----
    streamer_write_hwi_stream (ob->main_stream, node->count);
    streamer_write_hwi_stream (ob->main_stream, node->count_materialization_scale);
  
!   if (tag == LTO_symtab_analyzed_node)
      {
        if (node->global.inlined_to)
  	{
! 	  ref = lto_symtab_encoder_lookup (encoder, (symtab_node)node->global.inlined_to);
  	  gcc_assert (ref != LCC_NOT_FOUND);
  	}
        else
*************** lto_output_node (struct lto_simple_outpu
*** 487,494 ****
  
    if (node->symbol.same_comdat_group && !boundary_p)
      {
!       ref = lto_cgraph_encoder_lookup (encoder,
! 				       cgraph (node->symbol.same_comdat_group));
        gcc_assert (ref != LCC_NOT_FOUND);
      }
    else
--- 415,422 ----
  
    if (node->symbol.same_comdat_group && !boundary_p)
      {
!       ref = lto_symtab_encoder_lookup (encoder,
! 				       node->symbol.same_comdat_group);
        gcc_assert (ref != LCC_NOT_FOUND);
      }
    else
*************** lto_output_node (struct lto_simple_outpu
*** 505,511 ****
    bp_pack_value (&bp, node->symbol.force_output, 1);
    bp_pack_value (&bp, node->symbol.address_taken, 1);
    bp_pack_value (&bp, node->abstract_and_needed, 1);
!   bp_pack_value (&bp, tag == LTO_cgraph_analyzed_node
  		 && !DECL_EXTERNAL (node->symbol.decl)
  		 && !DECL_COMDAT (node->symbol.decl)
  		 && (reachable_from_other_partition_p (node, set)
--- 433,439 ----
    bp_pack_value (&bp, node->symbol.force_output, 1);
    bp_pack_value (&bp, node->symbol.address_taken, 1);
    bp_pack_value (&bp, node->abstract_and_needed, 1);
!   bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
  		 && !DECL_EXTERNAL (node->symbol.decl)
  		 && !DECL_COMDAT (node->symbol.decl)
  		 && (reachable_from_other_partition_p (node, set)
*************** lto_output_node (struct lto_simple_outpu
*** 554,566 ****
  
  static void
  lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
! 			 lto_varpool_encoder_t varpool_encoder,
  		         cgraph_node_set set, varpool_node_set vset)
  {
    bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed;
    struct bitpack_d bp;
    int ref;
  
    streamer_write_hwi_stream (ob->main_stream, node->symbol.order);
    lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->symbol.decl);
    bp = bitpack_create (ob->main_stream);
--- 482,496 ----
  
  static void
  lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
! 			 lto_symtab_encoder_t encoder,
  		         cgraph_node_set set, varpool_node_set vset)
  {
    bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed;
    struct bitpack_d bp;
    int ref;
  
+   streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
+ 		       LTO_symtab_variable);
    streamer_write_hwi_stream (ob->main_stream, node->symbol.order);
    lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->symbol.decl);
    bp = bitpack_create (ob->main_stream);
*************** lto_output_varpool_node (struct lto_simp
*** 593,600 ****
      lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->alias_of);
    if (node->symbol.same_comdat_group && !boundary_p)
      {
!       ref = lto_varpool_encoder_lookup (varpool_encoder,
! 					varpool (node->symbol.same_comdat_group));
        gcc_assert (ref != LCC_NOT_FOUND);
      }
    else
--- 523,530 ----
      lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->alias_of);
    if (node->symbol.same_comdat_group && !boundary_p)
      {
!       ref = lto_symtab_encoder_lookup (encoder,
! 				       node->symbol.same_comdat_group);
        gcc_assert (ref != LCC_NOT_FOUND);
      }
    else
*************** lto_output_varpool_node (struct lto_simp
*** 609,635 ****
  
  static void
  lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref,
! 		lto_cgraph_encoder_t encoder,
! 		lto_varpool_encoder_t varpool_encoder)
  {
    struct bitpack_d bp;
    bp = bitpack_create (ob->main_stream);
-   bp_pack_value (&bp, symtab_function_p (ref->referred), 1);
    bp_pack_value (&bp, ref->use, 2);
    streamer_write_bitpack (&bp);
!   if (symtab_function_p (ref->referred))
!     {
!       int nref = lto_cgraph_encoder_lookup (encoder, ipa_ref_node (ref));
!       gcc_assert (nref != LCC_NOT_FOUND);
!       streamer_write_hwi_stream (ob->main_stream, nref);
!     }
!   else
!     {
!       int nref = lto_varpool_encoder_lookup (varpool_encoder,
! 				             ipa_ref_varpool_node (ref));
!       gcc_assert (nref != LCC_NOT_FOUND);
!       streamer_write_hwi_stream (ob->main_stream, nref);
!     }
  }
  
  /* Stream out profile_summary to OB.  */
--- 539,555 ----
  
  static void
  lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref,
! 		lto_symtab_encoder_t encoder)
  {
    struct bitpack_d bp;
+   int nref;
+ 
    bp = bitpack_create (ob->main_stream);
    bp_pack_value (&bp, ref->use, 2);
    streamer_write_bitpack (&bp);
!   nref = lto_symtab_encoder_lookup (encoder, ref->referred);
!   gcc_assert (nref != LCC_NOT_FOUND);
!   streamer_write_hwi_stream (ob->main_stream, nref);
  }
  
  /* Stream out profile_summary to OB.  */
*************** output_profile_summary (struct lto_simpl
*** 654,674 ****
     Do it in a way so clones appear first.  */
  
  static void
! add_node_to (lto_cgraph_encoder_t encoder, struct cgraph_node *node,
  	     bool include_body)
  {
    if (node->clone_of)
      add_node_to (encoder, node->clone_of, include_body);
    else if (include_body)
!     lto_set_cgraph_encoder_encode_body (encoder, node);
!   lto_cgraph_encoder_encode (encoder, node);
  }
  
  /* Add all references in LIST to encoders.  */
  
  static void
! add_references (lto_cgraph_encoder_t encoder,
! 		lto_varpool_encoder_t varpool_encoder,
  		struct ipa_ref_list *list)
  {
    int i;
--- 574,593 ----
     Do it in a way so clones appear first.  */
  
  static void
! add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
  	     bool include_body)
  {
    if (node->clone_of)
      add_node_to (encoder, node->clone_of, include_body);
    else if (include_body)
!     lto_set_symtab_encoder_encode_body (encoder, node);
!   lto_symtab_encoder_encode (encoder, (symtab_node)node);
  }
  
  /* Add all references in LIST to encoders.  */
  
  static void
! add_references (lto_symtab_encoder_t encoder,
  		struct ipa_ref_list *list)
  {
    int i;
*************** add_references (lto_cgraph_encoder_t enc
*** 679,685 ****
      else
        {
  	struct varpool_node *vnode = ipa_ref_varpool_node (ref);
!         lto_varpool_encoder_encode (varpool_encoder, vnode);
        }
  }
  
--- 598,604 ----
      else
        {
  	struct varpool_node *vnode = ipa_ref_varpool_node (ref);
!         lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
        }
  }
  
*************** add_references (lto_cgraph_encoder_t enc
*** 689,695 ****
  static void
  output_outgoing_cgraph_edges (struct cgraph_edge *edge,
  			      struct lto_simple_output_block *ob,
! 			      lto_cgraph_encoder_t encoder)
  {
    if (!edge)
      return;
--- 608,614 ----
  static void
  output_outgoing_cgraph_edges (struct cgraph_edge *edge,
  			      struct lto_simple_output_block *ob,
! 			      lto_symtab_encoder_t encoder)
  {
    if (!edge)
      return;
*************** output_outgoing_cgraph_edges (struct cgr
*** 706,713 ****
  
  static void
  output_refs (cgraph_node_set set, varpool_node_set vset,
! 	     lto_cgraph_encoder_t encoder,
! 	     lto_varpool_encoder_t varpool_encoder)
  {
    cgraph_node_set_iterator csi;
    varpool_node_set_iterator vsi;
--- 625,631 ----
  
  static void
  output_refs (cgraph_node_set set, varpool_node_set vset,
! 	     lto_symtab_encoder_t encoder)
  {
    cgraph_node_set_iterator csi;
    varpool_node_set_iterator vsi;
*************** output_refs (cgraph_node_set set, varpoo
*** 727,736 ****
  	{
  	  streamer_write_uhwi_stream (ob->main_stream, count);
  	  streamer_write_uhwi_stream (ob->main_stream,
! 				     lto_cgraph_encoder_lookup (encoder, node));
  	  for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
  						      i, ref); i++)
! 	    lto_output_ref (ob, ref, encoder, varpool_encoder);
  	}
      }
  
--- 645,655 ----
  	{
  	  streamer_write_uhwi_stream (ob->main_stream, count);
  	  streamer_write_uhwi_stream (ob->main_stream,
! 				     lto_symtab_encoder_lookup (encoder, 
! 								(symtab_node)node));
  	  for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
  						      i, ref); i++)
! 	    lto_output_ref (ob, ref, encoder);
  	}
      }
  
*************** output_refs (cgraph_node_set set, varpoo
*** 745,755 ****
  	{
  	  streamer_write_uhwi_stream (ob->main_stream, count);
  	  streamer_write_uhwi_stream (ob->main_stream,
! 				     lto_varpool_encoder_lookup (varpool_encoder,
! 								 node));
  	  for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
  						      i, ref); i++)
! 	    lto_output_ref (ob, ref, encoder, varpool_encoder);
  	}
      }
  
--- 664,674 ----
  	{
  	  streamer_write_uhwi_stream (ob->main_stream, count);
  	  streamer_write_uhwi_stream (ob->main_stream,
! 				     lto_symtab_encoder_lookup (encoder,
! 								(symtab_node)node));
  	  for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
  						      i, ref); i++)
! 	    lto_output_ref (ob, ref, encoder);
  	}
      }
  
*************** compute_ltrans_boundary (struct lto_out_
*** 769,811 ****
    varpool_node_set_iterator vsi;
    struct cgraph_edge *edge;
    int i;
!   lto_cgraph_encoder_t encoder;
!   lto_varpool_encoder_t varpool_encoder;
  
!   encoder = state->cgraph_node_encoder = lto_cgraph_encoder_new ();
!   varpool_encoder = state->varpool_node_encoder = lto_varpool_encoder_new ();
  
    /* Go over all the nodes in SET and assign references.  */
    for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
      {
        node = csi_node (csi);
        add_node_to (encoder, node, true);
!       add_references (encoder, varpool_encoder, &node->symbol.ref_list);
      }
    for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi))
      {
        struct varpool_node *vnode = vsi_node (vsi);
        gcc_assert (!vnode->alias || vnode->alias_of);
!       lto_varpool_encoder_encode (varpool_encoder, vnode);
!       lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
!       add_references (encoder, varpool_encoder, &vnode->symbol.ref_list);
      }
    /* Pickle in also the initializer of all referenced readonly variables
       to help folding.  Constant pool variables are not shared, so we must
       pickle those too.  */
!   for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
      {
!       struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i);
!       if (DECL_INITIAL (vnode->symbol.decl)
! 	  && !lto_varpool_encoder_encode_initializer_p (varpool_encoder,
! 						        vnode)
! 	  && const_value_known_p (vnode->symbol.decl))
  	{
! 	  lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
! 	  add_references (encoder, varpool_encoder, &vnode->symbol.ref_list);
! 	}
!       else if (vnode->alias || vnode->alias_of)
!         add_references (encoder, varpool_encoder, &vnode->symbol.ref_list);
      }
  
    /* Go over all the nodes again to include callees that are not in
--- 688,732 ----
    varpool_node_set_iterator vsi;
    struct cgraph_edge *edge;
    int i;
!   lto_symtab_encoder_t encoder;
  
!   encoder = state->symtab_node_encoder = lto_symtab_encoder_new ();
  
    /* Go over all the nodes in SET and assign references.  */
    for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
      {
        node = csi_node (csi);
        add_node_to (encoder, node, true);
!       add_references (encoder, &node->symbol.ref_list);
      }
    for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi))
      {
        struct varpool_node *vnode = vsi_node (vsi);
        gcc_assert (!vnode->alias || vnode->alias_of);
!       lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
!       lto_set_symtab_encoder_encode_initializer (encoder, vnode);
!       add_references (encoder, &vnode->symbol.ref_list);
      }
    /* Pickle in also the initializer of all referenced readonly variables
       to help folding.  Constant pool variables are not shared, so we must
       pickle those too.  */
!   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
      {
!       symtab_node node = lto_symtab_encoder_deref (encoder, i);
!       if (symtab_variable_p (node))
  	{
! 	  struct varpool_node *vnode = varpool (node);
! 	  if (DECL_INITIAL (vnode->symbol.decl)
! 	      && !lto_symtab_encoder_encode_initializer_p (encoder,
! 							   vnode)
! 	      && const_value_known_p (vnode->symbol.decl))
! 	    {
! 	      lto_set_symtab_encoder_encode_initializer (encoder, vnode);
! 	      add_references (encoder, &vnode->symbol.ref_list);
! 	    }
! 	  else if (vnode->alias || vnode->alias_of)
! 	    add_references (encoder, &vnode->symbol.ref_list);
!        }
      }
  
    /* Go over all the nodes again to include callees that are not in
*************** output_cgraph (cgraph_node_set set, varp
*** 835,842 ****
    struct lto_simple_output_block *ob;
    cgraph_node_set_iterator csi;
    int i, n_nodes;
!   lto_cgraph_encoder_t encoder;
!   lto_varpool_encoder_t varpool_encoder;
    static bool asm_nodes_output = false;
  
    if (flag_wpa)
--- 756,762 ----
    struct lto_simple_output_block *ob;
    cgraph_node_set_iterator csi;
    int i, n_nodes;
!   lto_symtab_encoder_t encoder;
    static bool asm_nodes_output = false;
  
    if (flag_wpa)
*************** output_cgraph (cgraph_node_set set, varp
*** 848,866 ****
  
    /* An encoder for cgraph nodes should have been created by
       ipa_write_summaries_1.  */
!   gcc_assert (ob->decl_state->cgraph_node_encoder);
!   gcc_assert (ob->decl_state->varpool_node_encoder);
!   encoder = ob->decl_state->cgraph_node_encoder;
!   varpool_encoder = ob->decl_state->varpool_node_encoder;
  
    /* Write out the nodes.  We must first output a node and then its clones,
       otherwise at a time reading back the node there would be nothing to clone
       from.  */
!   n_nodes = lto_cgraph_encoder_size (encoder);
    for (i = 0; i < n_nodes; i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
!       lto_output_node (ob, node, encoder, set, vset);
      }
  
    /* Go over the nodes in SET again to write edges.  */
--- 768,789 ----
  
    /* An encoder for cgraph nodes should have been created by
       ipa_write_summaries_1.  */
!   gcc_assert (ob->decl_state->symtab_node_encoder);
!   encoder = ob->decl_state->symtab_node_encoder;
  
    /* Write out the nodes.  We must first output a node and then its clones,
       otherwise at a time reading back the node there would be nothing to clone
       from.  */
!   n_nodes = lto_symtab_encoder_size (encoder);
    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, set, vset);
!       else
!         lto_output_varpool_node (ob, varpool (node), encoder,
! 			         set, vset);
! 	
      }
  
    /* Go over the nodes in SET again to write edges.  */
*************** output_cgraph (cgraph_node_set set, varp
*** 885,892 ****
        lto_output_toplevel_asms ();
      }
  
!   output_varpool (set, vset);
!   output_refs (set, vset, encoder, varpool_encoder);
  }
  
  /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
--- 808,814 ----
        lto_output_toplevel_asms ();
      }
  
!   output_refs (set, vset, encoder);
  }
  
  /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
*************** output_cgraph (cgraph_node_set set, varp
*** 899,905 ****
  static void
  input_overwrite_node (struct lto_file_decl_data *file_data,
  		      struct cgraph_node *node,
! 		      enum LTO_cgraph_tags tag,
  		      struct bitpack_d *bp)
  {
    node->symbol.aux = (void *) tag;
--- 821,827 ----
  static void
  input_overwrite_node (struct lto_file_decl_data *file_data,
  		      struct cgraph_node *node,
! 		      enum LTO_symtab_tags tag,
  		      struct bitpack_d *bp)
  {
    node->symbol.aux = (void *) tag;
*************** input_overwrite_node (struct lto_file_de
*** 916,922 ****
    node->abstract_and_needed = bp_unpack_value (bp, 1);
    node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
    node->lowered = bp_unpack_value (bp, 1);
!   node->analyzed = tag == LTO_cgraph_analyzed_node;
    node->symbol.in_other_partition = bp_unpack_value (bp, 1);
    if (node->symbol.in_other_partition
        /* Avoid updating decl when we are seeing just inline clone.
--- 838,844 ----
    node->abstract_and_needed = bp_unpack_value (bp, 1);
    node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
    node->lowered = bp_unpack_value (bp, 1);
!   node->analyzed = tag == LTO_symtab_analyzed_node;
    node->symbol.in_other_partition = bp_unpack_value (bp, 1);
    if (node->symbol.in_other_partition
        /* Avoid updating decl when we are seeing just inline clone.
*************** input_overwrite_node (struct lto_file_de
*** 942,979 ****
  				     LDPR_NUM_KNOWN);
  }
  
- /* Output the part of the cgraph in SET.  */
- 
- static void
- output_varpool (cgraph_node_set set, varpool_node_set vset)
- {
-   struct lto_simple_output_block *ob = lto_create_simple_output_block (LTO_section_varpool);
-   lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
-   int len = lto_varpool_encoder_size (varpool_encoder), i;
- 
-   streamer_write_uhwi_stream (ob->main_stream, len);
- 
-   /* Write out the nodes.  We must first output a node and then its clones,
-      otherwise at a time reading back the node there would be nothing to clone
-      from.  */
-   for (i = 0; i < len; i++)
-     {
-       lto_output_varpool_node (ob, lto_varpool_encoder_deref (varpool_encoder, i),
-       			       varpool_encoder,
- 			       set, vset);
-     }
- 
-   lto_destroy_simple_output_block (ob);
- }
- 
  /* Read a node from input_block IB.  TAG is the node's tag just read.
     Return the node read or overwriten.  */
  
  static struct cgraph_node *
  input_node (struct lto_file_decl_data *file_data,
  	    struct lto_input_block *ib,
! 	    enum LTO_cgraph_tags tag,
! 	    VEC(cgraph_node_ptr, heap) *nodes)
  {
    tree fn_decl;
    struct cgraph_node *node;
--- 864,877 ----
  				     LDPR_NUM_KNOWN);
  }
  
  /* Read a node from input_block IB.  TAG is the node's tag just read.
     Return the node read or overwriten.  */
  
  static struct cgraph_node *
  input_node (struct lto_file_decl_data *file_data,
  	    struct lto_input_block *ib,
! 	    enum LTO_symtab_tags tag,
! 	    VEC(symtab_node, heap) *nodes)
  {
    tree fn_decl;
    struct cgraph_node *node;
*************** input_node (struct lto_file_decl_data *f
*** 991,997 ****
  
    if (clone_ref != LCC_NOT_FOUND)
      {
!       node = cgraph_clone_node (VEC_index (cgraph_node_ptr, nodes, clone_ref), fn_decl,
  				0, CGRAPH_FREQ_BASE, false, NULL, false);
      }
    else
--- 889,895 ----
  
    if (clone_ref != LCC_NOT_FOUND)
      {
!       node = cgraph_clone_node (cgraph (VEC_index (symtab_node, nodes, clone_ref)), fn_decl,
  				0, CGRAPH_FREQ_BASE, false, NULL, false);
      }
    else
*************** input_node (struct lto_file_decl_data *f
*** 1004,1010 ****
    node->count = streamer_read_hwi (ib);
    node->count_materialization_scale = streamer_read_hwi (ib);
  
!   if (tag == LTO_cgraph_analyzed_node)
      ref = streamer_read_hwi (ib);
  
    ref2 = streamer_read_hwi (ib);
--- 902,908 ----
    node->count = streamer_read_hwi (ib);
    node->count_materialization_scale = streamer_read_hwi (ib);
  
!   if (tag == LTO_symtab_analyzed_node)
      ref = streamer_read_hwi (ib);
  
    ref2 = streamer_read_hwi (ib);
*************** input_varpool_node (struct lto_file_decl
*** 1107,1131 ****
  static void
  input_ref (struct lto_input_block *ib,
  	   symtab_node referring_node,
! 	   VEC(cgraph_node_ptr, heap) *nodes,
! 	   VEC(varpool_node_ptr, heap) *varpool_nodes_vec)
  {
!   struct cgraph_node *node = NULL;
!   struct varpool_node *varpool_node = NULL;
    struct bitpack_d bp;
-   int type;
    enum ipa_ref_use use;
  
    bp = streamer_read_bitpack (ib);
-   type = bp_unpack_value (&bp, 1);
    use = (enum ipa_ref_use) bp_unpack_value (&bp, 2);
!   if (type)
!     node = VEC_index (cgraph_node_ptr, nodes, streamer_read_hwi (ib));
!   else
!     varpool_node = VEC_index (varpool_node_ptr, varpool_nodes_vec,
! 			      streamer_read_hwi (ib));
!   ipa_record_reference (referring_node,
! 		        node ? (symtab_node) node : (symtab_node) varpool_node, use, NULL);
  }
  
  /* Read an edge from IB.  NODES points to a vector of previously read nodes for
--- 1005,1020 ----
  static void
  input_ref (struct lto_input_block *ib,
  	   symtab_node referring_node,
! 	   VEC(symtab_node, heap) *nodes)
  {
!   symtab_node node = NULL;
    struct bitpack_d bp;
    enum ipa_ref_use use;
  
    bp = streamer_read_bitpack (ib);
    use = (enum ipa_ref_use) bp_unpack_value (&bp, 2);
!   node = VEC_index (symtab_node, nodes, streamer_read_hwi (ib));
!   ipa_record_reference (referring_node, node, use, NULL);
  }
  
  /* Read an edge from IB.  NODES points to a vector of previously read nodes for
*************** input_ref (struct lto_input_block *ib,
*** 1134,1140 ****
     indirect_unknown_callee set).  */
  
  static void
! input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
  	    bool indirect)
  {
    struct cgraph_node *caller, *callee;
--- 1023,1029 ----
     indirect_unknown_callee set).  */
  
  static void
! input_edge (struct lto_input_block *ib, VEC(symtab_node, heap) *nodes,
  	    bool indirect)
  {
    struct cgraph_node *caller, *callee;
*************** input_edge (struct lto_input_block *ib, 
*** 1146,1158 ****
    struct bitpack_d bp;
    int ecf_flags = 0;
  
!   caller = VEC_index (cgraph_node_ptr, nodes, streamer_read_hwi (ib));
    if (caller == NULL || caller->symbol.decl == NULL_TREE)
      internal_error ("bytecode stream: no caller found while reading edge");
  
    if (!indirect)
      {
!       callee = VEC_index (cgraph_node_ptr, nodes, streamer_read_hwi (ib));
        if (callee == NULL || callee->symbol.decl == NULL_TREE)
  	internal_error ("bytecode stream: no callee found while reading edge");
      }
--- 1035,1047 ----
    struct bitpack_d bp;
    int ecf_flags = 0;
  
!   caller = cgraph (VEC_index (symtab_node, nodes, streamer_read_hwi (ib)));
    if (caller == NULL || caller->symbol.decl == NULL_TREE)
      internal_error ("bytecode stream: no caller found while reading edge");
  
    if (!indirect)
      {
!       callee = cgraph (VEC_index (symtab_node, nodes, streamer_read_hwi (ib)));
        if (callee == NULL || callee->symbol.decl == NULL_TREE)
  	internal_error ("bytecode stream: no callee found while reading edge");
      }
*************** input_edge (struct lto_input_block *ib, 
*** 1197,1313 ****
  
  /* Read a cgraph from IB using the info in FILE_DATA.  */
  
! static VEC(cgraph_node_ptr, heap) *
  input_cgraph_1 (struct lto_file_decl_data *file_data,
  		struct lto_input_block *ib)
  {
!   enum LTO_cgraph_tags tag;
!   VEC(cgraph_node_ptr, heap) *nodes = NULL;
!   struct cgraph_node *node;
    unsigned i;
  
!   tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
    order_base = symtab_order;
    while (tag)
      {
!       if (tag == LTO_cgraph_edge)
          input_edge (ib, nodes, false);
!       else if (tag == LTO_cgraph_indirect_edge)
          input_edge (ib, nodes, true);
        else
  	{
! 	  node = input_node (file_data, ib, tag,nodes);
  	  if (node == NULL || node->symbol.decl == NULL_TREE)
  	    internal_error ("bytecode stream: found empty cgraph node");
! 	  VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
! 	  lto_cgraph_encoder_encode (file_data->cgraph_node_encoder, node);
  	}
  
!       tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
      }
  
    lto_input_toplevel_asms (file_data, order_base);
  
!   /* AUX pointers should be all non-zero for nodes read from the stream.  */
  #ifdef ENABLE_CHECKING
!   FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node)
!     gcc_assert (node->symbol.aux);
  #endif
!   FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node)
      {
!       int ref = (int) (intptr_t) node->global.inlined_to;
! 
!       /* We share declaration of builtins, so we may read same node twice.  */
!       if (!node->symbol.aux)
! 	continue;
!       node->symbol.aux = NULL;
  
!       /* Fixup inlined_to from reference to pointer.  */
!       if (ref != LCC_NOT_FOUND)
! 	node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
!       else
! 	node->global.inlined_to = NULL;
  
        ref = (int) (intptr_t) node->symbol.same_comdat_group;
  
        /* Fixup same_comdat_group from reference to pointer.  */
        if (ref != LCC_NOT_FOUND)
! 	node->symbol.same_comdat_group = (symtab_node)VEC_index (cgraph_node_ptr, nodes, ref);
        else
  	node->symbol.same_comdat_group = NULL;
      }
!   FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node)
!     node->symbol.aux = (void *)1;
    return nodes;
  }
  
- /* Read a varpool from IB using the info in FILE_DATA.  */
- 
- static VEC(varpool_node_ptr, heap) *
- input_varpool_1 (struct lto_file_decl_data *file_data,
- 		struct lto_input_block *ib)
- {
-   unsigned HOST_WIDE_INT len;
-   VEC(varpool_node_ptr, heap) *varpool = NULL;
-   int i;
-   struct varpool_node *node;
- 
-   len = streamer_read_uhwi (ib);
-   while (len)
-     {
-       VEC_safe_push (varpool_node_ptr, heap, varpool,
- 		     input_varpool_node (file_data, ib));
-       len--;
-     }
- #ifdef ENABLE_CHECKING
-   FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node)
-     gcc_assert (!node->symbol.aux);
- #endif
-   FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node)
-     {
-       int ref = (int) (intptr_t) node->symbol.same_comdat_group;
-       /* We share declaration of builtins, so we may read same node twice.  */
-       if (node->symbol.aux)
- 	continue;
-       node->symbol.aux = (void *)1;
- 
-       /* Fixup same_comdat_group from reference to pointer.  */
-       if (ref != LCC_NOT_FOUND)
- 	node->symbol.same_comdat_group = (symtab_node)VEC_index (varpool_node_ptr, varpool, ref);
-       else
- 	node->symbol.same_comdat_group = NULL;
-     }
-   FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node)
-     node->symbol.aux = NULL;
-   return varpool;
- }
- 
  /* Input ipa_refs.  */
  
  static void
  input_refs (struct lto_input_block *ib,
! 	    VEC(cgraph_node_ptr, heap) *nodes,
! 	    VEC(varpool_node_ptr, heap) *varpool)
  {
    int count;
    int idx;
--- 1086,1170 ----
  
  /* Read a cgraph from IB using the info in FILE_DATA.  */
  
! static VEC(symtab_node, heap) *
  input_cgraph_1 (struct lto_file_decl_data *file_data,
  		struct lto_input_block *ib)
  {
!   enum LTO_symtab_tags tag;
!   VEC(symtab_node, heap) *nodes = NULL;
!   symtab_node node;
    unsigned i;
  
!   tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
    order_base = symtab_order;
    while (tag)
      {
!       if (tag == LTO_symtab_edge)
          input_edge (ib, nodes, false);
!       else if (tag == LTO_symtab_indirect_edge)
          input_edge (ib, nodes, true);
+       else if (tag == LTO_symtab_variable)
+         {
+ 	  node = (symtab_node)input_varpool_node (file_data, ib);
+           VEC_safe_push (symtab_node, heap, nodes, node);
+ 	  lto_symtab_encoder_encode (file_data->symtab_node_encoder, node);
+         }
        else
  	{
! 	  node = (symtab_node)input_node (file_data, ib, tag, nodes);
  	  if (node == NULL || node->symbol.decl == NULL_TREE)
  	    internal_error ("bytecode stream: found empty cgraph node");
! 	  VEC_safe_push (symtab_node, heap, nodes, node);
! 	  lto_symtab_encoder_encode (file_data->symtab_node_encoder, node);
  	}
  
!       tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
      }
  
    lto_input_toplevel_asms (file_data, order_base);
  
!   /* 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));
  #endif
!   FOR_EACH_VEC_ELT (symtab_node, nodes, i, node)
      {
!       int ref;
!       if (symtab_function_p (node))
! 	{
! 	  ref = (int) (intptr_t) cgraph (node)->global.inlined_to;
  
! 	  /* We share declaration of builtins, so we may read same node twice.  */
! 	  if (!node->symbol.aux)
! 	    continue;
! 	  node->symbol.aux = NULL;
! 
! 	  /* Fixup inlined_to from reference to pointer.  */
! 	  if (ref != LCC_NOT_FOUND)
! 	    cgraph (node)->global.inlined_to = cgraph (VEC_index (symtab_node, nodes, ref));
! 	  else
! 	    cgraph (node)->global.inlined_to = NULL;
! 	}
  
        ref = (int) (intptr_t) node->symbol.same_comdat_group;
  
        /* Fixup same_comdat_group from reference to pointer.  */
        if (ref != LCC_NOT_FOUND)
! 	node->symbol.same_comdat_group = VEC_index (symtab_node, nodes, ref);
        else
  	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;
    return nodes;
  }
  
  /* Input ipa_refs.  */
  
  static void
  input_refs (struct lto_input_block *ib,
! 	    VEC(symtab_node, heap) *nodes)
  {
    int count;
    int idx;
*************** input_refs (struct lto_input_block *ib,
*** 1318,1327 ****
        if (!count)
  	break;
        idx = streamer_read_uhwi (ib);
!       node = VEC_index (cgraph_node_ptr, nodes, idx);
        while (count)
  	{
! 	  input_ref (ib, (symtab_node) node, nodes, varpool);
  	  count--;
  	}
      }
--- 1175,1184 ----
        if (!count)
  	break;
        idx = streamer_read_uhwi (ib);
!       node = cgraph (VEC_index (symtab_node, nodes, idx));
        while (count)
  	{
! 	  input_ref (ib, (symtab_node) node, nodes);
  	  count--;
  	}
      }
*************** input_refs (struct lto_input_block *ib,
*** 1331,1341 ****
        count = streamer_read_uhwi (ib);
        if (!count)
  	break;
!       node = VEC_index (varpool_node_ptr, varpool,
! 			streamer_read_uhwi (ib));
        while (count)
  	{
! 	  input_ref (ib, (symtab_node) node, nodes, varpool);
  	  count--;
  	}
      }
--- 1188,1198 ----
        count = streamer_read_uhwi (ib);
        if (!count)
  	break;
!       node = varpool (VEC_index (symtab_node, nodes,
! 		      streamer_read_uhwi (ib)));
        while (count)
  	{
! 	  input_ref (ib, (symtab_node) node, nodes);
  	  count--;
  	}
      }
*************** input_cgraph (void)
*** 1462,1499 ****
        const char *data;
        size_t len;
        struct lto_input_block *ib;
!       VEC(cgraph_node_ptr, heap) *nodes;
!       VEC(varpool_node_ptr, heap) *varpool;
  
        ib = lto_create_simple_input_block (file_data, LTO_section_cgraph,
  					  &data, &len);
        if (!ib) 
  	fatal_error ("cannot find LTO cgraph in %s", file_data->file_name);
        input_profile_summary (ib, file_data);
!       file_data->cgraph_node_encoder = lto_cgraph_encoder_new ();
        nodes = input_cgraph_1 (file_data, ib);
        lto_destroy_simple_input_block (file_data, LTO_section_cgraph,
  				      ib, data, len);
  
-       ib = lto_create_simple_input_block (file_data, LTO_section_varpool,
- 					  &data, &len);
-       if (!ib)
- 	fatal_error ("cannot find LTO varpool in %s", file_data->file_name);
-       varpool = input_varpool_1 (file_data, ib);
-       lto_destroy_simple_input_block (file_data, LTO_section_varpool,
- 				      ib, data, len);
- 
        ib = lto_create_simple_input_block (file_data, LTO_section_refs,
  					  &data, &len);
        if (!ib)
  	fatal_error("cannot find LTO section refs in %s", file_data->file_name);
!       input_refs (ib, nodes, varpool);
        lto_destroy_simple_input_block (file_data, LTO_section_refs,
  				      ib, data, len);
        if (flag_ltrans)
  	input_cgraph_opt_summary (nodes);
!       VEC_free (cgraph_node_ptr, heap, nodes);
!       VEC_free (varpool_node_ptr, heap, varpool);
      }
  
    merge_profile_summaries (file_data_vec);
--- 1319,1346 ----
        const char *data;
        size_t len;
        struct lto_input_block *ib;
!       VEC(symtab_node, heap) *nodes;
  
        ib = lto_create_simple_input_block (file_data, LTO_section_cgraph,
  					  &data, &len);
        if (!ib) 
  	fatal_error ("cannot find LTO cgraph in %s", file_data->file_name);
        input_profile_summary (ib, file_data);
!       file_data->symtab_node_encoder = lto_symtab_encoder_new ();
        nodes = input_cgraph_1 (file_data, ib);
        lto_destroy_simple_input_block (file_data, LTO_section_cgraph,
  				      ib, data, len);
  
        ib = lto_create_simple_input_block (file_data, LTO_section_refs,
  					  &data, &len);
        if (!ib)
  	fatal_error("cannot find LTO section refs in %s", file_data->file_name);
!       input_refs (ib, nodes);
        lto_destroy_simple_input_block (file_data, LTO_section_refs,
  				      ib, data, len);
        if (flag_ltrans)
  	input_cgraph_opt_summary (nodes);
!       VEC_free (symtab_node, heap, nodes);
      }
  
    merge_profile_summaries (file_data_vec);
*************** output_node_opt_summary (struct output_b
*** 1598,1624 ****
  static void
  output_cgraph_opt_summary (cgraph_node_set set)
  {
!   struct cgraph_node *node;
    int i, n_nodes;
!   lto_cgraph_encoder_t encoder;
    struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum);
    unsigned count = 0;
  
    ob->cgraph_node = NULL;
!   encoder = ob->decl_state->cgraph_node_encoder;
!   n_nodes = lto_cgraph_encoder_size (encoder);
    for (i = 0; i < n_nodes; i++)
!     if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i),
! 				     set))
        count++;
    streamer_write_uhwi (ob, count);
    for (i = 0; i < n_nodes; i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
!       if (output_cgraph_opt_summary_p (node, set))
  	{
  	  streamer_write_uhwi (ob, i);
! 	  output_node_opt_summary (ob, node, set);
  	}
      }
    produce_asm (ob, NULL);
--- 1445,1472 ----
  static void
  output_cgraph_opt_summary (cgraph_node_set set)
  {
!   symtab_node node;
    int i, n_nodes;
!   lto_symtab_encoder_t encoder;
    struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum);
    unsigned count = 0;
  
    ob->cgraph_node = NULL;
!   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), set))
        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), set))
  	{
  	  streamer_write_uhwi (ob, i);
! 	  output_node_opt_summary (ob, cgraph (node), set);
  	}
      }
    produce_asm (ob, NULL);
*************** input_node_opt_summary (struct cgraph_no
*** 1690,1696 ****
  
  static void
  input_cgraph_opt_section (struct lto_file_decl_data *file_data,
! 			  const char *data, size_t len, VEC (cgraph_node_ptr,
  							     heap) * nodes)
  {
    const struct lto_function_header *header =
--- 1538,1544 ----
  
  static void
  input_cgraph_opt_section (struct lto_file_decl_data *file_data,
! 			  const char *data, size_t len, VEC (symtab_node,
  							     heap) * nodes)
  {
    const struct lto_function_header *header =
*************** input_cgraph_opt_section (struct lto_fil
*** 1714,1720 ****
    for (i = 0; i < count; i++)
      {
        int ref = streamer_read_uhwi (&ib_main);
!       input_node_opt_summary (VEC_index (cgraph_node_ptr, nodes, ref),
  			      &ib_main, data_in);
      }
    lto_free_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, data,
--- 1562,1568 ----
    for (i = 0; i < count; i++)
      {
        int ref = streamer_read_uhwi (&ib_main);
!       input_node_opt_summary (cgraph (VEC_index (symtab_node, nodes, ref)),
  			      &ib_main, data_in);
      }
    lto_free_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, data,
*************** input_cgraph_opt_section (struct lto_fil
*** 1725,1731 ****
  /* Input optimization summary of cgraph.  */
  
  static void
! input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes)
  {
    struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    struct lto_file_decl_data *file_data;
--- 1573,1579 ----
  /* Input optimization summary of cgraph.  */
  
  static void
! input_cgraph_opt_summary (VEC (symtab_node, heap) * nodes)
  {
    struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    struct lto_file_decl_data *file_data;
Index: ipa-pure-const.c
===================================================================
*** ipa-pure-const.c	(revision 190283)
--- ipa-pure-const.c	(working copy)
*************** pure_const_write_summary (cgraph_node_se
*** 962,973 ****
  	  struct bitpack_d bp;
  	  funct_state fs;
  	  int node_ref;
! 	  lto_cgraph_encoder_t encoder;
  
  	  fs = get_function_state (node);
  
! 	  encoder = ob->decl_state->cgraph_node_encoder;
! 	  node_ref = lto_cgraph_encoder_encode (encoder, node);
  	  streamer_write_uhwi_stream (ob->main_stream, node_ref);
  
  	  /* Note that flags will need to be read in the opposite
--- 962,973 ----
  	  struct bitpack_d bp;
  	  funct_state fs;
  	  int node_ref;
! 	  lto_symtab_encoder_t encoder;
  
  	  fs = get_function_state (node);
  
! 	  encoder = ob->decl_state->symtab_node_encoder;
! 	  node_ref = lto_symtab_encoder_encode (encoder, (symtab_node)node);
  	  streamer_write_uhwi_stream (ob->main_stream, node_ref);
  
  	  /* Note that flags will need to be read in the opposite
*************** pure_const_read_summary (void)
*** 1015,1026 ****
  	      struct cgraph_node *node;
  	      struct bitpack_d bp;
  	      funct_state fs;
! 	      lto_cgraph_encoder_t encoder;
  
  	      fs = XCNEW (struct funct_state_d);
  	      index = streamer_read_uhwi (ib);
! 	      encoder = file_data->cgraph_node_encoder;
! 	      node = lto_cgraph_encoder_deref (encoder, index);
  	      set_function_state (node, fs);
  
  	      /* Note that the flags must be read in the opposite
--- 1015,1026 ----
  	      struct cgraph_node *node;
  	      struct bitpack_d bp;
  	      funct_state fs;
! 	      lto_symtab_encoder_t encoder;
  
  	      fs = XCNEW (struct funct_state_d);
  	      index = streamer_read_uhwi (ib);
! 	      encoder = file_data->symtab_node_encoder;
! 	      node = cgraph (lto_symtab_encoder_deref (encoder, index));
  	      set_function_state (node, fs);
  
  	      /* Note that the flags must be read in the opposite
Index: lto-streamer-out.c
===================================================================
*** lto-streamer-out.c	(revision 190283)
--- lto-streamer-out.c	(working copy)
*************** lto_write_tree (struct output_block *ob,
*** 348,360 ****
  	  && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
  	  && initial)
  	{
! 	  lto_varpool_encoder_t varpool_encoder;
  	  struct varpool_node *vnode;
  
! 	  varpool_encoder = ob->decl_state->varpool_node_encoder;
  	  vnode = varpool_get_node (expr);
  	  if (!vnode
! 	      || !lto_varpool_encoder_encode_initializer_p (varpool_encoder,
  							    vnode))
  	    initial = error_mark_node;
  	}
--- 348,360 ----
  	  && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
  	  && initial)
  	{
! 	  lto_symtab_encoder_t encoder;
  	  struct varpool_node *vnode;
  
! 	  encoder = ob->decl_state->symtab_node_encoder;
  	  vnode = varpool_get_node (expr);
  	  if (!vnode
! 	      || !lto_symtab_encoder_encode_initializer_p (encoder,
  							    vnode))
  	    initial = error_mark_node;
  	}
*************** lto_output (cgraph_node_set set, varpool
*** 979,995 ****
    bitmap output = lto_bitmap_alloc ();
  #endif
    int i, n_nodes;
!   lto_cgraph_encoder_t encoder = lto_get_out_decl_state ()->cgraph_node_encoder;
  
    /* Initialize the streamer.  */
    lto_streamer_init ();
  
!   n_nodes = lto_cgraph_encoder_size (encoder);
    /* Process only the functions with bodies.  */
    for (i = 0; i < n_nodes; i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
!       if (lto_cgraph_encoder_encode_body_p (encoder, node)
  	  && !node->alias
  	  && !node->thunk.thunk_p)
  	{
--- 979,998 ----
    bitmap output = lto_bitmap_alloc ();
  #endif
    int i, n_nodes;
!   lto_symtab_encoder_t encoder = lto_get_out_decl_state ()->symtab_node_encoder;
  
    /* Initialize the streamer.  */
    lto_streamer_init ();
  
!   n_nodes = lto_symtab_encoder_size (encoder);
    /* Process only the functions with bodies.  */
    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)
  	  && !node->alias
  	  && !node->thunk.thunk_p)
  	{
*************** produce_symtab (struct output_block *ob)
*** 1286,1293 ****
    struct cgraph_node *node;
    struct varpool_node *vnode;
    struct lto_output_stream stream;
!   lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
!   lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
    int i;
  
    lto_begin_section (section_name, false);
--- 1289,1295 ----
    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;
  
    lto_begin_section (section_name, false);
*************** produce_symtab (struct output_block *ob)
*** 1299,1307 ****
    /* Write all functions. 
       First write all defined functions and then write all used functions.
       This is done so only to handle duplicated symbols in cgraph.  */
!   for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
        if (DECL_EXTERNAL (node->symbol.decl))
  	continue;
        if (DECL_COMDAT (node->symbol.decl)
--- 1301,1311 ----
    /* Write all functions. 
       First write all defined functions and then write all used functions.
       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)))
! 	continue;
!       node = cgraph (lto_symtab_encoder_deref (encoder, i));
        if (DECL_EXTERNAL (node->symbol.decl))
  	continue;
        if (DECL_COMDAT (node->symbol.decl)
*************** produce_symtab (struct output_block *ob)
*** 1311,1319 ****
  	continue;
        write_symbol (cache, &stream, node->symbol.decl, seen, false);
      }
!   for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
        if (!DECL_EXTERNAL (node->symbol.decl))
  	continue;
        /* We keep around unused extern inlines in order to be able to inline
--- 1315,1325 ----
  	continue;
        write_symbol (cache, &stream, node->symbol.decl, seen, false);
      }
!   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
      {
!       if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
! 	continue;
!       node = cgraph (lto_symtab_encoder_deref (encoder, i));
        if (!DECL_EXTERNAL (node->symbol.decl))
  	continue;
        /* We keep around unused extern inlines in order to be able to inline
*************** produce_symtab (struct output_block *ob)
*** 1330,1338 ****
      }
  
    /* Write all variables.  */
!   for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
      {
!       vnode = lto_varpool_encoder_deref (varpool_encoder, i);
        if (DECL_EXTERNAL (vnode->symbol.decl))
  	continue;
        /* COMDAT virtual tables can be unshared.  Do not declare them
--- 1336,1346 ----
      }
  
    /* Write all variables.  */
!   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
      {
!       if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
! 	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
*************** produce_symtab (struct output_block *ob)
*** 1347,1355 ****
  	continue;
        write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
      }
!   for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++)
      {
!       vnode = lto_varpool_encoder_deref (varpool_encoder, i);
        if (!DECL_EXTERNAL (vnode->symbol.decl))
  	continue;
        if (DECL_COMDAT (vnode->symbol.decl)
--- 1355,1365 ----
  	continue;
        write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
      }
!   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
      {
!       if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
! 	continue;
!       vnode = varpool (lto_symtab_encoder_deref (encoder, i));
        if (!DECL_EXTERNAL (vnode->symbol.decl))
  	continue;
        if (DECL_COMDAT (vnode->symbol.decl)
*************** produce_asm_for_decls (cgraph_node_set s
*** 1478,1485 ****
  	VEC_index (lto_out_decl_state_ptr, lto_function_decl_states, idx);
        lto_delete_out_decl_state (fn_out_state);
      }
!   lto_cgraph_encoder_delete (ob->decl_state->cgraph_node_encoder);
!   lto_varpool_encoder_delete (ob->decl_state->varpool_node_encoder);
    VEC_free (lto_out_decl_state_ptr, heap, lto_function_decl_states);
    lto_function_decl_states = NULL;
    destroy_output_block (ob);
--- 1488,1494 ----
  	VEC_index (lto_out_decl_state_ptr, lto_function_decl_states, idx);
        lto_delete_out_decl_state (fn_out_state);
      }
!   lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder);
    VEC_free (lto_out_decl_state_ptr, heap, lto_function_decl_states);
    lto_function_decl_states = NULL;
    destroy_output_block (ob);
Index: ipa-inline-analysis.c
===================================================================
*** ipa-inline-analysis.c	(revision 190283)
--- ipa-inline-analysis.c	(working copy)
*************** inline_read_section (struct lto_file_dec
*** 3053,3065 ****
        unsigned int index;
        struct cgraph_node *node;
        struct inline_summary *info;
!       lto_cgraph_encoder_t encoder;
        struct bitpack_d bp;
        struct cgraph_edge *e;
  
        index = streamer_read_uhwi (&ib);
!       encoder = file_data->cgraph_node_encoder;
!       node = lto_cgraph_encoder_deref (encoder, index);
        info = inline_summary (node);
  
        info->estimated_stack_size
--- 3053,3065 ----
        unsigned int index;
        struct cgraph_node *node;
        struct inline_summary *info;
!       lto_symtab_encoder_t encoder;
        struct bitpack_d bp;
        struct cgraph_edge *e;
  
        index = streamer_read_uhwi (&ib);
!       encoder = file_data->symtab_node_encoder;
!       node = cgraph (lto_symtab_encoder_deref (encoder, index));
        info = inline_summary (node);
  
        info->estimated_stack_size
*************** inline_write_summary (cgraph_node_set se
*** 3186,3205 ****
  		      varpool_node_set vset ATTRIBUTE_UNUSED)
  {
    struct cgraph_node *node;
    struct output_block *ob = create_output_block (LTO_section_inline_summary);
!   lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
    unsigned int count = 0;
    int i;
  
!   for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
!     if (lto_cgraph_encoder_deref (encoder, i)->analyzed)
        count++;
    streamer_write_uhwi (ob, count);
  
!   for (i = 0; i < lto_cgraph_encoder_size (encoder); i++)
      {
!       node = lto_cgraph_encoder_deref (encoder, i);
!       if (node->analyzed)
  	{
  	  struct inline_summary *info = inline_summary (node);
  	  struct bitpack_d bp;
--- 3186,3207 ----
  		      varpool_node_set vset ATTRIBUTE_UNUSED)
  {
    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++;
    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)
  	{
  	  struct inline_summary *info = inline_summary (node);
  	  struct bitpack_d bp;
*************** inline_write_summary (cgraph_node_set se
*** 3208,3214 ****
  	  size_time_entry *e;
  	  struct condition *c;
  
! 	  streamer_write_uhwi (ob, lto_cgraph_encoder_encode (encoder, node));
  	  streamer_write_hwi (ob, info->estimated_self_stack_size);
  	  streamer_write_hwi (ob, info->self_size);
  	  streamer_write_hwi (ob, info->self_time);
--- 3210,3216 ----
  	  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);
  	  streamer_write_hwi (ob, info->self_time);
Index: ipa-prop.c
===================================================================
*** ipa-prop.c	(revision 190283)
--- ipa-prop.c	(working copy)
*************** static void
*** 3303,3316 ****
  ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
  {
    int node_ref;
!   lto_cgraph_encoder_t encoder;
    struct ipa_node_params *info = IPA_NODE_REF (node);
    int j;
    struct cgraph_edge *e;
    struct bitpack_d bp;
  
!   encoder = ob->decl_state->cgraph_node_encoder;
!   node_ref = lto_cgraph_encoder_encode (encoder, node);
    streamer_write_uhwi (ob, node_ref);
  
    bp = bitpack_create (ob->main_stream);
--- 3303,3316 ----
  ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
  {
    int node_ref;
!   lto_symtab_encoder_t encoder;
    struct ipa_node_params *info = IPA_NODE_REF (node);
    int j;
    struct cgraph_edge *e;
    struct bitpack_d bp;
  
!   encoder = ob->decl_state->symtab_node_encoder;
!   node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
    streamer_write_uhwi (ob, node_ref);
  
    bp = bitpack_create (ob->main_stream);
*************** ipa_prop_read_section (struct lto_file_d
*** 3454,3464 ****
      {
        unsigned int index;
        struct cgraph_node *node;
!       lto_cgraph_encoder_t encoder;
  
        index = streamer_read_uhwi (&ib_main);
!       encoder = file_data->cgraph_node_encoder;
!       node = lto_cgraph_encoder_deref (encoder, index);
        gcc_assert (node->analyzed);
        ipa_read_node_info (&ib_main, node, data_in);
      }
--- 3454,3464 ----
      {
        unsigned int index;
        struct cgraph_node *node;
!       lto_symtab_encoder_t encoder;
  
        index = streamer_read_uhwi (&ib_main);
!       encoder = file_data->symtab_node_encoder;
!       node = cgraph (lto_symtab_encoder_deref (encoder, index));
        gcc_assert (node->analyzed);
        ipa_read_node_info (&ib_main, node, data_in);
      }
Index: lto-streamer.h
===================================================================
*** lto-streamer.h	(revision 190283)
--- lto-streamer.h	(working copy)
*************** struct lto_stats_d
*** 423,471 ****
  };
  
  /* Encoder data structure used to stream callgraph nodes.  */
! struct lto_cgraph_encoder_d
  {
    /* Map nodes to reference number. */
    struct pointer_map_t *map;
  
    /* Map reference number to node. */
!   VEC(cgraph_node_ptr,heap) *nodes;
  
    /* Map of nodes where we want to output body.  */
    struct pointer_set_t *body;
- };
- 
- typedef struct lto_cgraph_encoder_d *lto_cgraph_encoder_t;
- 
- /* Return number of encoded nodes in ENCODER.  */
- 
- static inline int
- lto_cgraph_encoder_size (lto_cgraph_encoder_t encoder)
- {
-   return VEC_length (cgraph_node_ptr, encoder->nodes);
- }
- 
- 
- /* Encoder data structure used to stream callgraph nodes.  */
- struct lto_varpool_encoder_d
- {
-   /* Map nodes to reference number. */
-   struct pointer_map_t *map;
- 
-   /* Map reference number to node. */
-   VEC(varpool_node_ptr,heap) *nodes;
- 
    /* Map of nodes where we want to output initializer.  */
    struct pointer_set_t *initializer;
  };
! typedef struct lto_varpool_encoder_d *lto_varpool_encoder_t;
  
  /* Return number of encoded nodes in ENCODER.  */
  
  static inline int
! lto_varpool_encoder_size (lto_varpool_encoder_t encoder)
  {
!   return VEC_length (varpool_node_ptr, encoder->nodes);
  }
  
  /* Mapping from indices to trees.  */
--- 423,450 ----
  };
  
  /* Encoder data structure used to stream callgraph nodes.  */
! struct lto_symtab_encoder_d
  {
    /* Map nodes to reference number. */
    struct pointer_map_t *map;
  
    /* Map reference number to node. */
!   VEC(symtab_node,heap) *nodes;
  
    /* Map of nodes where we want to output body.  */
    struct pointer_set_t *body;
    /* Map of nodes where we want to output initializer.  */
    struct pointer_set_t *initializer;
  };
! 
! typedef struct lto_symtab_encoder_d *lto_symtab_encoder_t;
  
  /* Return number of encoded nodes in ENCODER.  */
  
  static inline int
! lto_symtab_encoder_size (lto_symtab_encoder_t encoder)
  {
!   return VEC_length (symtab_node, encoder->nodes);
  }
  
  /* Mapping from indices to trees.  */
*************** struct lto_out_decl_state
*** 520,529 ****
    struct lto_tree_ref_encoder streams[LTO_N_DECL_STREAMS];
  
    /* Encoder for cgraph nodes.  */
!   lto_cgraph_encoder_t cgraph_node_encoder;
! 
!   /* Encoder for varpool nodes.  */
!   lto_varpool_encoder_t varpool_node_encoder;
  
    /* If this out-decl state belongs to a function, fn_decl points to that
       function.  Otherwise, it is NULL. */
--- 499,505 ----
    struct lto_tree_ref_encoder streams[LTO_N_DECL_STREAMS];
  
    /* Encoder for cgraph nodes.  */
!   lto_symtab_encoder_t symtab_node_encoder;
  
    /* If this out-decl state belongs to a function, fn_decl points to that
       function.  Otherwise, it is NULL. */
*************** struct GTY(()) lto_file_decl_data
*** 549,558 ****
    struct lto_in_decl_state *global_decl_state;
  
    /* Table of cgraph nodes present in this file.  */
!   lto_cgraph_encoder_t GTY((skip)) cgraph_node_encoder;
! 
!   /* Table of varpool nodes present in this file.  */
!   lto_varpool_encoder_t GTY((skip)) varpool_node_encoder;
  
    /* Hash table maps lto-related section names to location in file.  */
    htab_t GTY((param_is (struct lto_in_decl_state))) function_decl_states;
--- 525,531 ----
    struct lto_in_decl_state *global_decl_state;
  
    /* Table of cgraph nodes present in this file.  */
!   lto_symtab_encoder_t GTY((skip)) symtab_node_encoder;
  
    /* Hash table maps lto-related section names to location in file.  */
    htab_t GTY((param_is (struct lto_in_decl_state))) function_decl_states;
*************** void lto_output_location (struct output_
*** 837,859 ****
  
  
  /* In lto-cgraph.c  */
! struct cgraph_node *lto_cgraph_encoder_deref (lto_cgraph_encoder_t, int);
! int lto_cgraph_encoder_lookup (lto_cgraph_encoder_t, struct cgraph_node *);
! lto_cgraph_encoder_t lto_cgraph_encoder_new (void);
! int lto_cgraph_encoder_encode (lto_cgraph_encoder_t, struct cgraph_node *);
! void lto_cgraph_encoder_delete (lto_cgraph_encoder_t);
! bool lto_cgraph_encoder_encode_body_p (lto_cgraph_encoder_t,
  				       struct cgraph_node *);
  
! bool lto_varpool_encoder_encode_body_p (lto_varpool_encoder_t,
! 				        struct varpool_node *);
! struct varpool_node *lto_varpool_encoder_deref (lto_varpool_encoder_t, int);
! int lto_varpool_encoder_lookup (lto_varpool_encoder_t, struct varpool_node *);
! lto_varpool_encoder_t lto_varpool_encoder_new (void);
! int lto_varpool_encoder_encode (lto_varpool_encoder_t, struct varpool_node *);
! void lto_varpool_encoder_delete (lto_varpool_encoder_t);
! bool lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t,
! 					       struct varpool_node *);
  void output_cgraph (cgraph_node_set, varpool_node_set);
  void input_cgraph (void);
  bool referenced_from_other_partition_p (struct ipa_ref_list *,
--- 810,825 ----
  
  
  /* In lto-cgraph.c  */
! symtab_node lto_symtab_encoder_deref (lto_symtab_encoder_t, int);
! int lto_symtab_encoder_lookup (lto_symtab_encoder_t, symtab_node);
! lto_symtab_encoder_t lto_symtab_encoder_new (void);
! int lto_symtab_encoder_encode (lto_symtab_encoder_t, symtab_node);
! void lto_symtab_encoder_delete (lto_symtab_encoder_t);
! bool lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t,
  				       struct cgraph_node *);
  
! bool lto_symtab_encoder_encode_initializer_p (lto_symtab_encoder_t,
! 					      struct varpool_node *);
  void output_cgraph (cgraph_node_set, varpool_node_set);
  void input_cgraph (void);
  bool referenced_from_other_partition_p (struct ipa_ref_list *,



More information about the Gcc-patches mailing list