aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-09-03 12:51:01 +0200
committerJakub Jelinek <jakub@redhat.com>2020-09-03 12:51:01 +0200
commit3536ff2de8317c430546fd97574d44c5146cef2b (patch)
tree8e204242f7a42d218ac77d9cf7503df54dd379a4 /gcc/lto-streamer-out.c
parentb246f5272eb7242a9cefe5b4e7220be9d86ea512 (diff)
downloadgcc-3536ff2de8317c430546fd97574d44c5146cef2b.zip
gcc-3536ff2de8317c430546fd97574d44c5146cef2b.tar.gz
gcc-3536ff2de8317c430546fd97574d44c5146cef2b.tar.bz2
lto: Cache location_ts including BLOCKs in GIMPLE streaming [PR94311]
As mentioned in the PR, when compiling valgrind even on fairly small testcase where in one larger function the location keeps oscillating between a small line number and 8000-ish line number in the same file we very quickly run out of all possible location_t numbers and because of that emit non-sensical line numbers in .debug_line. There are ways how to decrease speed of depleting location_t numbers in libcpp, but the main reason of this is that we use stream_input_location_now for streaming in location_t for gimple_location and phi arg locations. libcpp strongly prefers that the locations it is given are sorted by the different files and by line numbers in ascending order, otherwise it depletes quickly no matter what and is much more costly (many extra file changes etc.). The reason for not caching those were the BLOCKs that were streamed immediately after the location and encoded into the locations (and for PHIs we failed to stream the BLOCKs altogether). This patch enhances the location cache to handle also BLOCKs (but not for everything, only for the spots we care about the BLOCKs) and also optimizes the size of the LTO stream by emitting a single bit into a pack whether the BLOCK changed from last case and only streaming the BLOCK tree if it changed. 2020-09-03 Jakub Jelinek <jakub@redhat.com> PR lto/94311 * gimple.h (gimple_location_ptr, gimple_phi_arg_location_ptr): New functions. * streamer-hooks.h (struct streamer_hooks): Add output_location_and_block callback. Fix up formatting for output_location. (stream_output_location_and_block): Define. * lto-streamer.h (class lto_location_cache): Fix comment typo. Add current_block member. (lto_location_cache::input_location_and_block): New method. (lto_location_cache::lto_location_cache): Initialize current_block. (lto_location_cache::cached_location): Add block member. (struct output_block): Add current_block member. (lto_output_location): Formatting fix. (lto_output_location_and_block): Declare. * lto-streamer.c (lto_streamer_hooks_init): Initialize streamer_hooks.output_location_and_block. * lto-streamer-in.c (lto_location_cache::cmp_loc): Also compare block members. (lto_location_cache::apply_location_cache): Handle blocks. (lto_location_cache::accept_location_cache, lto_location_cache::revert_location_cache): Fix up function comments. (lto_location_cache::input_location_and_block): New method. (lto_location_cache::input_location): Implement using input_location_and_block. (input_function): Invoke apply_location_cache after streaming in all bbs. * lto-streamer-out.c (clear_line_info): Set current_block. (lto_output_location_1): New function, moved from lto_output_location, added block handling. (lto_output_location): Implement using lto_output_location_1. (lto_output_location_and_block): New function. * gimple-streamer-in.c (input_phi): Use input_location_and_block to input and cache both location and block. (input_gimple_stmt): Likewise. * gimple-streamer-out.c (output_phi): Use stream_output_location_and_block. (output_gimple_stmt): Likewise.
Diffstat (limited to 'gcc/lto-streamer-out.c')
-rw-r--r--gcc/lto-streamer-out.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index ec28928..914d5eb 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -60,6 +60,10 @@ clear_line_info (struct output_block *ob)
ob->current_line = 0;
ob->current_col = 0;
ob->current_sysp = false;
+ /* Initialize to something that will never appear as block,
+ so that the first location with block in a function etc.
+ always streams a change_block bit and the first block. */
+ ob->current_block = void_node;
}
@@ -178,40 +182,72 @@ tree_is_indexable (tree t)
After outputting bitpack, lto_output_location_data has
to be done to output actual data. */
-void
-lto_output_location (struct output_block *ob, struct bitpack_d *bp,
- location_t loc)
+static void
+lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
+ location_t orig_loc, bool block_p)
{
- expanded_location xloc;
+ location_t loc = LOCATION_LOCUS (orig_loc);
- loc = LOCATION_LOCUS (loc);
bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT,
loc < RESERVED_LOCATION_COUNT
? loc : RESERVED_LOCATION_COUNT);
- if (loc < RESERVED_LOCATION_COUNT)
- return;
+ if (loc >= RESERVED_LOCATION_COUNT)
+ {
+ expanded_location xloc = expand_location (loc);
- xloc = expand_location (loc);
+ bp_pack_value (bp, ob->current_file != xloc.file, 1);
+ bp_pack_value (bp, ob->current_line != xloc.line, 1);
+ bp_pack_value (bp, ob->current_col != xloc.column, 1);
- bp_pack_value (bp, ob->current_file != xloc.file, 1);
- bp_pack_value (bp, ob->current_line != xloc.line, 1);
- bp_pack_value (bp, ob->current_col != xloc.column, 1);
+ if (ob->current_file != xloc.file)
+ {
+ bp_pack_string (ob, bp, remap_debug_filename (xloc.file), true);
+ bp_pack_value (bp, xloc.sysp, 1);
+ }
+ ob->current_file = xloc.file;
+ ob->current_sysp = xloc.sysp;
+
+ if (ob->current_line != xloc.line)
+ bp_pack_var_len_unsigned (bp, xloc.line);
+ ob->current_line = xloc.line;
+
+ if (ob->current_col != xloc.column)
+ bp_pack_var_len_unsigned (bp, xloc.column);
+ ob->current_col = xloc.column;
+ }
- if (ob->current_file != xloc.file)
+ if (block_p)
{
- bp_pack_string (ob, bp, remap_debug_filename (xloc.file), true);
- bp_pack_value (bp, xloc.sysp, 1);
+ tree block = LOCATION_BLOCK (orig_loc);
+ bp_pack_value (bp, ob->current_block != block, 1);
+ streamer_write_bitpack (bp);
+ if (ob->current_block != block)
+ lto_output_tree (ob, block, true, true);
+ ob->current_block = block;
}
- ob->current_file = xloc.file;
- ob->current_sysp = xloc.sysp;
+}
+
+/* Output info about new location into bitpack BP.
+ After outputting bitpack, lto_output_location_data has
+ to be done to output actual data. */
- if (ob->current_line != xloc.line)
- bp_pack_var_len_unsigned (bp, xloc.line);
- ob->current_line = xloc.line;
+void
+lto_output_location (struct output_block *ob, struct bitpack_d *bp,
+ location_t loc)
+{
+ lto_output_location_1 (ob, bp, loc, false);
+}
+
+/* Output info about new location into bitpack BP.
+ After outputting bitpack, lto_output_location_data has
+ to be done to output actual data. Like lto_output_location, but
+ additionally output LOCATION_BLOCK info too and write the BP bitpack. */
- if (ob->current_col != xloc.column)
- bp_pack_var_len_unsigned (bp, xloc.column);
- ob->current_col = xloc.column;
+void
+lto_output_location_and_block (struct output_block *ob, struct bitpack_d *bp,
+ location_t loc)
+{
+ lto_output_location_1 (ob, bp, loc, true);
}