diff mbox series

c++: Post-pending redesign cleanup [PR 99170]

Message ID 7e2dda09-ecb0-aa92-1888-6ffcd45b6df8@acm.org
State New
Headers show
Series c++: Post-pending redesign cleanup [PR 99170] | expand

Commit Message

Nathan Sidwell March 4, 2021, 1:49 p.m. UTC
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 mbox series

Patch

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<tree, va_heap, vl_embed> *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<typename T>
-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<uintset> {
-    typedef unsigned compare_type;
-    typedef typename delete_ptr_hash<uintset>::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<traits> 
-  {
-    typedef typename traits::compare_type key_t;
-    typedef hash_table<traits> 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<typename T>
-bool
-uintset<T>::hash::add (typename uintset<T>::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<typename T>
-uintset<T> *
-uintset<T>::hash::create (typename uintset<T>::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<typename T>
-uintset<T> *
-uintset<T>::hash::get (typename uintset<T>::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<tree> attachset;
-static attachset::hash *attached_table;
+typedef hash_map<tree, auto_vec<tree>> 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);
     }