On Fri, Sep 30, 2011 at 1:43 PM, Jan Beulich <jbeul...@suse.com> wrote:
> Split out LTO's writing of top level asm nodes in preparation of extending
> what needs to be written out when top level asm-s get enhanced to accept a
> limited set of input operands.

Ok with ...

> gcc/
> 2011-09-30  Jan Beulich  <jbeul...@suse.com>
>
>        * lto-cgraph.c (output_cgraph): Remove processing of 
> 'cgraph_asm_nodes',
>        call lto_output_toplevel_asms() instead.
>        (input_cgraph_1): Remove loop calling cgraph_add_asm_node(), call
>        lto_input_toplevel_asms() instead.
>        * lto-section-in.c (lto_section_name): Add "asm" entry.
>        * lto-streamer-in.c (lto_input_toplevel_asms): New.
>        * lto-streamer-out.c (lto_output_toplevel_asms): New.
>        * lto-streamer.h (LTO_minor_version): Bump.
>        (enum lto_section_type): Add LTO_section_asm.
>        (struct lto_asm_header): New.
>        (lto_input_toplevel_asms, lto_output_toplevel_asms): Declare.
>        * tree-streamer.h (streamer_write_string_cst): Declare.
>        * tree-streamer-out.c (write_string_cst): Rename to
>        streamer_write_string_cst and make global.
>        (streamer_write_tree_header): Adjust call to renamed function.
>
> --- 2011-09-29.orig/gcc/lto-cgraph.c    2011-09-28 10:56:01.000000000 +0200
> +++ 2011-09-29/gcc/lto-cgraph.c 2011-09-29 15:07:23.000000000 +0200
> @@ -817,7 +817,6 @@ output_cgraph (cgraph_node_set set, varp
>   int i, n_nodes;
>   lto_cgraph_encoder_t encoder;
>   lto_varpool_encoder_t varpool_encoder;
> -  struct cgraph_asm_node *can;
>   static bool asm_nodes_output = false;
>
>   if (flag_wpa)
> @@ -854,6 +853,8 @@ output_cgraph (cgraph_node_set set, varp
>
>   streamer_write_uhwi_stream (ob->main_stream, 0);
>
> +  lto_destroy_simple_output_block (ob);
> +
>   /* Emit toplevel asms.
>      When doing WPA we must output every asm just once.  Since we do not 
> partition asm
>      nodes at all, output them to first output.  This is kind of hack, but 
> should work
> @@ -861,19 +862,9 @@ output_cgraph (cgraph_node_set set, varp
>   if (!asm_nodes_output)
>     {
>       asm_nodes_output = true;
> -      for (can = cgraph_asm_nodes; can; can = can->next)
> -       {
> -         int len = TREE_STRING_LENGTH (can->asm_str);
> -         streamer_write_uhwi_stream (ob->main_stream, len);
> -         for (i = 0; i < len; ++i)
> -           streamer_write_char_stream (ob->main_stream,
> -                                       TREE_STRING_POINTER 
> (can->asm_str)[i]);
> -       }
> +      lto_output_toplevel_asms ();
>     }
>
> -  streamer_write_uhwi_stream (ob->main_stream, 0);
> -
> -  lto_destroy_simple_output_block (ob);
>   output_varpool (set, vset);
>   output_refs (set, vset, encoder, varpool_encoder);
>  }
> @@ -1185,7 +1176,6 @@ input_cgraph_1 (struct lto_file_decl_dat
>   VEC(cgraph_node_ptr, heap) *nodes = NULL;
>   struct cgraph_node *node;
>   unsigned i;
> -  unsigned HOST_WIDE_INT len;
>
>   tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
>   while (tag)
> @@ -1206,18 +1196,8 @@ input_cgraph_1 (struct lto_file_decl_dat
>       tag = streamer_read_enum (ib, LTO_cgraph_tags, LTO_cgraph_last_tag);
>     }
>
> -  /* Input toplevel asms.  */
> -  len = streamer_read_uhwi (ib);
> -  while (len)
> -    {
> -      char *str = (char *)xmalloc (len + 1);
> -      for (i = 0; i < len; ++i)
> -       str[i] = streamer_read_uchar (ib);
> -      cgraph_add_asm_node (build_string (len, str));
> -      free (str);
> +  lto_input_toplevel_asms (file_data);
>
> -      len = streamer_read_uhwi (ib);
> -    }
>   /* 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)
> --- 2011-09-29.orig/gcc/lto-section-in.c        2011-09-28 10:56:01.000000000 
> +0200
> +++ 2011-09-29/gcc/lto-section-in.c     2011-09-29 15:07:23.000000000 +0200
> @@ -53,6 +53,7 @@ const char *lto_section_name[LTO_N_SECTI
>   "cgraph",
>   "vars",
>   "refs",
> +  "asm",
>   "jmpfuncs",
>   "pureconst",
>   "reference",
> --- 2011-09-29.orig/gcc/lto-streamer-in.c       2011-09-28 10:56:01.000000000 
> +0200
> +++ 2011-09-29/gcc/lto-streamer-in.c    2011-09-29 15:07:23.000000000 +0200
> @@ -1141,6 +1141,47 @@ lto_input_tree (struct lto_input_block *
>  }
>
>
> +/* Input toplevel asms.  */
> +
> +void
> +lto_input_toplevel_asms (struct lto_file_decl_data *file_data)
> +{
> +  size_t len;
> +  const char *data = lto_get_section_data (file_data, LTO_section_asm,
> +                                          NULL, &len);
> +  const struct lto_asm_header *header = (const struct lto_asm_header *) data;
> +  int32_t string_offset;
> +  struct data_in *data_in;
> +  struct lto_input_block ib;
> +  tree str;
> +
> +  if (! data)
> +    return;
> +
> +  string_offset = sizeof (*header) + header->main_size;
> +
> +  LTO_INIT_INPUT_BLOCK (ib,
> +                       data + sizeof (*header),
> +                       0,
> +                       header->main_size);
> +
> +  data_in = lto_data_in_create (file_data, data + string_offset,
> +                               header->string_size, NULL);
> +
> +  /* Make sure the file was generated by the exact same compiler.  */
> +  lto_check_version (header->lto_header.major_version,
> +                    header->lto_header.minor_version);
> +
> +  while ((str = streamer_read_string_cst (data_in, &ib)))
> +    cgraph_add_asm_node (str);
> +
> +  clear_line_info (data_in);
> +  lto_data_in_delete (data_in);
> +
> +  lto_free_section_data (file_data, LTO_section_asm, NULL, data, len);
> +}
> +
> +
>  /* Initialization for the LTO reader.  */
>
>  void
> --- 2011-09-29.orig/gcc/lto-streamer-out.c      2011-09-28 10:56:01.000000000 
> +0200
> +++ 2011-09-29/gcc/lto-streamer-out.c   2011-09-29 15:07:23.000000000 +0200
> @@ -934,6 +934,61 @@ output_unreferenced_globals (cgraph_node
>  }
>
>
> +/* Emit toplevel asms.  */
> +
> +void
> +lto_output_toplevel_asms (void)
> +{
> +  struct output_block *ob;
> +  struct cgraph_asm_node *can;
> +  char *section_name;
> +  struct lto_output_stream *header_stream;
> +  struct lto_asm_header header;
> +
> +  if (! cgraph_asm_nodes)
> +    return;
> +
> +  ob = create_output_block (LTO_section_asm);
> +
> +  /* Make string 0 be a NULL string.  */
> +  streamer_write_char_stream (ob->string_stream, 0);
> +
> +  for (can = cgraph_asm_nodes; can; can = can->next)
> +    streamer_write_string_cst (ob, ob->main_stream, can->asm_str);
> +
> +  streamer_write_string_cst (ob, ob->main_stream, NULL_TREE);
> +
> +  section_name = lto_get_section_name (LTO_section_asm, NULL, NULL);
> +  lto_begin_section (section_name, !flag_wpa);
> +  free (section_name);
> +
> +  /* The entire header stream is computed here.  */
> +  memset (&header, 0, sizeof (header));
> +
> +  /* Write the header.  */
> +  header.lto_header.major_version = LTO_major_version;
> +  header.lto_header.minor_version = LTO_minor_version;
> +  header.lto_header.section_type = LTO_section_asm;
> +
> +  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);
> +
> +  /* Put all of the gimple and the string table out the asm file as a
> +     block of text.  */
> +  lto_write_stream (ob->main_stream);
> +  lto_write_stream (ob->string_stream);
> +
> +  lto_end_section ();
> +
> +  destroy_output_block (ob);
> +}
> +
> +
>  /* Copy the function body of NODE without deserializing. */
>
>  static void
> --- 2011-09-29.orig/gcc/lto-streamer.h  2011-09-28 10:56:01.000000000 +0200
> +++ 2011-09-29/gcc/lto-streamer.h       2011-09-29 15:07:23.000000000 +0200
> @@ -142,7 +142,7 @@ along with GCC; see the file COPYING3.
>  #define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
>
>  #define LTO_major_version 2
> -#define LTO_minor_version 0
> +#define LTO_minor_version 1
>
>  typedef unsigned char  lto_decl_flags_t;
>
> @@ -238,6 +238,7 @@ enum lto_section_type
>   LTO_section_cgraph,
>   LTO_section_varpool,
>   LTO_section_refs,
> +  LTO_section_asm,
>   LTO_section_jump_functions,
>   LTO_section_ipa_pure_const,
>   LTO_section_ipa_reference,
> @@ -387,6 +388,23 @@ struct lto_decl_header
>  };
>
>
> +/* Structure describing top level asm()s.  */
> +struct lto_asm_header
> +{
> +  /* The header for all types of sections. */
> +  struct lto_header lto_header;
> +
> +  /* Size compressed or 0 if not compressed.  */
> +  int32_t compressed_size;
> +
> +  /* Size of region for expressions, decls, types, etc. */
> +  int32_t main_size;
> +
> +  /* Size of the string table.  */
> +  int32_t string_size;
> +};
> +
> +
>  /* Statistics gathered during LTO, WPA and LTRANS.  */
>  struct lto_stats_d
>  {
> @@ -789,6 +807,7 @@ extern void lto_input_function_body (str
>                                     const char *);
>  extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
>                                              const char *);
> +extern void lto_input_toplevel_asms (struct lto_file_decl_data *);
>  extern struct data_in *lto_data_in_create (struct lto_file_decl_data *,
>                                    const char *, unsigned,
>                                    VEC(ld_plugin_symbol_resolution_t,heap) *);
> @@ -807,6 +826,7 @@ extern void lto_register_decl_definition
>  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);
> +extern void lto_output_toplevel_asms (void);
>  extern void produce_asm (struct output_block *ob, tree fn);
>  void lto_output_decl_state_streams (struct output_block *,
>                                    struct lto_out_decl_state *);
> --- 2011-09-29.orig/gcc/tree-streamer.h 2011-09-28 10:56:01.000000000 +0200
> +++ 2011-09-29/gcc/tree-streamer.h      2011-09-29 15:07:23.000000000 +0200
> @@ -75,6 +75,8 @@ tree streamer_read_integer_cst (struct l
>  struct bitpack_d streamer_read_tree_bitfields (struct lto_input_block *, 
> tree);
>
>  /* In tree-streamer-out.c.  */
> +void streamer_write_string_cst (struct output_block *,
> +                               struct lto_output_stream *, tree);
>  void streamer_write_chain (struct output_block *, tree, bool);
>  void streamer_write_tree_header (struct output_block *, tree);
>  void streamer_pack_tree_bitfields (struct bitpack_d *, tree);
> --- 2011-09-29.orig/gcc/tree-streamer-out.c     2011-09-28 10:56:01.000000000 
> +0200
> +++ 2011-09-29/gcc/tree-streamer-out.c  2011-09-29 15:07:23.000000000 +0200
> @@ -31,11 +31,16 @@ along with GCC; see the file COPYING3.
>  /* Output the STRING constant to the string
>    table in OB.  Then put the index onto the INDEX_STREAM.  */
>
> -static void
> -write_string_cst (struct output_block *ob,
> -                  struct lto_output_stream *index_stream,
> -                  tree string)
> +void
> +streamer_write_string_cst (struct output_block *ob,
> +                          struct lto_output_stream *index_stream,
> +                          tree string)
>  {
> +  if (! string)
> +    {
> +      streamer_write_char_stream (index_stream, 0);
> +      return;
> +    }
>   streamer_write_string_with_length (ob, index_stream,
>                                     TREE_STRING_POINTER (string),
>                                     TREE_STRING_LENGTH (string),

Simply do

>   streamer_write_string_with_length (ob, index_stream,
>                                     string ? TREE_STRING_POINTER (string) : 
> NULL,
>                                     string ? TREE_STRING_LENGTH (string) : 0,

instead (that is, not expose that this would do
streamer_write_char_stream (index_stream, 0); here).

Thanks,
Richard.

> @@ -866,7 +871,7 @@ streamer_write_tree_header (struct outpu
>   /* The text in strings and identifiers are completely emitted in
>      the header.  */
>   if (CODE_CONTAINS_STRUCT (code, TS_STRING))
> -    write_string_cst (ob, ob->main_stream, expr);
> +    streamer_write_string_cst (ob, ob->main_stream, expr);
>   else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
>     write_identifier (ob, ob->main_stream, expr);
>   else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
>
>
>

Reply via email to