From ebad2eeed903f7c9cf6c55d37be8af8c84f1cf32 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 23 Oct 2019 20:22:40 +0200 Subject: [PATCH] lto-streamer-out.c (output_constructor): Push CTORS_OUT timevar. * lto-streamer-out.c (output_constructor): Push CTORS_OUT timevar. (cmp_symbol_files): New. (lto_output): Copy sections in file order. * lto-streamer.h (lto_file_decl_data): Add field order. * lto-common.c (lto_file_finalize): Add order attribute. (lto_create_files_from_ids): Pass order. (lto_file_read): UPdate call of lto_create_files_from_ids. From-SVN: r277346 --- gcc/ChangeLog | 7 +++ gcc/lto-streamer-out.c | 109 +++++++++++++++++++++++++---------------- gcc/lto-streamer.h | 3 ++ gcc/lto/ChangeLog | 6 +++ gcc/lto/lto-common.c | 11 +++-- 5 files changed, 91 insertions(+), 45 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4cd0fda8f1c..d68bc8a5524 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-10-23 Jan Hubicka + + * lto-streamer-out.c (output_constructor): Push CTORS_OUT timevar. + (cmp_symbol_files): New. + (lto_output): Copy sections in file order. + * lto-streamer.h (lto_file_decl_data): Add field order. + 2019-10-23 Jan Hubicka * ipa-reference.h (ipa_reference_var_uid): Move offline. diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 87c9e92f3af..2c712926f32 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -2228,6 +2228,7 @@ output_constructor (struct varpool_node *node) fprintf (streamer_dump_file, "\nStreaming constructor of %s\n", node->name ()); + timevar_push (TV_IPA_LTO_CTORS_OUT); ob = create_output_block (LTO_section_function_body); clear_line_info (ob); @@ -2247,6 +2248,7 @@ output_constructor (struct varpool_node *node) if (streamer_dump_file) fprintf (streamer_dump_file, "Finished streaming %s\n", node->name ()); + timevar_pop (TV_IPA_LTO_CTORS_OUT); } @@ -2427,6 +2429,30 @@ produce_lto_section () destroy_output_block (ob); } +/* Compare symbols to get them sorted by filename (to optimize streaming) */ + +static int +cmp_symbol_files (const void *pn1, const void *pn2) +{ + const symtab_node *n1 = *(const symtab_node * const *)pn1; + const symtab_node *n2 = *(const symtab_node * const *)pn2; + + int file_order1 = n1->lto_file_data ? n1->lto_file_data->order : -1; + int file_order2 = n2->lto_file_data ? n2->lto_file_data->order : -1; + + /* Order files same way as they appeared in the command line to reduce + seeking while copying sections. */ + if (file_order1 != file_order2) + return file_order1 - file_order2; + + /* Order within static library. */ + if (n1->lto_file_data && n1->lto_file_data->id != n2->lto_file_data->id) + return n1->lto_file_data->id - n2->lto_file_data->id; + + /* And finaly order by the definition order. */ + return n1->order - n2->order; +} + /* Main entry point from the pass manager. */ void @@ -2435,8 +2461,9 @@ lto_output (void) struct lto_out_decl_state *decl_state; bitmap output = NULL; bitmap_obstack output_obstack; - int i, n_nodes; + unsigned int i, n_nodes; lto_symtab_encoder_t encoder = lto_get_out_decl_state ()->symtab_node_encoder; + auto_vec symbols_to_copy; prune_offload_funcs (); @@ -2452,32 +2479,17 @@ lto_output (void) produce_lto_section (); n_nodes = lto_symtab_encoder_size (encoder); - /* Process only the functions with bodies. */ + /* Prepare vector of functions to output and then sort it to optimize + section copying. */ for (i = 0; i < n_nodes; i++) { symtab_node *snode = lto_symtab_encoder_deref (encoder, i); + if (snode->alias) + continue; if (cgraph_node *node = dyn_cast (snode)) { - if (lto_symtab_encoder_encode_body_p (encoder, node) - && !node->alias) - { - if (flag_checking) - gcc_assert (bitmap_set_bit (output, DECL_UID (node->decl))); - decl_state = lto_new_out_decl_state (); - lto_push_out_decl_state (decl_state); - if (gimple_has_body_p (node->decl) - || (!flag_wpa - && flag_incremental_link != INCREMENTAL_LINK_LTO) - /* Thunks have no body but they may be synthetized - at WPA time. */ - || DECL_ARGUMENTS (node->decl)) - output_function (node); - else - copy_function_or_variable (node); - gcc_assert (lto_get_out_decl_state () == decl_state); - lto_pop_out_decl_state (); - lto_record_function_out_decl_state (node->decl, decl_state); - } + if (lto_symtab_encoder_encode_body_p (encoder, node)) + symbols_to_copy.safe_push (node); } else if (varpool_node *node = dyn_cast (snode)) { @@ -2487,27 +2499,42 @@ lto_output (void) if (ctor && !in_lto_p) walk_tree (&ctor, wrap_refs, NULL, NULL); if (get_symbol_initial_value (encoder, node->decl) == error_mark_node - && lto_symtab_encoder_encode_initializer_p (encoder, node) - && !node->alias) - { - timevar_push (TV_IPA_LTO_CTORS_OUT); - if (flag_checking) - gcc_assert (bitmap_set_bit (output, DECL_UID (node->decl))); - decl_state = lto_new_out_decl_state (); - lto_push_out_decl_state (decl_state); - if (DECL_INITIAL (node->decl) != error_mark_node - || (!flag_wpa - && flag_incremental_link != INCREMENTAL_LINK_LTO)) - output_constructor (node); - else - copy_function_or_variable (node); - gcc_assert (lto_get_out_decl_state () == decl_state); - lto_pop_out_decl_state (); - lto_record_function_out_decl_state (node->decl, decl_state); - timevar_pop (TV_IPA_LTO_CTORS_OUT); - } + && lto_symtab_encoder_encode_initializer_p (encoder, node)) + symbols_to_copy.safe_push (node); } } + symbols_to_copy.qsort (cmp_symbol_files); + for (i = 0; i < symbols_to_copy.length (); i++) + { + symtab_node *snode = symbols_to_copy[i]; + cgraph_node *cnode; + varpool_node *vnode; + + if (flag_checking) + gcc_assert (bitmap_set_bit (output, DECL_UID (snode->decl))); + + decl_state = lto_new_out_decl_state (); + lto_push_out_decl_state (decl_state); + + if ((cnode = dyn_cast (snode)) + && (gimple_has_body_p (cnode->decl) + || (!flag_wpa + && flag_incremental_link != INCREMENTAL_LINK_LTO) + /* Thunks have no body but they may be synthetized + at WPA time. */ + || DECL_ARGUMENTS (cnode->decl))) + output_function (cnode); + else if ((vnode = dyn_cast (snode)) + && (DECL_INITIAL (vnode->decl) != error_mark_node + || (!flag_wpa + && flag_incremental_link != INCREMENTAL_LINK_LTO))) + output_constructor (vnode); + else + copy_function_or_variable (snode); + gcc_assert (lto_get_out_decl_state () == decl_state); + lto_pop_out_decl_state (); + lto_record_function_out_decl_state (snode->decl, decl_state); + } /* Emit the callgraph after emitting function bodies. This needs to be done now to make sure that all the statements in every function diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 9f787c4bd1e..3e4308aab15 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -603,6 +603,9 @@ struct GTY(()) lto_file_decl_data /* Linked list used temporarily in reader */ struct lto_file_decl_data *next; + /* Order in which the file appears on the command line. */ + int order; + /* Sub ID for merged objects. */ unsigned HOST_WIDE_INT id; diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index bb4e57ef131..49c77e03242 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2019-10-23 Jan Hubicka + + * lto-common.c (lto_file_finalize): Add order attribute. + (lto_create_files_from_ids): Pass order. + (lto_file_read): UPdate call of lto_create_files_from_ids. + 2019-10-12 Jan Hubicka * lto-common.c (read_cgraph_and_symbols): Grow ggc memory use after diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c index 967f2285a73..cdfc7b07719 100644 --- a/gcc/lto/lto-common.c +++ b/gcc/lto/lto-common.c @@ -2177,7 +2177,8 @@ create_subid_section_table (struct lto_section_slot *ls, splay_tree file_ids, /* Read declarations and other initializations for a FILE_DATA. */ static void -lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) +lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file, + int order) { const char *data; size_t len; @@ -2195,6 +2196,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) file_data->renaming_hash_table = lto_create_renaming_table (); file_data->file_name = file->filename; + file_data->order = order; #ifdef ACCEL_COMPILER lto_input_mode_table (file_data); #else @@ -2231,9 +2233,9 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) static int lto_create_files_from_ids (lto_file *file, struct lto_file_decl_data *file_data, - int *count) + int *count, int order) { - lto_file_finalize (file_data, file); + lto_file_finalize (file_data, file, order); if (symtab->dump_file) fprintf (symtab->dump_file, "Creating file %s with sub id " HOST_WIDE_INT_PRINT_HEX "\n", @@ -2285,9 +2287,10 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count) lto_resolution_read (file_ids, resolution_file, file); /* Finalize each lto file for each submodule in the merged object. */ + int order = 0; for (file_data = file_list.first; file_data != NULL; file_data = file_data->next) - lto_create_files_from_ids (file, file_data, count); + lto_create_files_from_ids (file, file_data, count, order++); splay_tree_delete (file_ids); htab_delete (section_hash_table); -- 2.30.2