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


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

[PATCH][LTO] Do not use the data streamer when we are not using it


The following patch avoids going though the data streamer when we
only end up outputting raw data via lto_output_data_stream.  The
patch adds a simple lto_write_data which writes to the current
section.  symtab producing may want to use an obstack similar to
lto-opts.c, but I didn't bother to adjust it.

Affected are for example writing the LTO headers.

This also avoids needless copying of the function body data
at WPA time.

(LTO) bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Richard.

2014-07-30  Richard Biener  <rguenther@suse.de>

	* lto-streamer.h (lto_write_data): New function.
	* langhooks.c (lhd_append_data): Do not free block.
	* lto-section-out.c (lto_write_data): New function writing
	raw data to the current section.
	(lto_write_stream): Adjust for langhook semantic change.
	(lto_destroy_simple_output_block): Write header directly.
	* lto-opts.c (lto_write_options): Write options directly.
	* lto-streamer-out.c (produce_asm): Write heaeder directly.
	(lto_output_toplevel_asms): Likewise.
	(copy_function_or_variable): Copy data directly.
	(write_global_references): Output index table directly.
	(lto_output_decl_state_refs): Likewise.
	(write_symbol): Write data directly.
	(produce_symtab): Adjust.
	(produce_asm_for_decls): Output header and refs directly.

	lto/
	* lto-object.c (lto_obj_append_data): Do not free block.

Index: gcc/lto-streamer.h
===================================================================
--- gcc/lto-streamer.h	(revision 213152)
+++ gcc/lto-streamer.h	(working copy)
@@ -777,6 +777,7 @@ extern void lto_value_range_error (const
 /* In lto-section-out.c  */
 extern void lto_begin_section (const char *, bool);
 extern void lto_end_section (void);
+extern void lto_write_data (const void *, unsigned int);
 extern void lto_write_stream (struct lto_output_stream *);
 extern void lto_output_data_stream (struct lto_output_stream *, const void *,
 				    size_t);
Index: gcc/lto-section-out.c
===================================================================
--- gcc/lto-section-out.c	(revision 213152)
+++ gcc/lto-section-out.c	(working copy)
@@ -98,6 +98,16 @@ lto_end_section (void)
   lang_hooks.lto.end_section ();
 }
 
+/* Write SIZE bytes starting at DATA to the assembler.  */
+
+void
+lto_write_data (const void *data, unsigned int size)
+{
+  if (compression_stream)
+    lto_compress_block (compression_stream, (const char *)data, size);
+  else
+    lang_hooks.lto.append_data ((const char *)data, size, NULL);
+}
 
 /* Write all of the chars in OBS to the assembler.  Recycle the blocks
    in obs as this is being done.  */
@@ -128,12 +138,10 @@ lto_write_stream (struct lto_output_stre
          blocks up output differently to the way it's blocked here.  So for
          now, we don't compress WPA output.  */
       if (compression_stream)
-	{
-	  lto_compress_block (compression_stream, base, num_chars);
-	  lang_hooks.lto.append_data (NULL, 0, block);
-	}
+	lto_compress_block (compression_stream, base, num_chars);
       else
 	lang_hooks.lto.append_data (base, num_chars, block);
+      free (block);
       block_size *= 2;
     }
 }
@@ -335,7 +343,6 @@ lto_destroy_simple_output_block (struct
 {
   char *section_name;
   struct lto_simple_header header;
-  struct lto_output_stream *header_stream;
 
   section_name = lto_get_section_name (ob->section_type, NULL, NULL);
   lto_begin_section (section_name, !flag_wpa);
@@ -346,15 +353,9 @@ lto_destroy_simple_output_block (struct
   memset (&header, 0, sizeof (struct lto_simple_header));
   header.lto_header.major_version = LTO_major_version;
   header.lto_header.minor_version = LTO_minor_version;
-
   header.compressed_size = 0;
-
   header.main_size = ob->main_stream->total_size;
-
-  header_stream = XCNEW (struct lto_output_stream);
-  lto_output_data_stream (header_stream, &header, sizeof header);
-  lto_write_stream (header_stream);
-  free (header_stream);
+  lto_write_data (&header, sizeof header);
 
   lto_write_stream (ob->main_stream);
 
Index: gcc/langhooks.c
===================================================================
--- gcc/langhooks.c	(revision 213152)
+++ gcc/langhooks.c	(working copy)
@@ -661,14 +661,13 @@ lhd_begin_section (const char *name)
 
 
 /* Write DATA of length LEN to the current LTO output section.  This default
-   implementation just calls assemble_string and frees BLOCK.  */
+   implementation just calls assemble_string.  */
 
 void
-lhd_append_data (const void *data, size_t len, void *block)
+lhd_append_data (const void *data, size_t len, void *)
 {
   if (data)
     assemble_string ((const char *)data, len);
-  free (block);
 }
 
 
Index: gcc/lto/lto-object.c
===================================================================
--- gcc/lto/lto-object.c	(revision 213152)
+++ gcc/lto/lto-object.c	(working copy)
@@ -354,7 +354,7 @@ lto_obj_begin_section (const char *name)
    DATA.  */
 
 void
-lto_obj_append_data (const void *data, size_t len, void *block)
+lto_obj_append_data (const void *data, size_t len, void *)
 {
   struct lto_simple_object *lo;
   const char *errmsg;
@@ -372,8 +372,6 @@ lto_obj_append_data (const void *data, s
       else
 	fatal_error ("%s: %s", errmsg, xstrerror (errno));
     }
-
-  free (block);
 }
 
 /* Stop writing to the current output section.  */
Index: gcc/lto-opts.c
===================================================================
--- gcc/lto-opts.c	(revision 213152)
+++ gcc/lto-opts.c	(working copy)
@@ -67,7 +67,6 @@ append_to_collect_gcc_options (struct ob
 void
 lto_write_options (void)
 {
-  struct lto_output_stream stream;
   char *section_name;
   struct obstack temporary_obstack;
   unsigned int i, j;
@@ -76,7 +75,6 @@ lto_write_options (void)
 
   section_name = lto_get_section_name (LTO_section_opts, NULL, NULL);
   lto_begin_section (section_name, false);
-  memset (&stream, 0, sizeof (stream));
 
   obstack_init (&temporary_obstack);
 
@@ -170,9 +168,7 @@ lto_write_options (void)
     }
   obstack_grow (&temporary_obstack, "\0", 1);
   args = XOBFINISH (&temporary_obstack, char *);
-  lto_output_data_stream (&stream, args, strlen (args) + 1);
-
-  lto_write_stream (&stream);
+  lto_write_data (args, strlen (args) + 1);
   lto_end_section ();
 
   obstack_free (&temporary_obstack, NULL);
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c	(revision 213152)
+++ gcc/lto-streamer-out.c	(working copy)
@@ -1872,7 +1872,6 @@ produce_asm (struct output_block *ob, tr
   enum lto_section_type section_type = ob->section_type;
   struct lto_function_header header;
   char *section_name;
-  struct lto_output_stream *header_stream;
 
   if (section_type == LTO_section_function_body)
     {
@@ -1898,11 +1897,7 @@ produce_asm (struct output_block *ob, tr
     header.cfg_size = ob->cfg_stream->total_size;
   header.main_size = ob->main_stream->total_size;
   header.string_size = ob->string_stream->total_size;
-
-  header_stream = XCNEW (struct lto_output_stream);
-  lto_output_data_stream (header_stream, &header, sizeof header);
-  lto_write_stream (header_stream);
-  free (header_stream);
+  lto_write_data (&header, sizeof header);
 
   /* Put all of the gimple and the string table out the asm file as a
      block of text.  */
@@ -2104,7 +2099,6 @@ lto_output_toplevel_asms (void)
   struct output_block *ob;
   struct asm_node *can;
   char *section_name;
-  struct lto_output_stream *header_stream;
   struct lto_asm_header header;
 
   if (! asm_nodes)
@@ -2136,11 +2130,7 @@ lto_output_toplevel_asms (void)
 
   header.main_size = ob->main_stream->total_size;
   header.string_size = ob->string_stream->total_size;
-
-  header_stream = XCNEW (struct lto_output_stream);
-  lto_output_data_stream (header_stream, &header, sizeof (header));
-  lto_write_stream (header_stream);
-  free (header_stream);
+  lto_write_data (&header, sizeof header);
 
   /* Put all of the gimple and the string table out the asm file as a
      block of text.  */
@@ -2160,7 +2150,6 @@ copy_function_or_variable (struct symtab
 {
   tree function = node->decl;
   struct lto_file_decl_data *file_data = node->lto_file_data;
-  struct lto_output_stream *output_stream = XCNEW (struct lto_output_stream);
   const char *data;
   size_t len;
   const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
@@ -2181,8 +2170,7 @@ copy_function_or_variable (struct symtab
   gcc_assert (data);
 
   /* Do a bit copy of the function body.  */
-  lto_output_data_stream (output_stream, data, len);
-  lto_write_stream (output_stream);
+  lto_write_data (data, len);
 
   /* Copy decls. */
   in_state =
@@ -2206,7 +2194,6 @@ copy_function_or_variable (struct symtab
 
   lto_free_section_data (file_data, LTO_section_function_body, name,
 			 data, len);
-  free (output_stream);
   lto_end_section ();
 }
 
@@ -2348,15 +2335,15 @@ write_global_stream (struct output_block
 
 static void
 write_global_references (struct output_block *ob,
-			 struct lto_output_stream *ref_stream,
  			 struct lto_tree_ref_encoder *encoder)
 {
   tree t;
   uint32_t index;
   const uint32_t size = lto_tree_ref_encoder_size (encoder);
 
-  /* Write size as 32-bit unsigned. */
-  lto_output_data_stream (ref_stream, &size, sizeof (int32_t));
+  /* Write size and slot indexes as 32-bit unsigned numbers. */
+  uint32_t *data = XNEWVEC (uint32_t, size + 1);
+  data[0] = size;
 
   for (index = 0; index < size; index++)
     {
@@ -2365,8 +2352,11 @@ write_global_references (struct output_b
       t = lto_tree_ref_encoder_get_tree (encoder, index);
       streamer_tree_cache_lookup (ob->writer_cache, t, &slot_num);
       gcc_assert (slot_num != (unsigned)-1);
-      lto_output_data_stream (ref_stream, &slot_num, sizeof slot_num);
+      data[index + 1] = slot_num;
     }
+
+  lto_write_data (data, sizeof (int32_t) * (size + 1));
+  free (data);
 }
 
 
@@ -2389,7 +2379,6 @@ lto_output_decl_state_streams (struct ou
 
 void
 lto_output_decl_state_refs (struct output_block *ob,
-			    struct lto_output_stream *out_stream,
 			    struct lto_out_decl_state *state)
 {
   unsigned i;
@@ -2401,10 +2390,10 @@ lto_output_decl_state_refs (struct outpu
   decl = (state->fn_decl) ? state->fn_decl : void_type_node;
   streamer_tree_cache_lookup (ob->writer_cache, decl, &ref);
   gcc_assert (ref != (unsigned)-1);
-  lto_output_data_stream (out_stream, &ref, sizeof (uint32_t));
+  lto_write_data (&ref, sizeof (uint32_t));
 
   for (i = 0;  i < LTO_N_DECL_STREAMS; i++)
-    write_global_references (ob, out_stream, &state->streams[i]);
+    write_global_references (ob, &state->streams[i]);
 }
 
 
@@ -2432,7 +2421,6 @@ lto_out_decl_state_written_size (struct
 
 static void
 write_symbol (struct streamer_tree_cache_d *cache,
-	      struct lto_output_stream *stream,
 	      tree t, struct pointer_set_t *seen, bool alias)
 {
   const char *name;
@@ -2531,14 +2519,14 @@ write_symbol (struct streamer_tree_cache
   else
     comdat = "";
 
-  lto_output_data_stream (stream, name, strlen (name) + 1);
-  lto_output_data_stream (stream, comdat, strlen (comdat) + 1);
+  lto_write_data (name, strlen (name) + 1);
+  lto_write_data (comdat, strlen (comdat) + 1);
   c = (unsigned char) kind;
-  lto_output_data_stream (stream, &c, 1);
+  lto_write_data (&c, 1);
   c = (unsigned char) visibility;
-  lto_output_data_stream (stream, &c, 1);
-  lto_output_data_stream (stream, &size, 8);
-  lto_output_data_stream (stream, &slot_num, 4);
+  lto_write_data (&c, 1);
+  lto_write_data (&size, 8);
+  lto_write_data (&slot_num, 4);
 }
 
 /* Return true if NODE should appear in the plugin symbol table.  */
@@ -2589,7 +2577,6 @@ produce_symtab (struct output_block *ob)
   struct streamer_tree_cache_d *cache = ob->writer_cache;
   char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
   struct pointer_set_t *seen;
-  struct lto_output_stream stream;
   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
   lto_symtab_encoder_iterator lsei;
 
@@ -2597,7 +2584,6 @@ produce_symtab (struct output_block *ob)
   free (section_name);
 
   seen = pointer_set_create ();
-  memset (&stream, 0, sizeof (stream));
 
   /* Write the symbol table.
      First write everything defined and then all declarations.
@@ -2609,7 +2595,7 @@ produce_symtab (struct output_block *ob)
 
       if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
 	continue;
-      write_symbol (cache, &stream, node->decl, seen, false);
+      write_symbol (cache, node->decl, seen, false);
     }
   for (lsei = lsei_start (encoder);
        !lsei_end_p (lsei); lsei_next (&lsei))
@@ -2618,10 +2604,9 @@ produce_symtab (struct output_block *ob)
 
       if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
 	continue;
-      write_symbol (cache, &stream, node->decl, seen, false);
+      write_symbol (cache, node->decl, seen, false);
     }
 
-  lto_write_stream (&stream);
   pointer_set_destroy (seen);
 
   lto_end_section ();
@@ -2642,7 +2627,6 @@ produce_asm_for_decls (void)
   struct lto_decl_header header;
   char *section_name;
   struct output_block *ob;
-  struct lto_output_stream *header_stream, *decl_state_stream;
   unsigned idx, num_fns;
   size_t decl_state_size;
   int32_t num_decl_states;
@@ -2701,26 +2685,18 @@ produce_asm_for_decls (void)
   header.main_size = ob->main_stream->total_size;
   header.string_size = ob->string_stream->total_size;
 
-  header_stream = XCNEW (struct lto_output_stream);
-  lto_output_data_stream (header_stream, &header, sizeof header);
-  lto_write_stream (header_stream);
-  free (header_stream);
+  lto_write_data (&header, sizeof header);
 
   /* Write the main out-decl state, followed by out-decl states of
      functions. */
-  decl_state_stream = XCNEW (struct lto_output_stream);
   num_decl_states = num_fns + 1;
-  lto_output_data_stream (decl_state_stream, &num_decl_states,
-			  sizeof (num_decl_states));
-  lto_output_decl_state_refs (ob, decl_state_stream, out_state);
+  lto_write_data (&num_decl_states, sizeof (num_decl_states));
+  lto_output_decl_state_refs (ob, out_state);
   for (idx = 0; idx < num_fns; idx++)
     {
-      fn_out_state =
-	lto_function_decl_states[idx];
-      lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
+      fn_out_state = lto_function_decl_states[idx];
+      lto_output_decl_state_refs (ob, fn_out_state);
     }
-  lto_write_stream (decl_state_stream);
-  free (decl_state_stream);
 
   lto_write_stream (ob->main_stream);
   lto_write_stream (ob->string_stream);


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