this patch cleans up tree streaming. The code is prepared to stream nested
trees, but we only handle flat trees. As a result we have quite heavy function
to stream in/out tree reference which is used many times and shows up in
profile.
This patch adds stream_write_tree_ref/stream_read_tree_ref which is used to
stream references to trees that are required to exist in the cache or be
indexable.
The actual implementation is just a first cut. I would like to make it more
compact. We used to stream 2 byte tag (as UHWI) + UHWI representing the index.
Now we stream one UHWI that represent type of reference + index for references
to cache, but still two integers for references to global stream. This is
becaue the abstraction is not very helpful here and I want to clean this up
incrementally.
I would also like to get rid of the ref_p parameters which seems unnecessary for
flat streams.
This reduces around 7% of global stream, 3% when compressed.
More reduction will happen once the format is sanitized a bit.
from
[WPA] read 4597161 unshared trees
[WPA] read 2937414 mergeable SCCs of average size 1.364280
[WPA] 8604617 tree bodies read in total
[WPA] tree SCC table: size 524287, 247507 elements, collision ratio: 0.377468
[WPA] tree SCC max chain length 2 (size 1)
[WPA] Compared 2689907 SCCs, 184 collisions (0.000068)
[WPA] Merged 2689890
SCCs
[WPA] Merged 3722677 tree bodies
[WPA] Merged 632040 types
...
[WPA] Compression: 88124141 input bytes, 234906430 uncompressed bytes (ratio: 2.665631)
[WPA] Size of mmap'd section decls: 88124141 bytes
...
[WPA] Compression: 113758813 input bytes, 316149514 uncompressed bytes (ratio: 2.779121)
[WPA] Size of mmap'd section decls: 88124141 bytes
[WPA] Size of mmap'd section function_body: 14485721 bytes
to
[WPA] read 4597174 unshared trees
[WPA] read 2937413 mergeable SCCs of average size 1.364280
[WPA] 8604629 tree bodies read in total
[WPA] tree SCC table: size 524287, 247509 elements, collision ratio: 0.377458
[WPA] tree SCC max chain length 2 (size 1)
[WPA] Compared 2689904 SCCs, 183 collisions (0.000068)
[WPA] Merged 2689888 SCCs
[WPA] Merged 3722675 tree bodies
[WPA] Merged 632041 types
....
[WPA] Size of mmap'd section decls: 86177293 bytes
[WPA] Compression: 86177293 input bytes, 217625095 uncompressed bytes (ratio: 2.525318)
....
[WPA] Compression: 111682269 input bytes, 297228756 uncompressed bytes (ratio: 2.661378)
[WPA] Size of mmap'd section decls: 86177293 bytes
[WPA] Size of mmap'd section function_body: 14349032 bytes
gcc/ChangeLog:
* lto-streamer-in.c (streamer_read_chain): Move here from
tree-streamer-in.c.
(stream_read_tree_ref): New.
(lto_input_tree_1): Simplify.
* lto-streamer-out.c (stream_write_tree_ref): New.
(lto_write_tree_1): Simplify.
(lto_output_tree_1): Simplify.
(DFS::DFS_write_tree): Simplify.
(streamer_write_chain): Move here from tree-stremaer-out.c.
* lto-streamer.h (lto_output_tree_ref): Update prototype.
(stream_read_tree_ref): Declare
(stream_write_tree_ref): Declare
* tree-streamer-in.c (streamer_read_chain): Update to use
stream_read_tree_ref.
(lto_input_ts_common_tree_pointers): Likewise.
(lto_input_ts_vector_tree_pointers): Likewise.
(lto_input_ts_poly_tree_pointers): Likewise.
(lto_input_ts_complex_tree_pointers): Likewise.
(lto_input_ts_decl_minimal_tree_pointers): Likewise.
(lto_input_ts_decl_common_tree_pointers): Likewise.
(lto_input_ts_decl_with_vis_tree_pointers): Likewise.
(lto_input_ts_field_decl_tree_pointers): Likewise.
(lto_input_ts_function_decl_tree_pointers): Likewise.
(lto_input_ts_type_common_tree_pointers): Likewise.
(lto_input_ts_type_non_common_tree_pointers): Likewise.
(lto_input_ts_list_tree_pointers): Likewise.
(lto_input_ts_vec_tree_pointers): Likewise.
(lto_input_ts_exp_tree_pointers): Likewise.
(lto_input_ts_block_tree_pointers): Likewise.
(lto_input_ts_binfo_tree_pointers): Likewise.
(lto_input_ts_constructor_tree_pointers): Likewise.
(lto_input_ts_omp_clause_tree_pointers): Likewise.
* tree-streamer-out.c (streamer_write_chain): Update to use
stream_write_tree_ref.
(write_ts_common_tree_pointers): Likewise.
(write_ts_vector_tree_pointers): Likewise.
(write_ts_poly_tree_pointers): Likewise.
(write_ts_complex_tree_pointers): Likewise.
(write_ts_decl_minimal_tree_pointers): Likewise.
(write_ts_decl_common_tree_pointers): Likewise.
(write_ts_decl_non_common_tree_pointers): Likewise.
(write_ts_decl_with_vis_tree_pointers): Likewise.
(write_ts_field_decl_tree_pointers): Likewise.
(write_ts_function_decl_tree_pointers): Likewise.
(write_ts_type_common_tree_pointers): Likewise.
(write_ts_type_non_common_tree_pointers): Likewise.
(write_ts_list_tree_pointers): Likewise.
(write_ts_vec_tree_pointers): Likewise.
(write_ts_exp_tree_pointers): Likewise.
(write_ts_block_tree_pointers): Likewise.
(write_ts_binfo_tree_pointers): Likewise.
(write_ts_constructor_tree_pointers): Likewise.
(write_ts_omp_clause_tree_pointers): Likewise.
(streamer_write_tree_body): Likewise.
(streamer_write_integer_cst): Likewise.
* tree-streamer.h (streamer_read_chain):Declare.
(streamer_write_chain):Declare.
(streamer_write_tree_body): Update prototype.
(streamer_write_integer_cst): Update prototype.
123 lines
4.3 KiB
C++
123 lines
4.3 KiB
C++
/* Data structures and functions for streaming trees.
|
|
|
|
Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
|
Contributed by Diego Novillo <dnovillo@google.com>
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 3, or (at your option) any later
|
|
version.
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef GCC_TREE_STREAMER_H
|
|
#define GCC_TREE_STREAMER_H
|
|
|
|
#include "streamer-hooks.h"
|
|
#include "data-streamer.h"
|
|
|
|
/* Cache of pickled nodes. Used to avoid writing the same node more
|
|
than once. The first time a tree node is streamed out, it is
|
|
entered in this cache. Subsequent references to the same node are
|
|
resolved by looking it up in this cache.
|
|
|
|
This is used in two ways:
|
|
|
|
- On the writing side, the first time T is added to STREAMER_CACHE,
|
|
a new reference index is created for T and T is emitted on the
|
|
stream. If T needs to be emitted again to the stream, instead of
|
|
pickling it again, the reference index is emitted.
|
|
|
|
- On the reading side, the first time T is read from the stream, it
|
|
is reconstructed in memory and a new reference index created for
|
|
T. The reconstructed T is inserted in some array so that when
|
|
the reference index for T is found in the input stream, it can be
|
|
used to look up into the array to get the reconstructed T. */
|
|
|
|
struct streamer_tree_cache_d
|
|
{
|
|
/* The mapping between tree nodes and slots into the nodes array. */
|
|
hash_map<tree, unsigned> *node_map;
|
|
|
|
/* The nodes pickled so far. */
|
|
vec<tree> nodes;
|
|
/* The node hashes (if available). */
|
|
vec<hashval_t> hashes;
|
|
|
|
/* Next index to assign. */
|
|
unsigned next_idx;
|
|
};
|
|
|
|
/* In tree-streamer-in.c. */
|
|
tree streamer_read_string_cst (class data_in *, class lto_input_block *);
|
|
tree streamer_alloc_tree (class lto_input_block *, class data_in *,
|
|
enum LTO_tags);
|
|
void streamer_read_tree_body (class lto_input_block *, class data_in *, tree);
|
|
tree streamer_get_pickled_tree (class lto_input_block *, class data_in *);
|
|
void streamer_read_tree_bitfields (class lto_input_block *,
|
|
class data_in *, tree);
|
|
|
|
/* In tree-streamer-out.c. */
|
|
void streamer_write_string_cst (struct output_block *,
|
|
struct lto_output_stream *, tree);
|
|
void streamer_write_tree_header (struct output_block *, tree);
|
|
void streamer_write_tree_bitfields (struct output_block *, tree);
|
|
void streamer_write_tree_body (struct output_block *, tree);
|
|
void streamer_write_integer_cst (struct output_block *, tree);
|
|
|
|
/* In tree-streamer.c. */
|
|
extern unsigned char streamer_mode_table[1 << 8];
|
|
void streamer_check_handled_ts_structures (void);
|
|
bool streamer_tree_cache_insert (struct streamer_tree_cache_d *, tree,
|
|
hashval_t, unsigned *);
|
|
void streamer_tree_cache_replace_tree (struct streamer_tree_cache_d *, tree,
|
|
unsigned);
|
|
void streamer_tree_cache_append (struct streamer_tree_cache_d *, tree,
|
|
hashval_t);
|
|
bool streamer_tree_cache_lookup (struct streamer_tree_cache_d *, tree,
|
|
unsigned *);
|
|
struct streamer_tree_cache_d *streamer_tree_cache_create (bool, bool, bool);
|
|
void streamer_tree_cache_delete (struct streamer_tree_cache_d *);
|
|
|
|
/* Return the tree node at slot IX in CACHE. */
|
|
|
|
static inline tree
|
|
streamer_tree_cache_get_tree (struct streamer_tree_cache_d *cache, unsigned ix)
|
|
{
|
|
return cache->nodes[ix];
|
|
}
|
|
|
|
/* Return the tree hash value at slot IX in CACHE. */
|
|
|
|
static inline hashval_t
|
|
streamer_tree_cache_get_hash (struct streamer_tree_cache_d *cache, unsigned ix)
|
|
{
|
|
return cache->hashes[ix];
|
|
}
|
|
|
|
static inline void
|
|
bp_pack_machine_mode (struct bitpack_d *bp, machine_mode mode)
|
|
{
|
|
streamer_mode_table[mode] = 1;
|
|
bp_pack_enum (bp, machine_mode, 1 << 8, mode);
|
|
}
|
|
|
|
static inline machine_mode
|
|
bp_unpack_machine_mode (struct bitpack_d *bp)
|
|
{
|
|
return (machine_mode)
|
|
((class lto_input_block *)
|
|
bp->stream)->mode_table[bp_unpack_enum (bp, machine_mode, 1 << 8)];
|
|
}
|
|
|
|
#endif /* GCC_TREE_STREAMER_H */
|