From patchwork Thu Mar 26 00:56:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 454837 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B97B314009B for ; Thu, 26 Mar 2015 11:56:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=XwHX87+7; dkim-adsp=none (unprotected policy); dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=FgdjpsWOzV5vF8NoyVJzqUu1OPwXP0X++EcbUwySp7HGyb4t1zvc4 GNo6xiJOv/wG+Fe2lqkUKIMnX53hmAcahPByN779HXnz3xNqZVoa1ptndgobSnaC mXuYirQ3z2rKNYk0mfbOvJGJrH+zw/IWo9rOKB91mI1nefO4bd7I60= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=dg17dj041zqYEg8XbA0vItjIebs=; b=XwHX87+7h3F2iqhrckaR c1IkACpnMNymMN2rrvzLjxQRJkzbnUwazvS2P/mymyPZeeglykaE34PkoUKVJEYv FqcOsE1cO+SZWbnA3sueER7KC819L/FmY7YKgJ4fXXBHC8U3t5D0EfRQ81TIa/yw Tq8Bj2XDwgsO32x7iRKQK4Y= Received: (qmail 27854 invoked by alias); 26 Mar 2015 00:56:37 -0000 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 Received: (qmail 27839 invoked by uid 89); 26 Mar 2015 00:56:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 26 Mar 2015 00:56:34 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 793B054690D; Thu, 26 Mar 2015 01:56:30 +0100 (CET) Date: Thu, 26 Mar 2015 01:56:30 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Fix line-maps wrt LTO Message-ID: <20150326005630.GB66441@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, I read linemap_line_start and I think I noticed few issues with respect to overflows and lines being added randomly. 1) line_delta is computed as to_line SOURCE_LINE (map, set->highest_line) I think the last inserted line is not very releavnt. What we care about is the base of the last location and to keep thing dense how much we are stretching the value range from highest inserted element (inserting into middle is cheap). For this reason I added base_line_delta and changed line_delta to be to_line - SOURCE_LINE (map, set->highest_location). Because things go in randomly, highest_line, which really is last inserted line, may be somewhere in between. 2) (line_delta > 10 && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000) ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) is in range 7... 15, so it never gets high enough to make this conditional trigger. I changed it to: || line_delta > 1000 || (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) > 1000 I.e. we do not want to skip more than 1000 unused entries since highest inserted location. 3) (max_column_hint <= 80 && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10) seems to intend to reduce the column range when it is no longer needed. Again, this is not really good idea when line inserted is not last. 4) the code deciding whether to do reuse seems worng: if (line_delta < 0 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) line_delta really should be base_line_delta, we do not need to give up when map's line is 1, SOURCE_LINE (map, set->highest_line) is 5 and we are requested to switch to line 3. Second last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) tests whether location has only one line that does not work (at least with my changes) because we may switch to next line and back. This conditoinal also seems to be completely missing hanlding of overflows. The following patch makes all line info and all but one carret to to be right on chromium warnings Bootstrapped/regtested x86_64-linux, OK? * line-map.c (linemap_line_start): Correct overflow tests. Index: line-map.c =================================================================== --- line-map.c (revision 221568) +++ line-map.c (working copy) @@ -519,25 +519,38 @@ linemap_line_start (struct line_maps *se struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (set); source_location highest = set->highest_location; source_location r; - linenum_type last_line = - SOURCE_LINE (map, set->highest_line); - int line_delta = to_line - last_line; + int base_line_delta = to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map); + int line_delta = to_line - SOURCE_LINE (map, set->highest_location); bool add_map = false; - if (line_delta < 0 - || (line_delta > 10 - && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000) - || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map))) + /* Single MAP entry can be used to encode multiple source lines. + Look for situations when this is impossible or undesriable. */ + if (base_line_delta < 0 + /* We want to keep maps resonably dense, so do not increase the range + of this linemap entry by more than 1000. */ + || line_delta > 1000 + || (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) > 1000 + /* If the max column is out of range and we are still not dropping line + info. */ + || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) + && highest < 0x60000000) + /* If the prevoius line was long. Ignore this problem is we already + re-used the map for lines with greater indexes. */ || (max_column_hint <= 80 - && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10) + && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10 && line_delta > 0) + /* If we are just started running out of locations (which makes us to drop + column info), but current line map still has column info, create fresh + one. */ || (highest > 0x60000000 - && (set->max_column_hint || highest > 0x70000000))) + && (ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) + || highest > 0x70000000))) add_map = true; else max_column_hint = set->max_column_hint; if (add_map) { int column_bits; + bool reuse_map = true; if (max_column_hint > 100000 || highest > 0x60000000) { /* If the column number is ridiculous or we've allocated a huge @@ -554,11 +567,38 @@ linemap_line_start (struct line_maps *se column_bits++; max_column_hint = 1U << column_bits; } + /* Allocate the new line_map. However, if the current map only has a single line we can sometimes just increase its column_bits instead. */ - if (line_delta < 0 - || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) - || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) + if (base_line_delta < 0 || base_line_delta != line_delta + /* If we just started running out of locators, but current map still + has column info, do not reuse it. */ + || (highest > 0x60000000 + && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) + && base_line_delta) + /* If the line delta is too large. */ + || line_delta > 1000) + reuse_map = false; + + /* When reusing, we must be sure that column_bits is high enough + for already recorded locations. */ + if (reuse_map) + { + unsigned int max_column = SOURCE_COLUMN (map, highest) + 1; + int combined_column_bits = column_bits; + + while (max_column >= (1U << combined_column_bits)) + combined_column_bits++; + + if ((line_delta << combined_column_bits) > 1000) + reuse_map = false; + else + { + column_bits = combined_column_bits; + max_column_hint = 1U << combined_column_bits; + } + } + if (!reuse_map) map = (struct line_map *) linemap_add (set, LC_RENAME, ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), @@ -609,6 +649,9 @@ linemap_position_for_column (struct line { struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (set); r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); + /* We just got to overflow; disable column numbers. */ + if (to_column >= set->max_column_hint) + return r; } } r = r + to_column;