From patchwork Thu Mar 4 13:49:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1447316 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Pal941TW; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Drsg82NCgz9sW8 for ; Fri, 5 Mar 2021 00:49:38 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5C7BD3AA981A; Thu, 4 Mar 2021 13:49:35 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by sourceware.org (Postfix) with ESMTPS id 995703AA9818 for ; Thu, 4 Mar 2021 13:49:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 995703AA9818 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qk1-x736.google.com with SMTP id n79so16127234qke.3 for ; Thu, 04 Mar 2021 05:49:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=mtzPuhfevYvmwNm9zYnVrD+aZRw35pKx5vGCkkS+BMc=; b=Pal941TWL2NlxX0Nd+OfL1juNcaCxp2EVUqnzHv7RVCZEYg8LhqdrMekG4PAdLaLxa bOxxEJjaI26BSGMElYUBaOx/16qjnSZLdeWTYfRthdpmyWbYB083Gk9XweGKWPJxJ0Z8 mn3+e9cIzuvCtPi91v9FHv0TW94VttBZ3HcR8J6z/V7JFKXYjPbmHzS+JbrdruplSTS5 0/Xeotc2dvqsJX6+jWc8A0fUHTveRpX0SrJvX4hhU8ksw/IKItV0JrbCDtES9LRQDuSW x95zXp2hIPr97KDKP5RgOJy4pW91C981XtiupPj6znfNKLr4E8vyiHUn6SWdN5BUwrts 77pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=mtzPuhfevYvmwNm9zYnVrD+aZRw35pKx5vGCkkS+BMc=; b=A2IcA5SYLcs+okHZTnzJ4Iu1menYntuq7NEcyDdk2i50jP/P5do7LJ1Tts6O+DCUBq 8mcAsF6fRltMveOU7jUbkdLNFCkfCLIZ01qvYqjWNHPn8eS2NqJLSfolC2FV0DJczPt3 t7UcaA+EZ9tqSAtOacDpQpo40hO+jpgOytw+WMUZ8iZ+bTkxnW8TlaBU2/S4iWDsAoa9 feu7DMKv86h0rT8YwgXwcS8a43XqwMQTktGyZUZG7qC7OlDjv3qqPDkqdqViajzfRxuf 8hNyXl1UgK9+L5Fz3FatjLaPDZnxR58bN3rLytWxqTbjci5CoFoKSFln0tN4USaQ2krK dofw== X-Gm-Message-State: AOAM533WHIPCejzUTbpk5BZYA5NGUfqWm/TPm+MJ1o6XjZIDaRYfBEi/ TU9JktjZOTs4p0olx7FE/N4= X-Google-Smtp-Source: ABdhPJzeo8rouhxVnl1LhyZybH+6FX+l6/XSZfppfnHnPkmUnVo5fOpq/2zkuom+ODVggDIz8Po+Gw== X-Received: by 2002:a05:620a:2216:: with SMTP id m22mr4155055qkh.73.1614865772228; Thu, 04 Mar 2021 05:49:32 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:c41b:3a5e:cd0a:9d1? ([2620:10d:c091:480::1:461b]) by smtp.googlemail.com with ESMTPSA id j20sm20057068qtl.36.2021.03.04.05.49.30 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 04 Mar 2021 05:49:31 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: Post-pending redesign cleanup [PR 99170] Message-ID: <7e2dda09-ecb0-aa92-1888-6ffcd45b6df8@acm.org> Date: Thu, 4 Mar 2021 08:49:30 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.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 autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" With pending entities reimplemented, the remaining use of uintset can just use a regular hash map -- I only used a uintset because it was there. So one adhoc hash-table/vector structure goes away. PR c++/99170 gcc/cp/ * module.cc (class uintset): Delete. (typedef attached_map_t): A hash map. (attached_table): Use attached_map_t. Adjust uses ... (trees_out::decl_value, trees_in::decl_value): ... here ... (trees_out::key_mergeable): ... here ... (trees_in::key_mergeable): ... here ... (maybe_attach_decl): ... here ... (direct_import): ... and here. diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc index 3ee71e5211f..31bbf9776dd 100644 --- c/gcc/cp/module.cc +++ w/gcc/cp/module.cc @@ -2697,167 +2697,11 @@ pending_map_t *pending_table; completed. */ vec *post_load_decls; -/* Values keyed to some unsigned integer. This is not GTY'd, so if - T is tree they must be reachable via some other path. */ - -template -class uintset { -public: - unsigned key; /* Entity index of the other entity. */ - - /* Payload. */ - unsigned allocp2 : 5; /* log(2) allocated pending */ - unsigned num : 27; /* Number of pending. */ - - /* Trailing array of values. */ - T values[1]; - -public: - /* Even with ctors, we're very pod-like. */ - uintset (unsigned uid) - : key (uid), allocp2 (0), num (0) - { - } - /* Copy constructor, which is exciting because of the trailing - array. */ - uintset (const uintset *from) - { - size_t size = (offsetof (uintset, values) - + sizeof (uintset::values) * from->num); - memmove (this, from, size); - if (from->num) - allocp2++; - } - -public: - struct traits : delete_ptr_hash { - typedef unsigned compare_type; - typedef typename delete_ptr_hash::value_type value_type; - - /* Hash and equality for compare_type. */ - inline static hashval_t hash (const compare_type k) - { - return hashval_t (k); - } - inline static hashval_t hash (const value_type v) - { - return hash (v->key); - } - - inline static bool equal (const value_type v, const compare_type k) - { - return v->key == k; - } - }; - -public: - class hash : public hash_table - { - typedef typename traits::compare_type key_t; - typedef hash_table parent; - - public: - hash (size_t size) - : parent (size) - { - } - ~hash () - { - } - - private: - uintset **find_slot (key_t key, insert_option insert) - { - return this->find_slot_with_hash (key, traits::hash (key), insert); - } - - public: - uintset *get (key_t key, bool extract = false); - bool add (key_t key, T value); - uintset *create (key_t key, unsigned num, T init = 0); - }; -}; - -/* Add VALUE to KEY's uintset, creating it if necessary. Returns true - if we created the uintset. */ - -template -bool -uintset::hash::add (typename uintset::hash::key_t key, T value) -{ - uintset **slot = this->find_slot (key, INSERT); - uintset *set = *slot; - bool is_new = !set; - - if (is_new || set->num == (1u << set->allocp2)) - { - if (set) - { - unsigned n = set->num * 2; - size_t new_size = (offsetof (uintset, values) - + sizeof (uintset (0u).values) * n); - uintset *new_set = new (::operator new (new_size)) uintset (set); - delete set; - set = new_set; - } - else - set = new (::operator new (sizeof (*set))) uintset (key); - *slot = set; - } - - set->values[set->num++] = value; - - return is_new; -} - -template -uintset * -uintset::hash::create (typename uintset::hash::key_t key, unsigned num, - T init) -{ - unsigned p2alloc = 0; - for (unsigned v = num; v != 1; v = (v >> 1) | (v & 1)) - p2alloc++; - - size_t new_size = (offsetof (uintset, values) - + (sizeof (uintset (0u).values) << p2alloc)); - uintset *set = new (::operator new (new_size)) uintset (key); - set->allocp2 = p2alloc; - set->num = num; - while (num--) - set->values[num] = init; - - uintset **slot = this->find_slot (key, INSERT); - gcc_checking_assert (!*slot); - *slot = set; - - return set; -} - -/* Locate KEY's uintset, potentially removing it from the hash table */ - -template -uintset * -uintset::hash::get (typename uintset::hash::key_t key, bool extract) -{ - uintset *res = NULL; - - if (uintset **slot = this->find_slot (key, NO_INSERT)) - { - res = *slot; - if (extract) - /* We need to remove the pendset without deleting it. */ - traits::mark_deleted (*slot); - } - - return res; -} - /* Some entities are attached to another entitity for ODR purposes. For example, at namespace scope, 'inline auto var = []{};', that lambda is attached to 'var', and follows its ODRness. */ -typedef uintset attachset; -static attachset::hash *attached_table; +typedef hash_map> attached_map_t; +static attached_map_t *attached_table; /********************************************************************/ /* Tree streaming. The tree streaming is very specific to the tree @@ -7865,13 +7709,13 @@ trees_out::decl_value (tree decl, depset *dep) && !is_key_order ()) { /* Stream the attached entities. */ - attachset *set = attached_table->get (DECL_UID (inner)); - unsigned num = set->num; + auto *attach_vec = attached_table->get (inner); + unsigned num = attach_vec->length (); if (streaming_p ()) u (num); for (unsigned ix = 0; ix != num; ix++) { - tree attached = set->values[ix]; + tree attached = (*attach_vec)[ix]; tree_node (attached); if (streaming_p ()) dump (dumper::MERGE) @@ -8169,13 +8013,14 @@ trees_in::decl_value () && DECL_MODULE_ATTACHMENTS_P (inner)) { /* Read and maybe install the attached entities. */ - attachset *set - = attached_table->get (DECL_UID (STRIP_TEMPLATE (existing))); + bool existed; + auto &set = attached_table->get_or_insert (STRIP_TEMPLATE (existing), + &existed); unsigned num = u (); - if (!is_new == !set) + if (is_new == existed) set_overrun (); if (is_new) - set = attached_table->create (DECL_UID (inner), num, NULL_TREE); + set.reserve (num); for (unsigned ix = 0; !get_overrun () && ix != num; ix++) { tree attached = tree_node (); @@ -8183,8 +8028,8 @@ trees_in::decl_value () && dump ("Read %d[%u] %s attached decl %N", tag, ix, is_new ? "new" : "matched", attached); if (is_new) - set->values[ix] = attached; - else if (set->values[ix] != attached) + set.quick_push (attached); + else if (set[ix] != attached) set_overrun (); } } @@ -10650,12 +10495,12 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, tree scope = LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR (TREE_TYPE (inner))); gcc_checking_assert (TREE_CODE (scope) == VAR_DECL); - attachset *root = attached_table->get (DECL_UID (scope)); - unsigned ix = root->num; + auto *root = attached_table->get (scope); + unsigned ix = root->length (); /* If we don't find it, we'll write a really big number that the reader will ignore. */ while (ix--) - if (root->values[ix] == inner) + if ((*root)[ix] == inner) break; /* Use the attached-to decl as the 'name'. */ @@ -10951,10 +10796,10 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, if (DECL_LANG_SPECIFIC (name) && VAR_OR_FUNCTION_DECL_P (name) && DECL_MODULE_ATTACHMENTS_P (name)) - if (attachset *set = attached_table->get (DECL_UID (name))) - if (key.index < set->num) + if (auto *set = attached_table->get (name)) + if (key.index < set->length ()) { - existing = set->values[key.index]; + existing = (*set)[key.index]; if (existing) { gcc_checking_assert @@ -18736,13 +18581,15 @@ maybe_attach_decl (tree ctx, tree decl) gcc_checking_assert (DECL_NAMESPACE_SCOPE_P (ctx)); if (!attached_table) - attached_table = new attachset::hash (EXPERIMENT (1, 400)); + attached_table = new attached_map_t (EXPERIMENT (1, 400)); - if (attached_table->add (DECL_UID (ctx), decl)) - { - retrofit_lang_decl (ctx); - DECL_MODULE_ATTACHMENTS_P (ctx) = true; - } + auto &vec = attached_table->get_or_insert (ctx); + if (!vec.length ()) + { + retrofit_lang_decl (ctx); + DECL_MODULE_ATTACHMENTS_P (ctx) = true; + } + vec.safe_push (decl); } /* Create the flat name string. It is simplest to have it handy. */ @@ -19051,7 +18898,7 @@ direct_import (module_state *import, cpp_reader *reader) if (import->loadedness < ML_LANGUAGE) { if (!attached_table) - attached_table = new attachset::hash (EXPERIMENT (1, 400)); + attached_table = new attached_map_t (EXPERIMENT (1, 400)); import->read_language (true); }