Cleanup global decl stream reference streaming, part 1

Message ID 20200601134426.GA44738@kam.mff.cuni.cz
State New
Headers show
Series
  • Cleanup global decl stream reference streaming, part 1
Related show

Commit Message

Jan Hubicka June 1, 2020, 1:44 p.m.
Hi,
this patch further simplifies way we reffer to global stream.  Every function
section has vector of references to global trees which are populated during
streaming.  This vector is for some reason divided into field_decls, fn_decls,
type_decls, types, namespace_decls, labels_decls and var_decls which contains
also other things.

There is no benefit for this split except perhaps for making the indexes
bit smaller and possibly better encodable by ulebs.  This however does not
pay back and makes things unnecesarily complex.
We may want to re-add multiple tables if we start streaming something else than
trees into the global stream, but that would not work with current
infrastructure anyway.

The patch drops different streams and I checked that it results in reduction of
global stream and apparently very small increase in function streams but it may
be just because I updated tree in between the tests. This will be fixed by
incremental patch.

[WPA] Compression: 86220483 input bytes, 217762146 uncompressed bytes (ratio: 2.525643)
[WPA] Compression: 111735464 input bytes, 297410918 uncompressed bytes (ratio: 2.661741)
[WPA] Size of mmap'd section decls: 86220483 bytes
[WPA] Size of mmap'd section function_body: 14353447 bytes

to:

[WPA] Compression: 85754594 input bytes, 216006049 uncompressed bytes (ratio: 2.518886)
[WPA] Compression: 111370381 input bytes, 295746052 uncompressed bytes (ratio: 2.655518)
[WPA] Size of mmap'd section decls: 85754594 bytes
[WPA] Size of mmap'd section function_body: 14447946 bytes

The patch also removes some of ugly macro generators of accessors functions and
makes it easier to further optimize the way we stream references to trees which
I plan to do incrementally.

I also made the API for streaming referneces symmetric.  I.e. you
stream out by
  lto_output_var_decl_ref
and stream in by
  lto_input_var_decl_ref

instead streaming out by
  lto_output_var_decl_index
and streaming in by
  decl_index = streamer_read_uhwi (ib);
  lto_file_decl_data_get_fn_decl (file_data, decl_index);

lto-bootstrapped/regtested x86_64-linux, will commit it shortly.

gcc/ChangeLog:

2020-06-01  Jan Hubicka  <hubicka@ucw.cz>

	* ipa-reference.c (stream_out_bitmap): Use lto_output_var_decl_ref.
	(ipa_reference_read_optimization_summary): Use lto_intput_var_decl_ref.
	* lto-cgraph.c (lto_output_node): Likewise.
	(lto_output_varpool_node): Likewise.
	(output_offload_tables): Likewise.
	(input_node): Likewise.
	(input_varpool_node): Likewise.
	(input_offload_tables): Likewise.
	* lto-streamer-in.c (lto_input_tree_ref): Declare.
	(lto_input_var_decl_ref): Declare.
	(lto_input_fn_decl_ref): Declare.
	* lto-streamer-out.c (lto_indexable_tree_ref): Use only one decl stream.
	(lto_output_var_decl_index): Rename to ..
	(lto_output_var_decl_ref): ... this.
	(lto_output_fn_decl_index): Rename to ...
	(lto_output_fn_decl_ref): ... this.
	* lto-streamer.h (enum lto_decl_stream_e_t): Remove per-type streams.
	(DEFINE_DECL_STREAM_FUNCS): Remove.
	(lto_output_var_decl_index): Remove.
	(lto_output_fn_decl_index): Remove.
	(lto_output_var_decl_ref): Declare.
	(lto_output_fn_decl_ref): Declare.
	(lto_input_var_decl_ref): Declare.
	(lto_input_fn_decl_ref): Declare.

Patch

diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 6ab0505c3fd..fc7e4312420 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -249,38 +249,12 @@  enum lto_section_type
 /* Indices to the various function, type and symbol streams. */
 enum lto_decl_stream_e_t
 {
-  LTO_DECL_STREAM_TYPE = 0,		/* Must be first. */
-  LTO_DECL_STREAM_FIELD_DECL,
-  LTO_DECL_STREAM_FN_DECL,
-  LTO_DECL_STREAM_VAR_DECL,
-  LTO_DECL_STREAM_TYPE_DECL,
-  LTO_DECL_STREAM_NAMESPACE_DECL,
-  LTO_DECL_STREAM_LABEL_DECL,
+  LTO_DECL_STREAM = 0,		/* Must be first.  */
   LTO_N_DECL_STREAMS
 };
 
 typedef enum ld_plugin_symbol_resolution ld_plugin_symbol_resolution_t;
 
-
-/* Macro to define convenience functions for type and decl streams
-   in lto_file_decl_data.  */
-#define DEFINE_DECL_STREAM_FUNCS(UPPER_NAME, name) \
-static inline tree \
-lto_file_decl_data_get_ ## name (struct lto_file_decl_data *data, \
-				 unsigned int idx) \
-{ \
-  struct lto_in_decl_state *state = data->current_decl_state; \
-   return (*state->streams[LTO_DECL_STREAM_## UPPER_NAME])[idx]; \
-} \
-\
-static inline unsigned int \
-lto_file_decl_data_num_ ## name ## s (struct lto_file_decl_data *data) \
-{ \
-  struct lto_in_decl_state *state = data->current_decl_state; \
-  return vec_safe_length (state->streams[LTO_DECL_STREAM_## UPPER_NAME]); \
-}
-
-
 /* Return a char pointer to the start of a data stream for an lto pass
    or function.  The first parameter is the file data that contains
    the information.  The second parameter is the type of information
@@ -908,10 +882,12 @@  extern struct output_block *create_output_block (enum lto_section_type);
 extern void destroy_output_block (struct output_block *);
 extern void lto_output_tree (struct output_block *, tree, bool, bool);
 extern void stream_write_tree_ref (struct output_block *, tree);
-extern void lto_output_var_decl_index (struct lto_out_decl_state *,
-				       struct lto_output_stream *, tree);
-extern void lto_output_fn_decl_index (struct lto_out_decl_state *,
-				      struct lto_output_stream *, tree);
+extern void lto_output_var_decl_ref (struct lto_out_decl_state *,
+				     struct lto_output_stream *, tree);
+extern void lto_output_fn_decl_ref (struct lto_out_decl_state *,
+				    struct lto_output_stream *, tree);
+extern tree lto_input_var_decl_ref (lto_input_block *, lto_file_decl_data *);
+extern tree lto_input_fn_decl_ref (lto_input_block *, lto_file_decl_data *);
 extern void lto_output_toplevel_asms (void);
 extern void produce_asm (struct output_block *ob, tree fn);
 extern void lto_output ();
@@ -1251,14 +1227,6 @@  lsei_start_variable_in_partition (lto_symtab_encoder_t encoder)
   return lsei;
 }
 
-DEFINE_DECL_STREAM_FUNCS (TYPE, type)
-DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl)
-DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl)
-DEFINE_DECL_STREAM_FUNCS (VAR_DECL, var_decl)
-DEFINE_DECL_STREAM_FUNCS (TYPE_DECL, type_decl)
-DEFINE_DECL_STREAM_FUNCS (NAMESPACE_DECL, namespace_decl)
-DEFINE_DECL_STREAM_FUNCS (LABEL_DECL, label_decl)
-
 /* Entry for the delayed registering of decl -> DIE references.  */
 struct dref_entry {
     tree decl;
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index c08d84d93e4..c9bc1485a0c 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1039,7 +1039,7 @@  stream_out_bitmap (struct lto_simple_output_block *ob,
   EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
     {
       tree decl = (*reference_vars_to_consider) [index];
-      lto_output_var_decl_index (ob->decl_state, ob->main_stream, decl);
+      lto_output_var_decl_ref (ob->decl_state, ob->main_stream, decl);
     }
 }
 
@@ -1158,9 +1158,7 @@  ipa_reference_read_optimization_summary (void)
 	    fprintf (dump_file, "all module statics:");
 	  for (i = 0; i < (unsigned int)b_count; i++)
 	    {
-	      unsigned int var_index = streamer_read_uhwi (ib);
-	      tree v_decl = lto_file_decl_data_get_var_decl (file_data,
-							     var_index);
+	      tree v_decl = lto_input_var_decl_ref (ib, file_data);
 	      bool existed;
 	      bitmap_set_bit (all_module_statics,
 			      ipa_reference_var_get_or_insert_uid
@@ -1206,9 +1204,7 @@  ipa_reference_read_optimization_summary (void)
 		    (&optimization_summary_obstack);
 		  for (j = 0; j < (unsigned int)v_count; j++)
 		    {
-		      unsigned int var_index = streamer_read_uhwi (ib);
-		      tree v_decl = lto_file_decl_data_get_var_decl (file_data,
-								     var_index);
+		      tree v_decl = lto_input_var_decl_ref (ib, file_data);
 		      bitmap_set_bit (info->statics_read,
 				      ipa_reference_var_uid (v_decl));
 		      if (dump_file)
@@ -1235,9 +1231,7 @@  ipa_reference_read_optimization_summary (void)
 		    (&optimization_summary_obstack);
 		  for (j = 0; j < (unsigned int)v_count; j++)
 		    {
-		      unsigned int var_index = streamer_read_uhwi (ib);
-		      tree v_decl = lto_file_decl_data_get_var_decl (file_data,
-								     var_index);
+		      tree v_decl = lto_input_var_decl_ref (ib, file_data);
 		      bitmap_set_bit (info->statics_written,
 				      ipa_reference_var_uid (v_decl));
 		      if (dump_file)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 17b6cfd83a7..a671c671fa7 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -451,7 +451,7 @@  lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
     streamer_write_hwi_stream (ob->main_stream, ref);
 
 
-  lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl);
+  lto_output_fn_decl_ref (ob->decl_state, ob->main_stream, node->decl);
   node->count.stream_out (ob->main_stream);
   streamer_write_hwi_stream (ob->main_stream, node->count_materialization_scale);
 
@@ -591,7 +591,7 @@  lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
   streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
 		       LTO_symtab_variable);
   streamer_write_hwi_stream (ob->main_stream, node->order);
-  lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl);
+  lto_output_var_decl_ref (ob->decl_state, ob->main_stream, node->decl);
   bp = bitpack_create (ob->main_stream);
   bp_pack_value (&bp, node->externally_visible, 1);
   bp_pack_value (&bp, node->no_reorder, 1);
@@ -1071,16 +1071,16 @@  output_offload_tables (void)
     {
       streamer_write_enum (ob->main_stream, LTO_symtab_tags,
 			   LTO_symtab_last_tag, LTO_symtab_unavail_node);
-      lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
-				(*offload_funcs)[i]);
+      lto_output_fn_decl_ref (ob->decl_state, ob->main_stream,
+			      (*offload_funcs)[i]);
     }
 
   for (unsigned i = 0; i < vec_safe_length (offload_vars); i++)
     {
       streamer_write_enum (ob->main_stream, LTO_symtab_tags,
 			   LTO_symtab_last_tag, LTO_symtab_variable);
-      lto_output_var_decl_index (ob->decl_state, ob->main_stream,
-				 (*offload_vars)[i]);
+      lto_output_var_decl_ref (ob->decl_state, ob->main_stream,
+			       (*offload_vars)[i]);
     }
 
   streamer_write_uhwi_stream (ob->main_stream, 0);
@@ -1219,7 +1219,6 @@  input_node (struct lto_file_decl_data *file_data,
   tree fn_decl;
   struct cgraph_node *node;
   struct bitpack_d bp;
-  unsigned decl_index;
   int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
   int clone_ref;
   int order;
@@ -1229,8 +1228,7 @@  input_node (struct lto_file_decl_data *file_data,
   order = streamer_read_hwi (ib) + file_data->order_base;
   clone_ref = streamer_read_hwi (ib);
 
-  decl_index = streamer_read_uhwi (ib);
-  fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
+  fn_decl = lto_input_fn_decl_ref (ib, file_data);
 
   if (clone_ref != LCC_NOT_FOUND)
     {
@@ -1339,7 +1337,6 @@  static varpool_node *
 input_varpool_node (struct lto_file_decl_data *file_data,
 		    class lto_input_block *ib)
 {
-  int decl_index;
   tree var_decl;
   varpool_node *node;
   struct bitpack_d bp;
@@ -1349,8 +1346,7 @@  input_varpool_node (struct lto_file_decl_data *file_data,
   const char *section;
 
   order = streamer_read_hwi (ib) + file_data->order_base;
-  decl_index = streamer_read_uhwi (ib);
-  var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
+  var_decl = lto_input_var_decl_ref (ib, file_data);
 
   /* Declaration of functions can be already merged with a declaration
      from other input file.  We keep cgraph unmerged until after streaming
@@ -1781,9 +1777,8 @@  input_offload_tables (bool do_force_output)
 	{
 	  if (tag == LTO_symtab_unavail_node)
 	    {
-	      int decl_index = streamer_read_uhwi (ib);
 	      tree fn_decl
-		= lto_file_decl_data_get_fn_decl (file_data, decl_index);
+		= lto_input_fn_decl_ref (ib, file_data);
 	      vec_safe_push (offload_funcs, fn_decl);
 
 	      /* Prevent IPA from removing fn_decl as unreachable, since there
@@ -1794,9 +1789,8 @@  input_offload_tables (bool do_force_output)
 	    }
 	  else if (tag == LTO_symtab_variable)
 	    {
-	      int decl_index = streamer_read_uhwi (ib);
 	      tree var_decl
-		= lto_file_decl_data_get_var_decl (file_data, decl_index);
+		= lto_input_var_decl_ref (ib, file_data);
 	      vec_safe_push (offload_vars, var_decl);
 
 	      /* Prevent IPA from removing var_decl as unused, since there
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 805a51c0fb8..d77b4f5e9ff 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -320,36 +320,16 @@  lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in,
 
   switch (tag)
     {
-    case LTO_type_ref:
-      ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_type (data_in->file_data, ix_u);
-      break;
-
     case LTO_ssa_name_ref:
       ix_u = streamer_read_uhwi (ib);
       result = (*SSANAMES (fn))[ix_u];
       break;
 
+    case LTO_type_ref:
     case LTO_field_decl_ref:
-      ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_field_decl (data_in->file_data, ix_u);
-      break;
-
     case LTO_function_decl_ref:
-      ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_fn_decl (data_in->file_data, ix_u);
-      break;
-
     case LTO_type_decl_ref:
-      ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_type_decl (data_in->file_data, ix_u);
-      break;
-
     case LTO_namespace_decl_ref:
-      ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_namespace_decl (data_in->file_data, ix_u);
-      break;
-
     case LTO_global_decl_ref:
     case LTO_result_decl_ref:
     case LTO_const_decl_ref:
@@ -358,7 +338,8 @@  lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in,
     case LTO_translation_unit_decl_ref:
     case LTO_namelist_decl_ref:
       ix_u = streamer_read_uhwi (ib);
-      result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
+      result = (*data_in->file_data->current_decl_state
+		->streams[LTO_DECL_STREAM])[ix_u];
       break;
 
     default:
@@ -370,6 +351,30 @@  lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in,
   return result;
 }
 
+/* Read VAR_DECL reference to DATA from IB.  */
+
+tree
+lto_input_var_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data)
+{
+  unsigned int ix_u = streamer_read_uhwi (ib);
+  tree result = (*file_data->current_decl_state
+		 ->streams[LTO_DECL_STREAM])[ix_u];
+  gcc_assert (TREE_CODE (result) == VAR_DECL);
+  return result;
+}
+
+/* Read VAR_DECL reference to DATA from IB.  */
+
+tree
+lto_input_fn_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data)
+{
+  unsigned int ix_u = streamer_read_uhwi (ib);
+  tree result = (*file_data->current_decl_state
+		 ->streams[LTO_DECL_STREAM])[ix_u];
+  gcc_assert (TREE_CODE (result) == FUNCTION_DECL);
+  return result;
+}
+
 
 /* Read and return a double-linked list of catch handlers from input
    block IB, using descriptors in DATA_IN.  */
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 1910ee2a5ea..a44ed0037ee 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -260,7 +260,7 @@  lto_indexable_tree_ref (struct output_block *ob, tree expr,
   if (TYPE_P (expr))
     {
       *tag = LTO_type_ref;
-      encoder = LTO_DECL_STREAM_TYPE;
+      encoder = LTO_DECL_STREAM;
     }
   else
     {
@@ -275,12 +275,12 @@  lto_indexable_tree_ref (struct output_block *ob, tree expr,
 
 	case FIELD_DECL:
 	  *tag = LTO_field_decl_ref;
-	  encoder = LTO_DECL_STREAM_FIELD_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case FUNCTION_DECL:
 	  *tag = LTO_function_decl_ref;
-	  encoder = LTO_DECL_STREAM_FN_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case VAR_DECL:
@@ -290,37 +290,37 @@  lto_indexable_tree_ref (struct output_block *ob, tree expr,
 	  /* FALLTHRU */
 	case PARM_DECL:
 	  *tag = LTO_global_decl_ref;
-	  encoder = LTO_DECL_STREAM_VAR_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case CONST_DECL:
 	  *tag = LTO_const_decl_ref;
-	  encoder = LTO_DECL_STREAM_VAR_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case TYPE_DECL:
 	  *tag = LTO_type_decl_ref;
-	  encoder = LTO_DECL_STREAM_TYPE_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case NAMESPACE_DECL:
 	  *tag = LTO_namespace_decl_ref;
-	  encoder = LTO_DECL_STREAM_NAMESPACE_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case LABEL_DECL:
 	  *tag = LTO_label_decl_ref;
-	  encoder = LTO_DECL_STREAM_VAR_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case RESULT_DECL:
 	  *tag = LTO_result_decl_ref;
-	  encoder = LTO_DECL_STREAM_VAR_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	case TRANSLATION_UNIT_DECL:
 	  *tag = LTO_translation_unit_decl_ref;
-	  encoder = LTO_DECL_STREAM_VAR_DECL;
+	  encoder = LTO_DECL_STREAM;
 	  break;
 
 	default:
@@ -336,12 +336,12 @@  lto_indexable_tree_ref (struct output_block *ob, tree expr,
 /* Output a static or extern var DECL to OBS.  */
 
 void
-lto_output_var_decl_index (struct lto_out_decl_state *decl_state,
-			   struct lto_output_stream * obs, tree decl)
+lto_output_var_decl_ref (struct lto_out_decl_state *decl_state,
+			 struct lto_output_stream * obs, tree decl)
 {
   gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
   streamer_write_uhwi_stream
-     (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM_VAR_DECL],
+     (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM],
 			  decl));
 }
 
@@ -349,12 +349,12 @@  lto_output_var_decl_index (struct lto_out_decl_state *decl_state,
 /* Output a static or extern var DECL to OBS.  */
 
 void
-lto_output_fn_decl_index (struct lto_out_decl_state *decl_state,
-			  struct lto_output_stream * obs, tree decl)
+lto_output_fn_decl_ref (struct lto_out_decl_state *decl_state,
+			struct lto_output_stream * obs, tree decl)
 {
   gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL);
   streamer_write_uhwi_stream
-     (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM_FN_DECL], decl));
+     (obs, lto_get_index (&decl_state->streams[LTO_DECL_STREAM], decl));
 }
 
 /* Return true if EXPR is a tree node that can be written to disk.  */