diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-17 15:08:24 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-17 15:08:24 +0000 |
commit | 8ceff600cdabf3b92b7543c9a940204dd8f784b6 (patch) | |
tree | 37057cc11efb7f662edca2c35160d9fcf3e20d36 /gcc/lto-streamer-in.c | |
parent | 3cad7e87732e9a5eb56a4800ceac16a605797b57 (diff) | |
download | gcc-8ceff600cdabf3b92b7543c9a940204dd8f784b6.tar.gz |
2013-06-17 Richard Biener <rguenther@suse.de>
* lto-streamer.h (enum LTO_tags): Add LTO_tree_scc.
(lto_input_scc): Declare.
(lto_input_tree_1): Likewise.
(struct lto_stats_d): Add num_tree_bodies_output and
num_pickle_refs_output.
* lto-streamer-in.c (lto_read_body): Use streamer_tree_cache_get_tree.
(lto_read_tree_1): Split out from ...
(lto_read_tree): ... this.
(lto_input_scc): New function.
(lto_input_tree_1): Split out from ...
(lto_input_tree): ... this. Handle LTO_tree_scc.
(lto_data_in_create): Create the streamer cache without hashes.
* lto-streamer-out.c (create_output_block): Create the streamer
cache with hashes when not doing WPA.
(lto_write_tree_1): Split out from ...
(lto_write_tree): ... this.
(get_symbol_initial_value): New function.
(lto_output_tree_1): Split out from ...
(lto_output_tree): ... this. Write trees as series of SCCs
using a DFS walk via DFS_write_tree.
(struct sccs, struct scc_entry): New types.
(next_dfs_num, sccstack, sccstate, sccstate_obstack): New globals.
(DFS_write_tree_body): New function.
(DFS_write_tree): Likewise.
(hash_tree): Likewise.
(scc_entry_compare): Likewise.
(hash_scc): Likewise.
(tree_is_indexable): DEBUG_EXPR_DECLs are local entities.
* tree-streamer-in.c (lto_input_ts_list_tree_pointers): Stream
TREE_CHAIN as regular reference.
(streamer_read_integer_cst): Remove.
(streamer_get_pickled_tree): Adjust.
* tree-streamer-out.c (streamer_write_chain): Disable streaming
of DECL_EXTERNALs in BLOCK_VARS for now.
(write_ts_list_tree_pointers): Stream TREE_CHAIN as regular
reference.
* tree-streamer.c (streamer_tree_cache_add_to_node_array):
Add hash value argument and record that if hashes are recorded
in the cache.
(streamer_tree_cache_insert_1): Adjust.
(streamer_tree_cache_insert): Likewise.
(streamer_tree_cache_insert_at): Rename to ...
(streamer_tree_cache_replace_tree): ... this and adjust.
(streamer_tree_cache_append): Adjust.
(record_common_node): Likewise.
(streamer_tree_cache_create): Add argument whether to
record hash values together with trees.
(streamer_tree_cache_delete): Adjust.
* tree-streamer.h (struct streamer_tree_cache_d): Add
vector of hashes.
(streamer_read_integer_cst): Remove.
(streamer_tree_cache_insert): Adjust.
(streamer_tree_cache_append): Likewise.
(streamer_tree_cache_insert_at): Rename to ...
(streamer_tree_cache_replace_tree): ... this and adjust.
(streamer_tree_cache_create): Add argument whether to record hashes.
(streamer_tree_cache_get): Rename to ...
(streamer_tree_cache_get_tree): ... this.
(streamer_tree_cache_get_hash): New function.
* tree.c (cache_integer_cst): New function.
* tree.h (cache_integer_cst): Declare.
(ANON_AGGRNAME_FORMAT, ANON_AGGRNAME_P): Move here from cp/cp-tree.h.
* lto-symtab.c (lto_varpool_replace_node): Only release
DECL_INITIAL of non-prevailing decls.
* varpool.c (varpool_remove_initializer): Do not release
DECL_INITIAL when we are still in CGRAPH_LTO_STREAMING.
cp/
* cp-tree.h (ANON_AGGRNAME_FORMAT, ANON_AGGRNAME_P): Move to tree.h.
lto/
* Make-lang.in (lto.o): Add $(DATA_STREAMER_H) dependency.
* lto.c: Include data-streamer.h.
(lto_read_in_decl_state): Use streamer_tree_cache_get_tree.
(gimple_type_leader_entry_s, gimple_type_leader,
gimple_lookup_type_leader): Remove.
(gtc_visit): Simplify.
(gimple_types_compatible_p): Likewise.
(gimple_register_type_1): Likewise. Merge into ...
(gimple_register_type): ... this. Keep it as legacy for
statistics purposes for now.
(fixup_integer_cst): Remove.
(LTO_FIXUP_TREE, lto_fixup_types, lto_ft_*): Simplify and
rename to ...
(MAYBE_REMEMBER_WITH_VARS, maybe_remember_with_vars,
maybe_remember_with_vars_*): ... these.
(uniquify_nodes): Remove.
(lto_fixup_prevailing_type): New function.
(struct tree_scc, struct tree_scc_hasher): New type and hasher.
(tree_scc_hash, tree_scc_hash_obstack): New globals.
(num_merged_types, num_prevailing_types, num_not_merged_types,
num_not_merged_types_in_same_scc, total_scc_size, num_sccs_read,
total_scc_size_merged, num_sccs_merged, num_scc_compares,
num_scc_compare_collisions): New global counters.
(compare_tree_sccs_1): New function.
(compare_tree_sccs): Likewise.
(unify_scc): Likewise.
(lto_read_decls): Stream in tree SCCs and unify them on the
way in. Finalize prevailing SCC tree members.
(read_cgraph_and_symbols): Do not initialize or free gimple_type_leader.
Allocate and free tree_scc_hash_obstack and tree_scc_hash, do not bother
to ggc-collect during merging.
(print_lto_report_1): Adjust for new merging code.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200151 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto-streamer-in.c')
-rw-r--r-- | gcc/lto-streamer-in.c | 149 |
1 files changed, 117 insertions, 32 deletions
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 02889a99501..2484cc23f52 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1016,7 +1016,7 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl, unsigned i; for (i = len; i-- > from;) { - tree t = cache->nodes[i]; + tree t = streamer_tree_cache_get_tree (cache, i); if (t == NULL_TREE) continue; @@ -1056,12 +1056,43 @@ lto_input_function_body (struct lto_file_decl_data *file_data, } +/* Read the physical representation of a tree node EXPR from + input block IB using the per-file context in DATA_IN. */ + +static void +lto_read_tree_1 (struct lto_input_block *ib, struct data_in *data_in, tree expr) +{ + /* Read all the bitfield values in EXPR. Note that for LTO, we + only write language-independent bitfields, so no more unpacking is + needed. */ + streamer_read_tree_bitfields (ib, data_in, expr); + + /* Read all the pointer fields in EXPR. */ + streamer_read_tree_body (ib, data_in, expr); + + /* Read any LTO-specific data not read by the tree streamer. */ + if (DECL_P (expr) + && TREE_CODE (expr) != FUNCTION_DECL + && TREE_CODE (expr) != TRANSLATION_UNIT_DECL) + DECL_INITIAL (expr) = stream_read_tree (ib, data_in); + + /* We should never try to instantiate an MD or NORMAL builtin here. */ + if (TREE_CODE (expr) == FUNCTION_DECL) + gcc_assert (!streamer_handle_as_builtin_p (expr)); + +#ifdef LTO_STREAMER_DEBUG + /* Remove the mapping to RESULT's original address set by + streamer_alloc_tree. */ + lto_orig_address_remove (expr); +#endif +} + /* Read the physical representation of a tree node with tag TAG from input block IB using the per-file context in DATA_IN. */ static tree lto_read_tree (struct lto_input_block *ib, struct data_in *data_in, - enum LTO_tags tag) + enum LTO_tags tag, hashval_t hash) { /* Instantiate a new tree node. */ tree result = streamer_alloc_tree (ib, data_in, tag); @@ -1069,35 +1100,70 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in, /* Enter RESULT in the reader cache. This will make RESULT available so that circular references in the rest of the tree structure can be resolved in subsequent calls to stream_read_tree. */ - streamer_tree_cache_append (data_in->reader_cache, result); + streamer_tree_cache_append (data_in->reader_cache, result, hash); - /* Read all the bitfield values in RESULT. Note that for LTO, we - only write language-independent bitfields, so no more unpacking is - needed. */ - streamer_read_tree_bitfields (ib, data_in, result); + lto_read_tree_1 (ib, data_in, result); - /* Read all the pointer fields in RESULT. */ - streamer_read_tree_body (ib, data_in, result); + /* end_marker = */ streamer_read_uchar (ib); - /* Read any LTO-specific data not read by the tree streamer. */ - if (DECL_P (result) - && TREE_CODE (result) != FUNCTION_DECL - && TREE_CODE (result) != TRANSLATION_UNIT_DECL) - DECL_INITIAL (result) = stream_read_tree (ib, data_in); + return result; +} - /* We should never try to instantiate an MD or NORMAL builtin here. */ - if (TREE_CODE (result) == FUNCTION_DECL) - gcc_assert (!streamer_handle_as_builtin_p (result)); - /* end_marker = */ streamer_read_uchar (ib); +/* Populate the reader cache with trees materialized from the SCC + following in the IB, DATA_IN stream. */ -#ifdef LTO_STREAMER_DEBUG - /* Remove the mapping to RESULT's original address set by - streamer_alloc_tree. */ - lto_orig_address_remove (result); -#endif +hashval_t +lto_input_scc (struct lto_input_block *ib, struct data_in *data_in, + unsigned *len, unsigned *entry_len) +{ + /* A blob of unnamed tree nodes, fill the cache from it and + recurse. */ + unsigned size = streamer_read_uhwi (ib); + hashval_t scc_hash = streamer_read_uhwi (ib); + unsigned scc_entry_len = 1; - return result; + if (size == 1) + { + enum LTO_tags tag = streamer_read_record_start (ib); + lto_input_tree_1 (ib, data_in, tag, scc_hash); + } + else + { + unsigned int first = data_in->reader_cache->nodes.length (); + tree result; + + scc_entry_len = streamer_read_uhwi (ib); + + /* Materialize size trees by reading their headers. */ + for (unsigned i = 0; i < size; ++i) + { + enum LTO_tags tag = streamer_read_record_start (ib); + if (tag == LTO_null + || (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref) + || tag == LTO_tree_pickle_reference + || tag == LTO_builtin_decl + || tag == LTO_integer_cst + || tag == LTO_tree_scc) + gcc_unreachable (); + + result = streamer_alloc_tree (ib, data_in, tag); + streamer_tree_cache_append (data_in->reader_cache, result, 0); + } + + /* Read the tree bitpacks and references. */ + for (unsigned i = 0; i < size; ++i) + { + result = streamer_tree_cache_get_tree (data_in->reader_cache, + first + i); + lto_read_tree_1 (ib, data_in, result); + /* end_marker = */ streamer_read_uchar (ib); + } + } + + *len = size; + *entry_len = scc_entry_len; + return scc_hash; } @@ -1106,12 +1172,11 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in, to previously read nodes. */ tree -lto_input_tree (struct lto_input_block *ib, struct data_in *data_in) +lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in, + enum LTO_tags tag, hashval_t hash) { - enum LTO_tags tag; tree result; - tag = streamer_read_record_start (ib); gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS); if (tag == LTO_null) @@ -1137,19 +1202,39 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in) } else if (tag == LTO_integer_cst) { - /* For shared integer constants we only need the type and its hi/low - words. */ - result = streamer_read_integer_cst (ib, data_in); + /* For shared integer constants in singletons we can use the existing + tree integer constant merging code. */ + tree type = stream_read_tree (ib, data_in); + unsigned HOST_WIDE_INT low = streamer_read_uhwi (ib); + HOST_WIDE_INT high = streamer_read_hwi (ib); + result = build_int_cst_wide (type, low, high); + streamer_tree_cache_append (data_in->reader_cache, result, hash); + } + else if (tag == LTO_tree_scc) + { + unsigned len, entry_len; + + /* Input and skip the SCC. */ + lto_input_scc (ib, data_in, &len, &entry_len); + + /* Recurse. */ + return lto_input_tree (ib, data_in); } else { /* Otherwise, materialize a new node from IB. */ - result = lto_read_tree (ib, data_in, tag); + result = lto_read_tree (ib, data_in, tag, hash); } return result; } +tree +lto_input_tree (struct lto_input_block *ib, struct data_in *data_in) +{ + return lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0); +} + /* Input toplevel asms. */ @@ -1220,7 +1305,7 @@ lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings, data_in->strings = strings; data_in->strings_len = len; data_in->globals_resolution = resolutions; - data_in->reader_cache = streamer_tree_cache_create (); + data_in->reader_cache = streamer_tree_cache_create (false); return data_in; } |