diff options
author | Jan Hubicka <jh@suse.cz> | 2010-05-18 01:02:47 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-05-17 23:02:47 +0000 |
commit | 922f15c273e96e7bff9fecb9c0cbd90a5709f839 (patch) | |
tree | 8dc7afe7cb29c4f8a1378cea118b057dbc8b8444 | |
parent | 28632d639518d2d98347218a1269548fa2c22765 (diff) | |
download | gcc-922f15c273e96e7bff9fecb9c0cbd90a5709f839.zip gcc-922f15c273e96e7bff9fecb9c0cbd90a5709f839.tar.gz gcc-922f15c273e96e7bff9fecb9c0cbd90a5709f839.tar.bz2 |
cgraph.h (struct ipa_replace_map): Add parm_num parameter.
* cgraph.h (struct ipa_replace_map): Add parm_num parameter.
* lto-cgraph.c (output_cgraph_opt_summary, input_cgraph_opt_summary):
New functions.
(output_cgraph): Call output_cgraph_opt_summary.
(input_cgrpah): Call input_cgraph_opt_summary.
(output_cgraph_opt_summary_p, output_node_opt_summary,
input_node_opt_summary, input_cgraph_opt_section): New functions.
* lto-section-in.c (lto_section_name): Add cgraphopt.
* tree-inline.c (tree_function_versioning): Handle parm_num.
* lto-streamer.c (lto_get_section_name): Handle cgraphopt.
* lto-streamer.h (lto_section_type): Add LTO_section_cgraph_opt_sum.
From-SVN: r159517
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 202 | ||||
-rw-r--r-- | gcc/lto-section-in.c | 3 | ||||
-rw-r--r-- | gcc/lto-streamer.c | 3 | ||||
-rw-r--r-- | gcc/lto-streamer.h | 1 | ||||
-rw-r--r-- | gcc/tree-inline.c | 9 |
7 files changed, 233 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d01aa4..9a7b3c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-05-17 Jan Hubicka <jh@suse.cz> + + * cgraph.h (struct ipa_replace_map): Add parm_num parameter. + * lto-cgraph.c (output_cgraph_opt_summary, input_cgraph_opt_summary): + New functions. + (output_cgraph): Call output_cgraph_opt_summary. + (input_cgrpah): Call input_cgraph_opt_summary. + (output_cgraph_opt_summary_p, output_node_opt_summary, + input_node_opt_summary, input_cgraph_opt_section): New functions. + * lto-section-in.c (lto_section_name): Add cgraphopt. + * tree-inline.c (tree_function_versioning): Handle parm_num. + * lto-streamer.c (lto_get_section_name): Handle cgraphopt. + * lto-streamer.h (lto_section_type): Add LTO_section_cgraph_opt_sum. + 2010-05-17 Changpeng Fang <changpeng.fang@amd.com> * doc/invoke.texi: Update documentation for min-insn-to-prefetch-ratio. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 2841d25..b092301 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -157,6 +157,8 @@ struct GTY(()) ipa_replace_map tree old_tree; /* The new (replacing) tree. */ tree new_tree; + /* Parameter number to replace, when old_tree is NULL. */ + int parm_num; /* True when a substitution should be done, false otherwise. */ bool replace_p; /* True when we replace a reference to old_tree. */ diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 48e834e..8b0f8e1 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -47,6 +47,9 @@ along with GCC; see the file COPYING3. If not see #include "gcov-io.h" static void output_varpool (cgraph_node_set, varpool_node_set); +static void output_cgraph_opt_summary (void); +static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes); + /* Cgraph streaming is organized as set of record whose type is indicated by a tag. */ @@ -840,6 +843,9 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset) lto_varpool_encoder_t varpool_encoder; struct cgraph_asm_node *can; + if (flag_wpa) + output_cgraph_opt_summary (); + ob = lto_create_simple_output_block (LTO_section_cgraph); output_profile_summary (ob); @@ -1403,6 +1409,8 @@ input_cgraph (void) input_refs (ib, nodes, varpool); lto_destroy_simple_input_block (file_data, LTO_section_refs, ib, data, len); + if (flag_ltrans) + input_cgraph_opt_summary (nodes); VEC_free (cgraph_node_ptr, heap, nodes); VEC_free (varpool_node_ptr, heap, varpool); } @@ -1420,3 +1428,197 @@ input_cgraph (void) node->aux = NULL; } } + +/* True when we need optimization summary for NODE. */ + +static int +output_cgraph_opt_summary_p (struct cgraph_node *node) +{ + if (!node->clone_of) + return false; + return (node->clone.tree_map + || node->clone.args_to_skip + || node->clone.combined_args_to_skip); +} + +/* Output optimization summary for NODE to OB. */ + +static void +output_node_opt_summary (struct output_block *ob, + struct cgraph_node *node) +{ + unsigned int index; + bitmap_iterator bi; + struct ipa_replace_map *map; + struct bitpack_d *bp; + int i; + + lto_output_uleb128_stream (ob->main_stream, + bitmap_count_bits (node->clone.args_to_skip)); + EXECUTE_IF_SET_IN_BITMAP (node->clone.args_to_skip, 0, index, bi) + lto_output_uleb128_stream (ob->main_stream, index); + lto_output_uleb128_stream (ob->main_stream, + bitmap_count_bits (node->clone.combined_args_to_skip)); + EXECUTE_IF_SET_IN_BITMAP (node->clone.combined_args_to_skip, 0, index, bi) + lto_output_uleb128_stream (ob->main_stream, index); + lto_output_uleb128_stream (ob->main_stream, + VEC_length (ipa_replace_map_p, node->clone.tree_map)); + for (i = 0; VEC_iterate (ipa_replace_map_p, node->clone.tree_map, i, map); i++) + { + int parm_num; + tree parm; + + for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm; + parm = TREE_CHAIN (parm), parm_num++) + if (map->old_tree == parm) + break; + /* At the moment we assume all old trees to be PARM_DECLs, because we have no + mechanism to store function local declarations into summaries. */ + gcc_assert (parm); + lto_output_uleb128_stream (ob->main_stream, parm_num); + lto_output_tree (ob, map->new_tree, true); + bp = bitpack_create (); + bp_pack_value (bp, map->replace_p, 1); + bp_pack_value (bp, map->ref_p, 1); + lto_output_bitpack (ob->main_stream, bp); + bitpack_delete (bp); + } +} + +/* Output optimization summaries stored in callgraph. + At the moment it is the clone info structure. */ + +static void +output_cgraph_opt_summary (void) +{ + struct cgraph_node *node; + int i, n_nodes; + lto_cgraph_encoder_t encoder; + struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum); + unsigned count = 0; + + ob->cgraph_node = NULL; + encoder = ob->decl_state->cgraph_node_encoder; + n_nodes = lto_cgraph_encoder_size (encoder); + for (i = 0; i < n_nodes; i++) + if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i))) + count++; + lto_output_uleb128_stream (ob->main_stream, count); + for (i = 0; i < n_nodes; i++) + { + node = lto_cgraph_encoder_deref (encoder, i); + if (output_cgraph_opt_summary_p (node)) + { + lto_output_uleb128_stream (ob->main_stream, i); + output_node_opt_summary (ob, node); + } + } + produce_asm (ob, NULL); + destroy_output_block (ob); +} + +/* Input optimiation summary of NODE. */ + +static void +input_node_opt_summary (struct cgraph_node *node, + struct lto_input_block *ib_main, + struct data_in *data_in) +{ + int i; + int count; + int bit; + struct bitpack_d *bp; + + count = lto_input_uleb128 (ib_main); + if (count) + node->clone.args_to_skip = BITMAP_GGC_ALLOC (); + for (i = 0; i < count; i++) + { + bit = lto_input_uleb128 (ib_main); + bitmap_set_bit (node->clone.args_to_skip, bit); + } + count = lto_input_uleb128 (ib_main); + if (count) + node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC (); + for (i = 0; i < count; i++) + { + bit = lto_input_uleb128 (ib_main); + bitmap_set_bit (node->clone.combined_args_to_skip, bit); + } + count = lto_input_uleb128 (ib_main); + for (i = 0; i < count; i++) + { + int parm_num; + tree parm; + struct ipa_replace_map *map = GGC_NEW (struct ipa_replace_map); + + VEC_safe_push (ipa_replace_map_p, gc, node->clone.tree_map, map); + for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm_num; + parm = TREE_CHAIN (parm)) + parm_num --; + map->parm_num = lto_input_uleb128 (ib_main); + map->old_tree = NULL; + map->new_tree = lto_input_tree (ib_main, data_in); + bp = lto_input_bitpack (ib_main); + map->replace_p = bp_unpack_value (bp, 1); + map->ref_p = bp_unpack_value (bp, 1); + bitpack_delete (bp); + } +} + +/* Read section in file FILE_DATA of length LEN with data DATA. */ + +static void +input_cgraph_opt_section (struct lto_file_decl_data *file_data, + const char *data, size_t len, VEC (cgraph_node_ptr, + heap) * nodes) +{ + const struct lto_function_header *header = + (const struct lto_function_header *) data; + const int32_t cfg_offset = sizeof (struct lto_function_header); + const int32_t main_offset = cfg_offset + header->cfg_size; + const int32_t string_offset = main_offset + header->main_size; + struct data_in *data_in; + struct lto_input_block ib_main; + unsigned int i; + unsigned int count; + + LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0, + header->main_size); + + data_in = + lto_data_in_create (file_data, (const char *) data + string_offset, + header->string_size, NULL); + count = lto_input_uleb128 (&ib_main); + + for (i = 0; i < count; i++) + { + int ref = lto_input_uleb128 (&ib_main); + input_node_opt_summary (VEC_index (cgraph_node_ptr, nodes, ref), + &ib_main, data_in); + } + lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data, + len); + lto_data_in_delete (data_in); +} + +/* Input optimization summary of cgraph. */ + +static void +input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes) +{ + struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data (); + struct lto_file_decl_data *file_data; + unsigned int j = 0; + + while ((file_data = file_data_vec[j++])) + { + size_t len; + const char *data = + lto_get_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, + &len); + + if (data) + input_cgraph_opt_section (file_data, data, len, nodes); + } +} diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 44b3e1c..6d081d8 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -58,7 +58,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] = "ipa_pure_const", "ipa_reference", "symtab", - "opts" + "opts", + "cgraphopt" }; unsigned char diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index 153d2a7..20ce075 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -178,6 +178,9 @@ lto_get_section_name (int section_type, const char *name) case LTO_section_opts: return concat (LTO_SECTION_NAME_PREFIX, ".opts", NULL); + case LTO_section_cgraph_opt_sum: + return concat (LTO_SECTION_NAME_PREFIX, ".cgraphopt", NULL); + default: internal_error ("bytecode stream: unexpected LTO section %s", name); } diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index d86811a..b7c0c36 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -264,6 +264,7 @@ enum lto_section_type LTO_section_ipa_reference, LTO_section_symtab, LTO_section_opts, + LTO_section_cgraph_opt_sum, LTO_N_SECTION_TYPES /* Must be last. */ }; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 03b013c..bb2ee23 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4945,6 +4945,15 @@ tree_function_versioning (tree old_decl, tree new_decl, if (replace_info->replace_p) { tree op = replace_info->new_tree; + if (!replace_info->old_tree) + { + int i = replace_info->parm_num; + tree parm; + for (parm = DECL_ARGUMENTS (old_decl); i; parm = TREE_CHAIN (parm)) + i --; + replace_info->old_tree = parm; + } + STRIP_NOPS (op); |