From 1dba47757c97526eff70d7622dc1405866435e8d Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 6 Oct 2017 14:19:23 +0000 Subject: [PATCH] [C++ PATCH] hash-table for extern-c fns. https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00376.html Use hash_table for extern "C" names * name-lookup.c (extern_c_fns): Use hash_table. (check_extern_c_conflict): Adjust. (c_linkage_bindings): Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253493 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/name-lookup.c | 50 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ef053a51cd4..7292fee2d67 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2017-10-06 Nathan Sidwell + Use hash_table for extern "C" names + * name-lookup.c (extern_c_fns): Use hash_table. + (check_extern_c_conflict): Adjust. + (c_linkage_bindings): Adjust. + Use hash_table for namespace bindings * cp-tree.h (struct named_decl_hash): New. (lang_decl_ns): Change type of bindings field. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 84f7381cc6f..fb86310c884 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2511,9 +2511,9 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, return decl; } -/* Map of identifiers to extern C functions (or LISTS thereof). */ +/* Table of identifiers to extern C functions (or LISTS thereof). */ -static GTY(()) hash_map *extern_c_fns; +static GTY(()) hash_table *extern_c_fns; /* DECL has C linkage. If we have an existing instance, make sure it has the same exception specification [7.5, 7.6]. If there's no @@ -2527,17 +2527,15 @@ check_extern_c_conflict (tree decl) return; if (!extern_c_fns) - extern_c_fns = hash_map::create_ggc (127); + extern_c_fns = hash_table::create_ggc (127); - bool existed; - tree *slot = &extern_c_fns->get_or_insert (DECL_NAME (decl), &existed); - if (!existed) - *slot = decl; - else + tree *slot = extern_c_fns + ->find_slot_with_hash (DECL_NAME (decl), + IDENTIFIER_HASH_VALUE (DECL_NAME (decl)), INSERT); + if (tree old = *slot) { - tree old = *slot; - if (TREE_CODE (old) == TREE_LIST) - old = TREE_VALUE (old); + if (TREE_CODE (old) == OVERLOAD) + old = OVL_FUNCTION (old); int mismatch = 0; if (DECL_CONTEXT (old) == DECL_CONTEXT (decl)) @@ -2563,9 +2561,24 @@ check_extern_c_conflict (tree decl) "due to different exception specifications"); } else - /* Chain it on for c_linkage_binding's use. */ - *slot = tree_cons (NULL_TREE, decl, *slot); + { + if (old == *slot) + /* The hash table expects OVERLOADS, so construct one with + OLD as both the function and the chain. This allocate + an excess OVERLOAD node, but it's rare to have multiple + extern "C" decls of the same name. And we save + complicating the hash table logic (which is used + elsewhere). */ + *slot = ovl_make (old, old); + + slot = &OVL_CHAIN (*slot); + + /* Chain it on for c_linkage_binding's use. */ + *slot = tree_cons (NULL_TREE, decl, *slot); + } } + else + *slot = decl; } /* Returns a list of C-linkage decls with the name NAME. Used in @@ -2575,8 +2588,15 @@ tree c_linkage_bindings (tree name) { if (extern_c_fns) - if (tree *slot = extern_c_fns->get (name)) - return *slot; + if (tree *slot = extern_c_fns + ->find_slot_with_hash (name, IDENTIFIER_HASH_VALUE (name), NO_INSERT)) + { + tree result = *slot; + if (TREE_CODE (result) == OVERLOAD) + result = OVL_CHAIN (result); + return result; + } + return NULL_TREE; } -- 2.11.4.GIT