From patchwork Thu Jun 23 12:18:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 55327 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1321B3856DD5 for ; Thu, 23 Jun 2022 12:18:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1321B3856DD5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655986719; bh=dK1tWWj79hKJFaziqmsihK5sJhcynEGu/pNev9jCL+0=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=TEyIo3fif1N/Lf4/bp8xQBlJEOBcr2fe1X8dxqtqDanUW3qUeGZ/+Y5qqLJtezcYn JwnxYeOyo5smND4+ZGAN5g2i0ADqgI6rWr10Q+Xt94+PkI9fUssyOw/9L9OzKCDo/4 hB+2RvmlmCSN0FdQYNE0zYq1BpODAa6seV+JOBgw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by sourceware.org (Postfix) with ESMTPS id AB081385828E for ; Thu, 23 Jun 2022 12:18:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AB081385828E Received: by mail-qv1-xf29.google.com with SMTP id y14so24297101qvs.10 for ; Thu, 23 Jun 2022 05:18:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:message-id:date:mime-version:user-agent :content-language:to:from:subject; bh=dK1tWWj79hKJFaziqmsihK5sJhcynEGu/pNev9jCL+0=; b=dJ+kc+DP0Po0iDxp8aZ3WGo75EmSEEnT/fztMh+Vb5FCGMQ6DzOSJEDL/rJhqbNS6Y WqQkbfaq5pBHLJuGkLRoUkJPdixraLfFOOWaB24H0cZj83bVnqpI7Az7s8rrdtED8O/s zzBL+buY0A8cHmu6P5IW/9cuaHqrOMpl8WV/J+r/EX13eBPBfWv8q9+bVXolUL3tTWO8 4sVSbCQYWV3x59WZgETt+5PC+gZqlE2bhXEbFWsPpwW8JjyRdIroE4giX+M1fOzV1zw2 /Ee6wtpFq92sx8vu5TvmofbpCr27FUkyJ2dLqnVbd6/4oyy4710VxO57Ipglz9MVKgRF GzLA== X-Gm-Message-State: AJIora/ppgerpLAd0xEgN9NYMfmH2OmglmUXedcxue3sZF4eRhMCcd9n +0/o6sIoPh43gzSzLEue9TlYDsyBp5o= X-Google-Smtp-Source: AGRyM1uZ+ezr2CAgxe/zrxti05X95A43W4/sdNlvkOSeC+TDcPIuqra13e78TSSd5Ug8sqowUmYUJw== X-Received: by 2002:a05:622a:103:b0:305:89b:f159 with SMTP id u3-20020a05622a010300b00305089bf159mr7724395qtw.488.1655986684846; Thu, 23 Jun 2022 05:18:04 -0700 (PDT) Received: from ?IPV6:2620:10d:c0a3:1407:abb9:bd2a:a51d:da6c? ([2620:10d:c091:500::b2bb]) by smtp.googlemail.com with ESMTPSA id cj11-20020a05622a258b00b002f93ece0df3sm16568979qtb.71.2022.06.23.05.18.04 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 23 Jun 2022 05:18:04 -0700 (PDT) Message-ID: <0b4ac9e6-e681-f1dc-578c-c729c0840c6f@acm.org> Date: Thu, 23 Jun 2022 08:18:03 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 Content-Language: en-US To: GCC Patches Subject: c++: Prune unneeded macro locations X-Spam-Status: No, score=-3038.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Nathan Sidwell via Gcc-patches From: Nathan Sidwell Reply-To: Nathan Sidwell Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This implements garbage collection on locations within macro expansions, when streaming out a CMI. When doing the reachability walks, we now note which macro locations we need and then only write those locations. The complication here is that every macro expansion location has an independently calculated offset. This complicates writing, but reading remains the same -- the macro locations of a CMI continue to form a contiguous block. For std headers this reduced the number of macro maps by 40% and the number of locations by 16%. For a GMF including iostream, it reduced it by 80% and 60% respectively. Ordinary locations are still transformed en-mass. They are somewhat more complicated to apply a similar optimization to. nathan From 445cc1266ff8b9b8f96eceafa3c1116da54de967 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 22 Jun 2022 05:54:30 -0700 Subject: [PATCH] c++: Prune unneeded macro locations This implements garbage collection on locations within macro expansions, when streaming out a CMI. When doing the reachability walks, we now note which macro locations we need and then only write those locations. The complication here is that every macro expansion location has an independently calculated offset. This complicates writing, but reading remains the same -- the macro locations of a CMI continue to form a contiguous block. For std headers this reduced the number of macro maps by 40% and the number of locations by 16%. For a GMF including iostream, it reduced it by 80% and 60% respectively. Ordinary locations are still transformed en-mass. They are somewhat more complicated to apply a similar optimization to. gcc/cp/ * module.cc (struct macro_info): New. (struct macro_traits): New. (macro_remap, macro_table): New globals. (depset::hash::find_dependencies): Note namespace location. (module_for_macro_loc): Adjust. (module_state::note_location): New. (module_state::Write_location): Note location when not streaming. Adjust macro location streaming. (module_state::read_location): Adjust macro location streaming. (module_state::write_init_maps): New. (module_state::write_prepare_maps): Reimplement macro map preparation. (module_state::write_macro_maps): Reimplement. (module_state::read_macro_maps): Likewise. (module_state::write_begin): Adjust. gcc/testsuite/ * g++.dg/modules/loc-prune-1.C: New. * g++.dg/modules/loc-prune-2.C: New. * g++.dg/modules/loc-prune-3.C: New. * g++.dg/modules/pr98718_a.C: Adjust. * g++.dg/modules/pr98718_b.C: Adjust. --- gcc/cp/module.cc | 349 ++++++++++++++------- gcc/testsuite/g++.dg/modules/loc-prune-1.C | 19 ++ gcc/testsuite/g++.dg/modules/loc-prune-2.C | 14 + gcc/testsuite/g++.dg/modules/loc-prune-3.C | 16 + gcc/testsuite/g++.dg/modules/pr98718_a.C | 4 +- gcc/testsuite/g++.dg/modules/pr98718_b.C | 6 +- 6 files changed, 290 insertions(+), 118 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/loc-prune-1.C create mode 100644 gcc/testsuite/g++.dg/modules/loc-prune-2.C create mode 100644 gcc/testsuite/g++.dg/modules/loc-prune-3.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index d735d7e8b30..7ee779d06b9 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3238,6 +3238,65 @@ public: }; static loc_spans spans; + +/* Information about macro locations we stream out. */ +struct macro_info +{ + const line_map_macro *src; // original expansion + unsigned remap; // serialization + + static int compare (const void *a_, const void *b_) + { + auto *a = static_cast (a_); + auto *b = static_cast (b_); + + gcc_checking_assert (MAP_START_LOCATION (a->src) + != MAP_START_LOCATION (b->src)); + if (MAP_START_LOCATION (a->src) < MAP_START_LOCATION (b->src)) + return -1; + else + return +1; + } +}; +struct macro_traits +{ + typedef macro_info value_type; + typedef const line_map_macro *compare_type; + + static const bool empty_zero_p = false; + + static hashval_t hash (compare_type p) + { + return pointer_hash::hash (p); + } + static hashval_t hash (const value_type &v) + { + return hash (v.src); + } + static bool equal (const value_type &v, const compare_type p) + { + return v.src == p; + } + + static void mark_empty (value_type &v) + { + v.src = nullptr; + } + static bool is_empty (value_type &v) + { + return !v.src; + } + + static bool is_deleted (value_type &) { return false; } + static void mark_deleted (value_type &) { gcc_unreachable (); } + + static void remove (value_type &) {} +}; +/* Table keyed by line_map_macro, used for noting. */ +static hash_table *macro_table; +/* Sorted vector, used for writing. */ +static vec *macro_remap; + /* Indirection to allow bsearching imports by ordinary location. */ static vec *ool; @@ -3398,7 +3457,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { /* Location ranges for this module. adhoc-locs are decomposed, so don't have a range. */ loc_range_t GTY((skip)) ordinary_locs; - loc_range_t GTY((skip)) macro_locs; + loc_range_t GTY((skip)) macro_locs; // [lwm,num) /* LOC is first set too the importing location. When initially loaded it refers to a module loc whose parent is the importing @@ -3591,6 +3650,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { bool read_entities (unsigned count, unsigned lwm, unsigned hwm); private: + void write_init_maps (); location_map_info write_prepare_maps (module_state_config *); bool read_prepare_maps (const module_state_config *); @@ -3599,7 +3659,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { bool read_ordinary_maps (); void write_macro_maps (elf_out *to, location_map_info &, module_state_config *, unsigned *crc_ptr); - bool read_macro_maps (); + bool read_macro_maps (unsigned); private: void write_define (bytes_out &, const cpp_macro *, bool located = true); @@ -3616,6 +3676,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { static cpp_macro *deferred_macro (cpp_reader *, location_t, cpp_hashnode *); public: + static void note_location (location_t); static void write_location (bytes_out &, location_t); location_t read_location (bytes_in &) const; @@ -13106,7 +13167,10 @@ depset::hash::find_dependencies (module_state *module) else if (TREE_VISITED (decl)) /* A global tree. */; else if (item->get_entity_kind () == EK_NAMESPACE) - add_namespace_context (current, CP_DECL_CONTEXT (decl)); + { + module->note_location (DECL_SOURCE_LOCATION (decl)); + add_namespace_context (current, CP_DECL_CONTEXT (decl)); + } else { walker.mark_declaration (decl, current->has_defn ()); @@ -15518,15 +15582,15 @@ module_for_macro_loc (location_t loc) { unsigned half = len / 2; module_state *probe = (*modules)[pos + half]; - if (loc >= probe->macro_locs.second) - len = half; - else if (loc >= probe->macro_locs.first) - return probe; - else + if (loc < probe->macro_locs.first) { pos += half + 1; len = len - (half + 1); } + else if (loc >= (probe->macro_locs.first + probe->macro_locs.second)) + len = half; + else + return probe; } return NULL; @@ -15545,6 +15609,62 @@ module_state::imported_from () const return from; } +/* Note that LOC will need writing. This allows us to prune locations + that are not needed. */ + +void +module_state::note_location (location_t loc) +{ + if (!macro_table) + ; + else if (loc < RESERVED_LOCATION_COUNT) + ; + else if (IS_ADHOC_LOC (loc)) + { + location_t locus = get_location_from_adhoc_loc (line_table, loc); + note_location (locus); + source_range range = get_range_from_loc (line_table, loc); + if (range.m_start != locus) + note_location (range.m_start); + note_location (range.m_finish); + } + else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table)) + { + if (spans.macro (loc)) + { + const line_map *map = linemap_lookup (line_table, loc); + const line_map_macro *mac_map = linemap_check_macro (map); + hashval_t hv = macro_traits::hash (mac_map); + macro_info *slot + = macro_table->find_slot_with_hash (mac_map, hv, INSERT); + if (!slot->src) + { + slot->src = mac_map; + slot->remap = 0; + // Expansion locations could themselves be from a + // macro, we need to note them all. + note_location (mac_map->expansion); + gcc_checking_assert (mac_map->n_tokens); + location_t tloc = UNKNOWN_LOCATION; + for (unsigned ix = mac_map->n_tokens * 2; ix--;) + if (mac_map->macro_locations[ix] != tloc) + { + tloc = mac_map->macro_locations[ix]; + note_location (tloc); + } + } + } + } + else if (IS_ORDINARY_LOC (loc)) + { + /* This is where we should note we use this location. See comment + about write_ordinary_maps. */ + } + else + gcc_unreachable (); + return; +} + /* If we're not streaming, record that we need location LOC. Otherwise stream it. */ @@ -15552,9 +15672,10 @@ void module_state::write_location (bytes_out &sec, location_t loc) { if (!sec.streaming_p ()) - /* This is where we should note we use this location. See comment - about write_ordinary_maps. */ - return; + { + note_location (loc); + return; + } if (loc < RESERVED_LOCATION_COUNT) { @@ -15576,20 +15697,40 @@ module_state::write_location (bytes_out &sec, location_t loc) } else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table)) { - if (const loc_spans::span *span = spans.macro (loc)) + const macro_info *info = nullptr; + unsigned offset = 0; + if (unsigned hwm = macro_remap->length ()) { - unsigned off = MAX_LOCATION_T - loc; + info = macro_remap->begin (); + while (hwm != 1) + { + unsigned mid = hwm / 2; + if (MAP_START_LOCATION (info[mid].src) <= loc) + { + info += mid; + hwm -= mid; + } + else + hwm = mid; + } + offset = loc - MAP_START_LOCATION (info->src); + if (offset > info->src->n_tokens) + info = nullptr; + } - off -= span->macro_delta; + gcc_checking_assert (bool (info) == bool (spans.macro (loc))); + if (info) + { + offset += info->remap; sec.u (LK_MACRO); - sec.u (off); + sec.u (offset); dump (dumper::LOCATION) - && dump ("Macro location %u output %u", loc, off); + && dump ("Macro location %u output %u", loc, offset); } else if (const module_state *import = module_for_macro_loc (loc)) { - unsigned off = import->macro_locs.second - loc - 1; + unsigned off = loc - import->macro_locs.first; sec.u (LK_IMPORT_MACRO); sec.u (import->remap); sec.u (off); @@ -15668,12 +15809,8 @@ module_state::read_location (bytes_in &sec) const if (macro_locs.first) { - location_t adjusted = MAX_LOCATION_T - off; - adjusted -= slurp->loc_deltas.second; - if (adjusted < macro_locs.first) - sec.set_overrun (); - else if (adjusted < macro_locs.second) - locus = adjusted; + if (off < macro_locs.second) + locus = off + macro_locs.first; else sec.set_overrun (); } @@ -15733,8 +15870,8 @@ module_state::read_location (bytes_in &sec) const { if (!import->macro_locs.first) locus = import->loc; - else if (off < import->macro_locs.second - macro_locs.first) - locus = import->macro_locs.second - off - 1; + else if (off < import->macro_locs.second) + locus = off + import->macro_locs.first; else sec.set_overrun (); } @@ -15768,8 +15905,14 @@ module_state::read_location (bytes_in &sec) const // should decompose locations so that we can have a more graceful // degradation upon running out? +void +module_state::write_init_maps () +{ + macro_table = new hash_table (EXPERIMENT (1, 400)); +} + location_map_info -module_state::write_prepare_maps (module_state_config *) +module_state::write_prepare_maps (module_state_config *cfg) { dump () && dump ("Preparing locations"); dump.indent (); @@ -15840,7 +15983,6 @@ module_state::write_prepare_maps (module_state_config *) /* Adjust the maps. Ordinary ones ascend, and we must maintain alignment. Macro ones descend, but are unaligned. */ location_t ord_off = spans[loc_spans::SPAN_FIRST].ordinary.first; - location_t mac_off = spans[loc_spans::SPAN_FIRST].macro.second; location_t range_mask = (1u << max_range) - 1; dump () && dump ("Ordinary maps range bits:%u, preserve:%x, zero:%u", @@ -15850,16 +15992,9 @@ module_state::write_prepare_maps (module_state_config *) { loc_spans::span &span = spans[ix]; - span.macro_delta = mac_off - span.macro.second; - mac_off -= span.macro.second - span.macro.first; - dump () && dump ("Macro span:%u [%u,%u):%u->%d(%u)", ix, - span.macro.first, span.macro.second, - span.macro.second - span.macro.first, - span.macro_delta, span.macro.first + span.macro_delta); - line_map_ordinary const *omap = linemap_check_ordinary (linemap_lookup (line_table, - span.ordinary.first)); + span.ordinary.first)); location_t base = MAP_START_LOCATION (omap); /* Preserve the low MAX_RANGE bits of base by incrementing ORD_OFF. */ @@ -15888,14 +16023,33 @@ module_state::write_prepare_maps (module_state_config *) ord_off = span.ordinary.second + span.ordinary_delta; } - dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps lwm:%u ", + vec_alloc (macro_remap, macro_table->size ()); + for (auto iter = macro_table->begin (), end = macro_table->end (); + iter != end; ++iter) + macro_remap->quick_push (*iter); + delete macro_table; + macro_table = nullptr; + + macro_remap->qsort (¯o_info::compare); + unsigned offset = 0; + for (auto iter = macro_remap->begin (), end = macro_remap->end (); + iter != end; ++iter) + { + auto mac = iter->src; + iter->remap = offset; + offset += mac->n_tokens; + } + info.num_maps.second = macro_remap->length (); + cfg->macro_locs = offset; + + dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps %u locs", info.num_maps.first, ord_off, - info.num_maps.second, mac_off); + info.num_maps.second, cfg->macro_locs); dump.outdent (); info.max_range = max_range; - + return info; } @@ -16077,7 +16231,7 @@ module_state::write_ordinary_maps (elf_out *to, location_map_info &info, void module_state::write_macro_maps (elf_out *to, location_map_info &info, - module_state_config *cfg, unsigned *crc_p) + module_state_config *, unsigned *crc_p) { dump () && dump ("Writing macro location maps"); dump.indent (); @@ -16088,74 +16242,46 @@ module_state::write_macro_maps (elf_out *to, location_map_info &info, dump () && dump ("Macro maps:%u", info.num_maps.second); sec.u (info.num_maps.second); - location_t offset = spans[loc_spans::SPAN_FIRST].macro.second; - sec.u (offset); - unsigned macro_num = 0; - for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++) + for (auto iter = macro_remap->end (), begin = macro_remap->begin (); + iter-- != begin;) { - loc_spans::span &span = spans[ix]; - if (span.macro.first == span.macro.second) - /* Empty span. */ - continue; - - for (unsigned macro - = linemap_lookup_macro_index (line_table, span.macro.second - 1); - macro < LINEMAPS_MACRO_USED (line_table); - macro++) + auto mac = iter->src; + sec.u (iter->remap); + sec.u (mac->n_tokens); + sec.cpp_node (mac->macro); + write_location (sec, mac->expansion); + const location_t *locs = mac->macro_locations; + /* There are lots of identical runs. */ + location_t prev = UNKNOWN_LOCATION; + unsigned count = 0; + unsigned runs = 0; + for (unsigned jx = mac->n_tokens * 2; jx--;) { - line_map_macro const *mmap - = LINEMAPS_MACRO_MAP_AT (line_table, macro); - location_t start_loc = MAP_START_LOCATION (mmap); - if (start_loc < span.macro.first) - /* Fallen out of the span. */ - break; - - if (!mmap->n_tokens) - /* Empty expansion. */ - continue; - - sec.u (offset); - sec.u (mmap->n_tokens); - sec.cpp_node (mmap->macro); - write_location (sec, mmap->expansion); - const location_t *locs = mmap->macro_locations; - /* There are lots of identical runs. */ - location_t prev = UNKNOWN_LOCATION; - unsigned count = 0; - unsigned runs = 0; - for (unsigned jx = mmap->n_tokens * 2; jx--;) + location_t tok_loc = locs[jx]; + if (tok_loc == prev) { - location_t tok_loc = locs[jx]; - if (tok_loc == prev) - { - count++; - continue; - } - runs++; - sec.u (count); - count = 1; - prev = tok_loc; - write_location (sec, tok_loc); + count++; + continue; } + runs++; sec.u (count); - dump (dumper::LOCATION) - && dump ("Span:%u macro:%u %I %u/%u*2 locations [%u,%u)->%u", - ix, macro_num, identifier (mmap->macro), - runs, mmap->n_tokens, - start_loc, start_loc + mmap->n_tokens, - start_loc + span.macro_delta); - macro_num++; - offset -= mmap->n_tokens; - gcc_checking_assert (offset == start_loc + span.macro_delta); + count = 1; + prev = tok_loc; + write_location (sec, tok_loc); } + sec.u (count); + dump (dumper::LOCATION) + && dump ("Macro:%u %I %u/%u*2 locations [%u,%u)->%u", + macro_num, identifier (mac->macro), + runs, mac->n_tokens, + MAP_START_LOCATION (mac), + MAP_START_LOCATION (mac) + mac->n_tokens, + iter->remap); + macro_num++; } - dump () && dump ("Macro location lwm:%u", offset); - sec.u (offset); gcc_assert (macro_num == info.num_maps.second); - cfg->macro_locs = MAX_LOCATION_T + 1 - offset; - sec.end (to, to->name (MOD_SNAME_PFX ".mlm"), crc_p); dump.outdent (); } @@ -16265,7 +16391,7 @@ module_state::read_ordinary_maps () } bool -module_state::read_macro_maps () +module_state::read_macro_maps (unsigned num_macro_locs) { bytes_in sec; @@ -16275,24 +16401,22 @@ module_state::read_macro_maps () dump.indent (); unsigned num_macros = sec.u (); - location_t zero = sec.u (); - dump () && dump ("Macro maps:%u zero:%u", num_macros, zero); + dump () && dump ("Macro maps:%u locs:%u", num_macros, num_macro_locs); bool propagated = spans.maybe_propagate (this, line_table->highest_location + 1); location_t offset = LINEMAPS_MACRO_LOWEST_LOCATION (line_table); - slurp->loc_deltas.second = zero - offset; - macro_locs.second = zero - slurp->loc_deltas.second; - dump () && dump ("Macro loc delta %d", slurp->loc_deltas.second); + macro_locs.second = num_macro_locs; + macro_locs.first = offset - num_macro_locs; + + dump () && dump ("Macro loc delta %d", offset); + dump () && dump ("Macro locations [%u,%u)", + macro_locs.first, macro_locs.second); for (unsigned ix = 0; ix != num_macros && !sec.get_overrun (); ix++) { - unsigned lwm = sec.u (); - /* Record the current LWM so that the below read_location is - ok. */ - macro_locs.first = lwm - slurp->loc_deltas.second; - + unsigned offset = sec.u (); unsigned n_tokens = sec.u (); cpp_hashnode *node = sec.cpp_node (); location_t exp_loc = read_location (sec); @@ -16303,6 +16427,8 @@ module_state::read_macro_maps () /* We shouldn't run out of locations, as we checked that we had enough before starting. */ break; + gcc_checking_assert (MAP_START_LOCATION (macro) + == offset + macro_locs.first); location_t *locs = macro->macro_locations; location_t tok_loc = UNKNOWN_LOCATION; @@ -16326,11 +16452,8 @@ module_state::read_macro_maps () MAP_START_LOCATION (macro), MAP_START_LOCATION (macro) + n_tokens); } - location_t lwm = sec.u (); - macro_locs.first = lwm - slurp->loc_deltas.second; dump () && dump ("Macro location lwm:%u", macro_locs.first); - if (propagated) spans.close (); @@ -17604,6 +17727,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader, /* No partitions present. */ partitions = nullptr; + write_init_maps (); + /* Find the set of decls we must write out. */ depset::hash table (DECL_NAMESPACE_BINDINGS (global_namespace)->size () * 8); /* Add the specializations before the writables, so that we can @@ -17911,7 +18036,7 @@ module_state::read_initial (cpp_reader *reader) gcc_assert (!from ()->is_frozen ()); /* Macro maps after the imports. */ - if (ok && have_locs && !read_macro_maps ()) + if (ok && have_locs && !read_macro_maps (config.macro_locs)) ok = false; /* Note whether there's an active initializer. */ diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-1.C b/gcc/testsuite/g++.dg/modules/loc-prune-1.C new file mode 100644 index 00000000000..6978e496f1b --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/loc-prune-1.C @@ -0,0 +1,19 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} } + +export module foo; +// { dg-module-cmi foo } +#define NOT 1 +#define YES 1 +#define AGAIN_NO (1 + 2) +#if NOT +int foo (int = YES) +{ + return AGAIN_NO; +} +#endif + +// { dg-final { scan-lang-dump { Macro maps:1} module } } +// { dg-final { scan-lang-dump { Macro:0 YES 1/1.2 locations } module } } +// { dg-final { scan-lang-dump { Ordinary:[0-9]* maps hwm:[0-9]* macro:1 maps 1 locs} module } } +// { dg-final { scan-lang-dump-not {Macro:. NOT } module } } +// { dg-final { scan-lang-dump-not {Macro:. AGAIN_NO } module } } diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-2.C b/gcc/testsuite/g++.dg/modules/loc-prune-2.C new file mode 100644 index 00000000000..fc4ed7825f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/loc-prune-2.C @@ -0,0 +1,14 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} } + +export module Eve; +// { dg-module-cmi Eve } + +#define BEGIN_NAMESPACE(X) inline namespace X { +#define END_NAMESPACE(X) } + +BEGIN_NAMESPACE (BOB) +void Alice (); +END_NAMESPACE (BOB) + +// { dg-final { scan-lang-dump { Macro maps:1} module } } +// { dg-final { scan-lang-dump { Macro:0 BEGIN_NAMESPACE 5/6.2 locations } module } } diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-3.C b/gcc/testsuite/g++.dg/modules/loc-prune-3.C new file mode 100644 index 00000000000..40e8aa68e1d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/loc-prune-3.C @@ -0,0 +1,16 @@ +// { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} } + +export module Eve; +// { dg-module-cmi Eve } + +#define BEGIN_NAMESPACE(X) inline namespace X { +#define END_NAMESPACE(X) } + +BEGIN_NAMESPACE (BOB) +namespace inner { +void Alice (); +} +END_NAMESPACE (BOB) + +// { dg-final { scan-lang-dump { Macro maps:1} module } } +// { dg-final { scan-lang-dump { Macro:0 BEGIN_NAMESPACE 5/6.2 locations } module } } diff --git a/gcc/testsuite/g++.dg/modules/pr98718_a.C b/gcc/testsuite/g++.dg/modules/pr98718_a.C index 0be5f905ee4..ebd95ea1f85 100644 --- a/gcc/testsuite/g++.dg/modules/pr98718_a.C +++ b/gcc/testsuite/g++.dg/modules/pr98718_a.C @@ -14,5 +14,5 @@ namespace std _GLIBCXX_VISIBILITY(default) export module hello:format; // { dg-module-cmi hello:format } -// { dg-final { scan-lang-dump { Ordinary:4 maps hwm:[0-9]* macro:1 maps lwm:214[0-9]*} module } } -// { dg-final { scan-lang-dump { Span:2 macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } } +// { dg-final { scan-lang-dump { Ordinary:4 maps hwm:[0-9]* macro:0 maps 0 locs} module } } +// { dg-final { scan-lang-dump-not { Macro:. _GLIBCXX_VISIBILITY} module } } diff --git a/gcc/testsuite/g++.dg/modules/pr98718_b.C b/gcc/testsuite/g++.dg/modules/pr98718_b.C index 50679c8d82c..6cb4698bad5 100644 --- a/gcc/testsuite/g++.dg/modules/pr98718_b.C +++ b/gcc/testsuite/g++.dg/modules/pr98718_b.C @@ -14,7 +14,5 @@ export module hello; export import :format; // { dg-module-cmi hello } -// { dg-final { scan-lang-dump {Macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } } -// { dg-final { scan-lang-dump { Ordinary:8 maps hwm:[0-9]* macro:2 maps lwm:214[0-9]*} module } } -// { dg-final { scan-lang-dump { Span:2 macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } } -// { dg-final { scan-lang-dump { Span:4 macro:1 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } } +// { dg-final { scan-lang-dump { Ordinary:8 maps hwm:[0-9]* macro:0 maps 0 locs} module } } +// { dg-final { scan-lang-dump-not { Macro:. _GLIBCXX_VISIBILITY} module } } -- 2.30.2