aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-06-17 15:08:24 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-06-17 15:08:24 +0000
commitee03e71d472a3f73cbc1a132a284309f36565972 (patch)
tree37057cc11efb7f662edca2c35160d9fcf3e20d36 /gcc/tree.c
parenta0e33cbcd8966627b6a9d88b14e4ad9efccc97b4 (diff)
downloadgcc-ee03e71d472a3f73cbc1a132a284309f36565972.zip
gcc-ee03e71d472a3f73cbc1a132a284309f36565972.tar.gz
gcc-ee03e71d472a3f73cbc1a132a284309f36565972.tar.bz2
lto-streamer.h (enum LTO_tags): Add LTO_tree_scc.
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. From-SVN: r200151
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 2c93c0e..67553b8 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1266,6 +1266,99 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
return t;
}
+void
+cache_integer_cst (tree t)
+{
+ tree type = TREE_TYPE (t);
+ HOST_WIDE_INT hi = TREE_INT_CST_HIGH (t);
+ unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (t);
+ int ix = -1;
+ int limit = 0;
+
+ gcc_assert (!TREE_OVERFLOW (t));
+
+ switch (TREE_CODE (type))
+ {
+ case NULLPTR_TYPE:
+ gcc_assert (hi == 0 && low == 0);
+ /* Fallthru. */
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ /* Cache NULL pointer. */
+ if (!hi && !low)
+ {
+ limit = 1;
+ ix = 0;
+ }
+ break;
+
+ case BOOLEAN_TYPE:
+ /* Cache false or true. */
+ limit = 2;
+ if (!hi && low < 2)
+ ix = low;
+ break;
+
+ case INTEGER_TYPE:
+ case OFFSET_TYPE:
+ if (TYPE_UNSIGNED (type))
+ {
+ /* Cache 0..N */
+ limit = INTEGER_SHARE_LIMIT;
+ if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
+ ix = low;
+ }
+ else
+ {
+ /* Cache -1..N */
+ limit = INTEGER_SHARE_LIMIT + 1;
+ if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
+ ix = low + 1;
+ else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1)
+ ix = 0;
+ }
+ break;
+
+ case ENUMERAL_TYPE:
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (ix >= 0)
+ {
+ /* Look for it in the type's vector of small shared ints. */
+ if (!TYPE_CACHED_VALUES_P (type))
+ {
+ TYPE_CACHED_VALUES_P (type) = 1;
+ TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
+ }
+
+ gcc_assert (TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) == NULL_TREE);
+ TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
+ }
+ else
+ {
+ /* Use the cache of larger shared ints. */
+ void **slot;
+
+ slot = htab_find_slot (int_cst_hash_table, t, INSERT);
+ /* If there is already an entry for the number verify it's the
+ same. */
+ if (*slot)
+ {
+ gcc_assert (TREE_INT_CST_LOW ((tree)*slot) == low
+ && TREE_INT_CST_HIGH ((tree)*slot) == hi);
+ return;
+ }
+ /* Otherwise insert this one into the hash table. */
+ *slot = t;
+ }
+}
+
+
/* Builds an integer constant in TYPE such that lowest BITS bits are ones
and the rest are zeros. */