From patchwork Thu May 26 09:34:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 97514 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E1E11B6FC0 for ; Thu, 26 May 2011 19:34:30 +1000 (EST) Received: (qmail 16395 invoked by alias); 26 May 2011 09:34:29 -0000 Received: (qmail 15991 invoked by uid 22791); 26 May 2011 09:34:27 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 26 May 2011 09:34:12 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 2281E9AC7CD; Thu, 26 May 2011 11:34:10 +0200 (CEST) Date: Thu, 26 May 2011 11:34:10 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Better location streaming Message-ID: <20110526093410.GG17175@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, we spend a lot of effort (and disk space) into streaming file/line/column and sys_p fields of locations. Since often the trees come from same statement, it is common for those to not change. We even already have current location info in output_block and data_in, but don't use it. This patch update streaming to stream first bitpack of what changed and then streaming only the changed locations. Because I did not find any use of insys_p field in the backend, I removed streaming it (though it would be easy doable to stream it along the file info). Because we need only 4 bits, it would make a lot of sense to merge location bitpack with the other bitpack and for this reason I split the i/o intput part doing bitpack and part streaming the actual data. At the moment we always do that at once, since doing anything saner needs a bit of reorganization of how we stream trees. Regtested x86_64-linux, full bootstrap®test running, OK? Honza * lto-streamer-out.c (clear_line_info): Set location_output_done. (lto_output_location_bitpack): New function. (lto_output_location_data): New function. (lto_output_location): Reorg. * lto-streamer-in.c (clear_line_info): Set location_input_done. (lto_input_location_bitpack): New function. (lto_input_location_data): New function. (lto_input_location): Reorg. * lto-streamer.h (struct output_block): Add output_file, output_line, output_col and location_output_done flags. (struct data_in): Add input_file, input_line, input_col and location_input_done flags. Index: lto-streamer-out.c =================================================================== --- lto-streamer-out.c (revision 174264) +++ lto-streamer-out.c (working copy) @@ -95,6 +95,7 @@ clear_line_info (struct output_block *ob ob->current_file = NULL; ob->current_line = 0; ob->current_col = 0; + ob->location_output_done = 1; } @@ -587,29 +588,72 @@ pack_value_fields (struct bitpack_d *bp, } -/* Emit location LOC to output block OB. */ +/* Output info about new location into bitpack BP. + After outputting bitpack, lto_output_location_data has + to be done to output actual data. */ + +static inline void +lto_output_location_bitpack (struct bitpack_d *bp, + struct output_block *ob, + location_t loc) +{ + gcc_checking_assert (ob->location_output_done); + bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1); + if (loc == UNKNOWN_LOCATION) + ob->output_file = ob->output_line = ob->output_col = 0; + else + { + expanded_location xloc; + + xloc = expand_location (loc); + + ob->output_file = xloc.file != ob->current_file; + ob->output_line = xloc.line != ob->current_line; + ob->output_col = xloc.column != ob->current_col; + } + bp_pack_value (bp, ob->output_file, 1); + bp_pack_value (bp, ob->output_line, 1); + bp_pack_value (bp, ob->output_col, 1); + ob->location_output_done = false; +} + + +/* Output location info we prepared to output in + lto_output_location_bitpack */ static void -lto_output_location (struct output_block *ob, location_t loc) +lto_output_location_data (struct output_block *ob) { - expanded_location xloc; + gcc_checking_assert (!ob->location_output_done); - if (loc == UNKNOWN_LOCATION) + if (ob->output_file) + lto_output_string (ob, ob->main_stream, ob->current_file); + if (ob->output_line) { - lto_output_string (ob, ob->main_stream, NULL); - return; + gcc_checking_assert (ob->current_line >= 0); + output_uleb128 (ob, ob->current_line); } + if (ob->output_col) + { + gcc_checking_assert (ob->current_col >= 0); + output_uleb128 (ob, ob->current_col); + } + ob->location_output_done = true; +} - xloc = expand_location (loc); - lto_output_string (ob, ob->main_stream, xloc.file); - output_sleb128 (ob, xloc.line); - output_sleb128 (ob, xloc.column); - output_sleb128 (ob, xloc.sysp); - - ob->current_file = xloc.file; - ob->current_line = xloc.line; - ob->current_col = xloc.column; +/* Emit location LOC to output block OB. + When bitpack is handy, it is more space effecient to call + lto_output_location_bitpack and lto_output_location_data directly + adding info into the existing bitpack. */ + +static void +lto_output_location (struct output_block *ob, location_t loc) +{ + struct bitpack_d bp = bitpack_create (ob->main_stream); + lto_output_location_bitpack (&bp, ob, loc); + lto_output_bitpack (&bp); + lto_output_location_data (ob); } @@ -642,7 +686,7 @@ lto_output_tree_ref (struct output_block if (expr == NULL_TREE) { - output_zero (ob); + output_record_start (ob, LTO_null); return; } Index: lto-streamer-in.c =================================================================== --- lto-streamer-in.c (revision 174264) +++ lto-streamer-in.c (working copy) @@ -281,40 +281,69 @@ clear_line_info (struct data_in *data_in data_in->current_file = NULL; data_in->current_line = 0; data_in->current_col = 0; + data_in->location_input_done = true; } -/* Read a location from input block IB. */ +/* Read a location bitpack from input block IB. */ + +static inline void +lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp) +{ + gcc_checking_assert (data_in->location_input_done); + data_in->location_input_done = false; + data_in->input_unknown_location = bp_unpack_value (bp, 1); + data_in->input_file_p = bp_unpack_value (bp, 1); + data_in->input_line_p = bp_unpack_value (bp, 1); + data_in->input_col_p = bp_unpack_value (bp, 1); +} + + +/* Read locaiton data we determined to change and update info. */ static location_t -lto_input_location (struct lto_input_block *ib, struct data_in *data_in) +lto_input_location_data (struct lto_input_block *ib, struct data_in *data_in) { - expanded_location xloc; + bool prev_file = data_in->current_file != NULL; - xloc.file = lto_input_string (data_in, ib); - if (xloc.file == NULL) + gcc_checking_assert (!data_in->location_input_done); + data_in->location_input_done = true; + if (data_in->input_unknown_location) return UNKNOWN_LOCATION; + if (data_in->input_file_p) + { + data_in->current_file = lto_input_string (data_in, ib); + data_in->current_file = canon_file_name (data_in->current_file); + } + if (data_in->input_line_p) + data_in->current_line = lto_input_uleb128 (ib); + if (data_in->input_col_p) + data_in->current_col = lto_input_uleb128 (ib); - xloc.file = canon_file_name (xloc.file); - xloc.line = lto_input_sleb128 (ib); - xloc.column = lto_input_sleb128 (ib); - xloc.sysp = lto_input_sleb128 (ib); - - if (data_in->current_file != xloc.file) + if (data_in->input_file_p) { - if (data_in->current_file) + if (prev_file) linemap_add (line_table, LC_LEAVE, false, NULL, 0); - linemap_add (line_table, LC_ENTER, xloc.sysp, xloc.file, xloc.line); + linemap_add (line_table, LC_ENTER, false, data_in->current_file, data_in->current_line); } - else if (data_in->current_line != xloc.line) - linemap_line_start (line_table, xloc.line, xloc.column); + else if (data_in->input_line_p) + linemap_line_start (line_table, data_in->current_line, data_in->current_col); - data_in->current_file = xloc.file; - data_in->current_line = xloc.line; - data_in->current_col = xloc.column; + return linemap_position_for_column (line_table, data_in->current_col); +} + + +/* Read a location from input block IB. */ + +static location_t +lto_input_location (struct lto_input_block *ib, struct data_in *data_in) +{ + struct bitpack_d bp; - return linemap_position_for_column (line_table, xloc.column); + bp = lto_input_bitpack (ib); + lto_input_location_bitpack (data_in, &bp); + return lto_input_location_data (ib, data_in); } Index: lto-streamer.h =================================================================== --- lto-streamer.h (revision 174264) +++ lto-streamer.h (working copy) @@ -694,6 +694,10 @@ struct output_block const char *current_file; int current_line; int current_col; + unsigned output_file : 1; + unsigned output_line : 1; + unsigned output_col : 1; + unsigned location_output_done : 1; /* True if writing globals and types. */ bool global; @@ -728,6 +732,11 @@ struct data_in const char *current_file; int current_line; int current_col; + unsigned input_unknown_location : 1; + unsigned input_file_p : 1; + unsigned input_line_p : 1; + unsigned input_col_p : 1; + unsigned location_input_done : 1; /* Maps each reference number to the resolution done by the linker. */ VEC(ld_plugin_symbol_resolution_t,heap) *globals_resolution;