summaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-in.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-17 15:08:24 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-17 15:08:24 +0000
commit8ceff600cdabf3b92b7543c9a940204dd8f784b6 (patch)
tree37057cc11efb7f662edca2c35160d9fcf3e20d36 /gcc/lto-streamer-in.c
parent3cad7e87732e9a5eb56a4800ceac16a605797b57 (diff)
downloadgcc-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.c149
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;
}