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)) > > >