public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [00/13] Share hash traits between hash_table and hash_set
@ 2015-06-16  8:44 Richard Sandiford
  2015-06-16  8:46 ` [01/13] Move hash traits to their own header file Richard Sandiford
                   ` (13 more replies)
  0 siblings, 14 replies; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:44 UTC (permalink / raw)
  To: gcc-patches

When reviewing Mikhail's patch, I objected to another local "traits for
hashing a string" class.  But when I looked into it, I realised it really
is quite hard to unify the current hash traits.

At the moment we need separate traits classes for hash_table, hash_set
and hash_map.  I think that's a sign that we don't have the right
abstraction.

The aim of this series is to unify the traits for hash_table and hash_set.
If that's OK, I'll look at adding default hash_map traits for the common
case in which the deleted/empty information is stored in the key rather
than the value and where hash_table traits could be used.

There were various things I needed to change along the way:

- Our one generic hasher, pointer_hash, inherits from typed_noop_remove.
  In other words, it's specifically for cases where the pointer isn't
  freed when an entry is deleted.  That seems a bit arbitrary.  I think
  we should separate out the hashing and the removing aspects.

  Also, typed_noop_remove and typed_free_remove don't provide hashing typedefs,
  but the ggc equivalents ggc_hasher and ggc_cache_hasher do.  If we separate
  the hashing and removing aspects, the typedefs belong to the hashing side.

  This gives:

  "Hashers"
    - the only generic one is pointer_hash, but I'll follow up with a string
      one if the series is OK

  "Removers"
    - typed_noop_remove (as it exists now)
    - typed_free_remove (as it exists now)
    - ggc_remove (renamed from ggc_hasher, but without the typedefs)
    - ggc_cache_remove (renamed from ggc_cache_hasher, but without the typedefs)

  These are then combined to give:
    - nofree_ptr_hash
    - free_ptr_hash
    - ggc_ptr_hash
    - ggc_cache_ptr_hash

  For this particular case, it might be cleaner to use a vec<>-style
  parameter for the allocator (really just freer), e.g.

    hash_table<foo, da_gc>,
    hash_table<foo, da_heap>

  I did try that, but it felt unnatural in the cases where the remove()
  function frees some subobject as well.  Either you have a separate
  "allocator" that frees both the subdata and the entry itself, or you
  have a separate (hasher?) function for freeing subdata.

  Much of the awkwardness here is due to not having "proper" object
  construction and destruction.  If we had that, the memory management
  would be an integral part of the element type rather than being part
  of the traits.  So I don't think adding a template parameter for the
  element remover would necessarily be forward progress.

  Although we end up with four classes for pointers, and could have at
  least three for strings, most other types have only one.

- The traits have optional is_deleted, is_empty, mark_deleted and
  mark_empty methods, with a default behaviour suitable for pointer elements.
  The methods were probably optional because many pointer traits classes
  were implemented independently, but after the change above, they can
  instead inherit from pointer_hash (or from an allocator-specific
  derivation).  It then makes sense to put the handling of empty and
  deleted pointer entries in pointer_hash and remove the complicated
  code for handling defaults.

- handle_cache_entry is too tied to the internals.  The generic
  implementation is:

    static void
    handle_cache_entry (T &e)
    {
      if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
	e = static_cast<T> (HTAB_DELETED_ENTRY);
    }

  and a typical override looks like:

    void
    pad_type_hasher::handle_cache_entry (pad_type_hash *&t)
    {
      extern void gt_ggc_mx (pad_type_hash *&);
      if (t == HTAB_EMPTY_ENTRY || t == HTAB_DELETED_ENTRY)
	return;
      else if (ggc_marked_p (t->type))
	gt_ggc_mx (t);
      else
	t = static_cast<pad_type_hash *> (HTAB_DELETED_ENTRY);
    }

  In particular, this bypasses the normal remove() function, so we never
  update m_n_deleted.

  ISTM the (single) caller should be checking for empty and deleted items
  first and handling any deletion itself.  All we want to know from the
  traits is which of the following applies:

  - the entry should be deleted
  - the entry should be kept and needs to be marked
  - the entry should be kept and is already marked (an optimisation of
    the previous case).

  The patch adds a keep_cache_entry function to provide this information.

Series bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested
with config-list.mk.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [01/13] Move hash traits to their own header file
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
@ 2015-06-16  8:46 ` Richard Sandiford
  2015-06-23 20:53   ` Jeff Law
  2015-06-16  8:46 ` [02/13] Replace handle_cache_entry with new interface Richard Sandiford
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:46 UTC (permalink / raw)
  To: gcc-patches

This patch just moves the traits classes to their own header file,
hash-traits.h.

gcc/
	* hash-table.h: Include hash-traits.h.
	(typed_free_remove, typed_noop_remove, pointer_hash, ggc_hasher)
	(ggc_cache_hasher): Move to...
	* hash-traits.h: ...this new file.

Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-15 16:04:44.775663659 +0100
+++ gcc/hash-table.h	2015-06-15 16:04:44.771663705 +0100
@@ -81,7 +81,7 @@ Software Foundation; either version 3, o
    We compose this into a few steps.
 
       1. Decide on a removal policy for values stored in the table.
-         This header provides class templates for the two most common
+         hash-traits.h provides class templates for the two most common
          policies.
 
          * typed_free_remove implements the static 'remove' member function
@@ -202,6 +202,7 @@ #define TYPED_HASHTAB_H
 #include "hashtab.h"
 #include "inchash.h"
 #include "mem-stats-traits.h"
+#include "hash-traits.h"
 #include "hash-map-traits.h"
 
 template<typename, typename, typename> class hash_map;
@@ -238,143 +239,6 @@ xcallocator <Type>::data_free (Type *mem
 }
 
 
-/* Helpful type for removing with free.  */
-
-template <typename Type>
-struct typed_free_remove
-{
-  static inline void remove (Type *p);
-};
-
-
-/* Remove with free.  */
-
-template <typename Type>
-inline void
-typed_free_remove <Type>::remove (Type *p)
-{
-  free (p);
-}
-
-
-/* Helpful type for a no-op remove.  */
-
-template <typename Type>
-struct typed_noop_remove
-{
-  static inline void remove (Type *p);
-};
-
-
-/* Remove doing nothing.  */
-
-template <typename Type>
-inline void
-typed_noop_remove <Type>::remove (Type *p ATTRIBUTE_UNUSED)
-{
-}
-
-
-/* Pointer hash with a no-op remove method.  */
-
-template <typename Type>
-struct pointer_hash : typed_noop_remove <Type>
-{
-  typedef Type *value_type;
-  typedef Type *compare_type;
-
-  static inline hashval_t hash (const value_type &);
-
-  static inline bool equal (const value_type &existing,
-			    const compare_type &candidate);
-};
-
-template <typename Type>
-inline hashval_t
-pointer_hash <Type>::hash (const value_type &candidate)
-{
-  /* This is a really poor hash function, but it is what the current code uses,
-     so I am reusing it to avoid an additional axis in testing.  */
-  return (hashval_t) ((intptr_t)candidate >> 3);
-}
-
-template <typename Type>
-inline bool
-pointer_hash <Type>::equal (const value_type &existing,
-			   const compare_type &candidate)
-{
-  return existing == candidate;
-}
-
-/* Hasher for entry in gc memory.  */
-
-template<typename T>
-struct ggc_hasher
-{
-  typedef T value_type;
-  typedef T compare_type;
-
-  static void remove (T) {}
-
-  static void
-  ggc_mx (T p)
-  {
-    extern void gt_ggc_mx (T &);
-    gt_ggc_mx (p);
-  }
-
-  static void
-  pch_nx (T &p)
-  {
-  extern void gt_pch_nx (T &);
-  gt_pch_nx (p);
-  }
-
-  static void
-  pch_nx (T &p, gt_pointer_operator op, void *cookie)
-  {
-    op (&p, cookie);
-  }
-};
-
-/* Hasher for cache entry in gc memory.  */
-
-template<typename T>
-struct ggc_cache_hasher
-{
-  typedef T value_type;
-  typedef T compare_type;
-
-  static void remove (T &) {}
-
-  /* Entries are weakly held because this is for caches.  */
-
-  static void ggc_mx (T &) {}
-
-  static void
-  pch_nx (T &p)
-  {
-  extern void gt_pch_nx (T &);
-  gt_pch_nx (p);
-  }
-
-  static void
-  pch_nx (T &p, gt_pointer_operator op, void *cookie)
-  {
-    op (&p, cookie);
-  }
-
-  /* Clear out entries if they are about to be gc'd.  */
-
-  static void
-  handle_cache_entry (T &e)
-  {
-    if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
-      e = static_cast<T> (HTAB_DELETED_ENTRY);
-  }
-};
-
-
 /* Table of primes and their inversion information.  */
 
 struct prime_ent
Index: gcc/hash-traits.h
===================================================================
--- /dev/null	2015-06-02 17:27:28.541944012 +0100
+++ gcc/hash-traits.h	2015-06-15 16:04:44.771663705 +0100
@@ -0,0 +1,159 @@
+/* Traits for hashable types.
+   Copyright (C) 2014-2015 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef hash_traits_h
+#define hash_traits_h
+
+/* Helpful type for removing with free.  */
+
+template <typename Type>
+struct typed_free_remove
+{
+  static inline void remove (Type *p);
+};
+
+
+/* Remove with free.  */
+
+template <typename Type>
+inline void
+typed_free_remove <Type>::remove (Type *p)
+{
+  free (p);
+}
+
+
+/* Helpful type for a no-op remove.  */
+
+template <typename Type>
+struct typed_noop_remove
+{
+  static inline void remove (Type *p);
+};
+
+
+/* Remove doing nothing.  */
+
+template <typename Type>
+inline void
+typed_noop_remove <Type>::remove (Type *p ATTRIBUTE_UNUSED)
+{
+}
+
+
+/* Pointer hash with a no-op remove method.  */
+
+template <typename Type>
+struct pointer_hash : typed_noop_remove <Type>
+{
+  typedef Type *value_type;
+  typedef Type *compare_type;
+
+  static inline hashval_t hash (const value_type &);
+
+  static inline bool equal (const value_type &existing,
+			    const compare_type &candidate);
+};
+
+template <typename Type>
+inline hashval_t
+pointer_hash <Type>::hash (const value_type &candidate)
+{
+  /* This is a really poor hash function, but it is what the current code uses,
+     so I am reusing it to avoid an additional axis in testing.  */
+  return (hashval_t) ((intptr_t)candidate >> 3);
+}
+
+template <typename Type>
+inline bool
+pointer_hash <Type>::equal (const value_type &existing,
+			   const compare_type &candidate)
+{
+  return existing == candidate;
+}
+
+/* Hasher for entry in gc memory.  */
+
+template<typename T>
+struct ggc_hasher
+{
+  typedef T value_type;
+  typedef T compare_type;
+
+  static void remove (T) {}
+
+  static void
+  ggc_mx (T p)
+  {
+    extern void gt_ggc_mx (T &);
+    gt_ggc_mx (p);
+  }
+
+  static void
+  pch_nx (T &p)
+  {
+    extern void gt_pch_nx (T &);
+    gt_pch_nx (p);
+  }
+
+  static void
+  pch_nx (T &p, gt_pointer_operator op, void *cookie)
+  {
+    op (&p, cookie);
+  }
+};
+
+/* Hasher for cache entry in gc memory.  */
+
+template<typename T>
+struct ggc_cache_hasher
+{
+  typedef T value_type;
+  typedef T compare_type;
+
+  static void remove (T &) {}
+
+  /* Entries are weakly held because this is for caches.  */
+
+  static void ggc_mx (T &) {}
+
+  static void
+  pch_nx (T &p)
+  {
+    extern void gt_pch_nx (T &);
+    gt_pch_nx (p);
+  }
+
+  static void
+  pch_nx (T &p, gt_pointer_operator op, void *cookie)
+  {
+    op (&p, cookie);
+  }
+
+  /* Clear out entries if they are about to be gc'd.  */
+
+  static void
+  handle_cache_entry (T &e)
+  {
+    if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
+      e = static_cast<T> (HTAB_DELETED_ENTRY);
+  }
+};
+
+#endif

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [02/13] Replace handle_cache_entry with new interface
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
  2015-06-16  8:46 ` [01/13] Move hash traits to their own header file Richard Sandiford
@ 2015-06-16  8:46 ` Richard Sandiford
  2015-06-23 20:55   ` Jeff Law
  2015-07-01  9:41   ` Trevor Saunders
  2015-06-16  8:53 ` [03/13] Make ggc_cached_hasher inherit from ggc_hasher Richard Sandiford
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:46 UTC (permalink / raw)
  To: gcc-patches

As described in the covering note, this patch replaces handle_cache_entry
with a new function keep_cache_entry.  It also ensures that elements are
deleted using the proper function, so that m_n_deleted is updated.

I couldn't tell whether the unusual name of the function
("gt_cleare_cache") is deliberate or not, but I left it be.

gcc/ada/
	* gcc-interface/decl.c (value_annotation_hasher::handle_cache_entry):
	Delete.
	(value_annotation_hasher::keep_cache_entry): New function.
	* gcc-interface/utils.c (pad_type_hasher::handle_cache_entry):
	Delete.
	(pad_type_hasher::keep_cache_entry): New function.

gcc/
	* hash-table.h (hash_table): Add gt_cleare_cache as a friend.
	(gt_cleare_cache): Check here for deleted and empty entries.
	Replace handle_cache_entry with a call to keep_cache_entry.
	* hash-traits.h (ggc_cache_hasher::handle_cache_entry): Delete.
	(ggc_cache_hasher::keep_cache_entry): New function.
	* trans-mem.c (tm_wrapper_hasher::handle_cache_entry): Delete.
	(tm_wrapper_hasher::keep_cache_entry): New function.
	* tree.h (tree_decl_map_cache_hasher::handle_cache_entry): Delete.
	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
	* tree.c (type_cache_hasher::handle_cache_entry): Delete.
	(type_cache_hasher::keep_cache_entry): New function.
	(tree_vec_map_cache_hasher::handle_cache_entry): Delete.
	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
	* ubsan.c (tree_type_map_cache_hasher::handle_cache_entry): Delete.
	(tree_type_map_cache_hasher::keep_cache_entry): New function.
	* varasm.c (tm_clone_hasher::handle_cache_entry): Delete.
	(tm_clone_hasher::keep_cache_entry): New function.
	* config/i386/i386.c (dllimport_hasher::handle_cache_entry): Delete.
	(dllimport_hasher::keep_cache_entry): New function.

Index: gcc/ada/gcc-interface/decl.c
===================================================================
--- gcc/ada/gcc-interface/decl.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/ada/gcc-interface/decl.c	2015-06-15 16:04:47.363633798 +0100
@@ -149,16 +149,10 @@ struct value_annotation_hasher : ggc_cac
     return a->base.from == b->base.from;
   }
 
-  static void
-  handle_cache_entry (tree_int_map *&m)
+  static int
+  keep_cache_entry (tree_int_map *&m)
   {
-    extern void gt_ggc_mx (tree_int_map *&);
-    if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (m->base.from))
-      gt_ggc_mx (m);
-    else
-      m = static_cast<tree_int_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (m->base.from);
   }
 };
 
Index: gcc/ada/gcc-interface/utils.c
===================================================================
--- gcc/ada/gcc-interface/utils.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/ada/gcc-interface/utils.c	2015-06-15 16:04:47.359633844 +0100
@@ -243,7 +243,7 @@ struct pad_type_hasher : ggc_cache_hashe
 {
   static inline hashval_t hash (pad_type_hash *t) { return t->hash; }
   static bool equal (pad_type_hash *a, pad_type_hash *b);
-  static void handle_cache_entry (pad_type_hash *&);
+  static int keep_cache_entry (pad_type_hash *&);
 };
 
 static GTY ((cache))
@@ -1170,16 +1170,10 @@ make_type_from_size (tree type, tree siz
 
 /* See if the data pointed to by the hash table slot is marked.  */
 
-void
-pad_type_hasher::handle_cache_entry (pad_type_hash *&t)
+int
+pad_type_hasher::keep_cache_entry (pad_type_hash *&t)
 {
-  extern void gt_ggc_mx (pad_type_hash *&);
-  if (t == HTAB_EMPTY_ENTRY || t == HTAB_DELETED_ENTRY)
-    return;
-  else if (ggc_marked_p (t->type))
-    gt_ggc_mx (t);
-  else
-    t = static_cast<pad_type_hash *> (HTAB_DELETED_ENTRY);
+  return ggc_marked_p (t->type);
 }
 
 /* Return true iff the padded types are equivalent.  */
Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-15 16:04:47.379633614 +0100
+++ gcc/hash-table.h	2015-06-15 16:04:47.355633890 +0100
@@ -52,6 +52,16 @@ Software Foundation; either version 3, o
          individual elements of the table need to be disposed of (e.g.,
          when deleting a hash table, removing elements from the table, etc).
 
+	 - An optional static function named 'keep_cache_entry'.  This
+	 function is provided only for garbage-collected elements that
+	 are not marked by the normal gc mark pass.  It describes what
+	 what should happen to the element at the end of the gc mark phase.
+	 The return value should be:
+	   - 0 if the element should be deleted
+	   - 1 if the element should be kept and needs to be marked
+	   - -1 if the element should be kept and is already marked.
+	 Returning -1 rather than 1 is purely an optimization.
+
       3. The type of the hash table itself.  (More later.)
 
    In very special circumstances, users may need to know about a fourth type.
@@ -584,6 +594,8 @@ struct mark_empty_helper<Type *, Traits,
   template<typename T> friend void gt_pch_nx (hash_table<T> *,
 					      gt_pointer_operator, void *);
 
+  template<typename T> friend void gt_cleare_cache (hash_table<T> *);
+
   value_type *alloc_entries (size_t n CXX_MEM_STAT_INFO) const;
   value_type *find_empty_slot_for_expand (hashval_t);
   void expand ();
@@ -1131,12 +1143,20 @@ gt_pch_nx (hash_table<D> *h, gt_pointer_
 inline void
 gt_cleare_cache (hash_table<H> *h)
 {
+  extern void gt_ggc_mx (typename H::value_type &t);
+  typedef hash_table<H> table;
   if (!h)
     return;
 
-  for (typename hash_table<H>::iterator iter = h->begin (); iter != h->end ();
-       ++iter)
-    H::handle_cache_entry (*iter);
+  for (typename table::iterator iter = h->begin (); iter != h->end (); ++iter)
+    if (!table::is_empty (*iter) && !table::is_deleted (*iter))
+      {
+	int res = H::keep_cache_entry (*iter);
+	if (res == 0)
+	  h->clear_slot (&*iter);
+	else if (res != -1)
+	  gt_ggc_mx (*iter);
+      }
 }
 
 #endif /* TYPED_HASHTAB_H */
Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-15 16:04:47.379633614 +0100
+++ gcc/hash-traits.h	2015-06-15 16:04:47.355633890 +0100
@@ -146,13 +146,10 @@ struct ggc_cache_hasher
     op (&p, cookie);
   }
 
-  /* Clear out entries if they are about to be gc'd.  */
-
-  static void
-  handle_cache_entry (T &e)
+  static int
+  keep_cache_entry (T &e)
   {
-    if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
-      e = static_cast<T> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (e) ? -1 : 0;
   }
 };
 
Index: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/trans-mem.c	2015-06-15 16:04:47.359633844 +0100
@@ -483,17 +483,11 @@ struct tm_wrapper_hasher : ggc_cache_has
     return a->base.from == b->base.from;
   }
 
-  static void
-  handle_cache_entry (tree_map *&m)
-    {
-      extern void gt_ggc_mx (tree_map *&);
-      if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-	return;
-      else if (ggc_marked_p (m->base.from))
-	gt_ggc_mx (m);
-      else
-	m = static_cast<tree_map *> (HTAB_DELETED_ENTRY);
-    }
+  static int
+  keep_cache_entry (tree_map *&m)
+  {
+    return ggc_marked_p (m->base.from);
+  }
 };
 
 static GTY((cache)) hash_table<tm_wrapper_hasher> *tm_wrap_map;
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	2015-06-15 16:04:47.379633614 +0100
+++ gcc/tree.h	2015-06-15 16:04:47.375633660 +0100
@@ -4637,16 +4637,10 @@ struct tree_decl_map_cache_hasher : ggc_
     return tree_decl_map_eq (a, b);
   }
 
-  static void
-  handle_cache_entry (tree_decl_map *&m)
+  static int
+  keep_cache_entry (tree_decl_map *&m)
   {
-    extern void gt_ggc_mx (tree_decl_map *&);
-    if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (m->base.from))
-      gt_ggc_mx (m);
-    else
-      m = static_cast<tree_decl_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (m->base.from);
   }
 };
 
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/tree.c	2015-06-15 16:04:47.375633660 +0100
@@ -203,16 +203,10 @@ struct type_cache_hasher : ggc_cache_has
   static hashval_t hash (type_hash *t) { return t->hash; }
   static bool equal (type_hash *a, type_hash *b);
 
-  static void
-  handle_cache_entry (type_hash *&t)
+  static int
+  keep_cache_entry (type_hash *&t)
   {
-    extern void gt_ggc_mx (type_hash *&);
-    if (t == HTAB_DELETED_ENTRY || t == HTAB_EMPTY_ENTRY)
-      return;
-    else if (ggc_marked_p (t->type))
-      gt_ggc_mx (t);
-    else
-      t = static_cast<type_hash *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (t->type);
   }
 };
 
@@ -261,7 +255,7 @@ static GTY ((cache))
 static GTY ((cache))
      hash_table<tree_decl_map_cache_hasher> *value_expr_for_decl;
 
-     struct tree_vec_map_cache_hasher : ggc_cache_hasher<tree_vec_map *>
+struct tree_vec_map_cache_hasher : ggc_cache_hasher<tree_vec_map *>
 {
   static hashval_t hash (tree_vec_map *m) { return DECL_UID (m->base.from); }
 
@@ -271,16 +265,10 @@ static GTY ((cache))
     return a->base.from == b->base.from;
   }
 
-  static void
-  handle_cache_entry (tree_vec_map *&m)
+  static int
+  keep_cache_entry (tree_vec_map *&m)
   {
-    extern void gt_ggc_mx (tree_vec_map *&);
-    if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (m->base.from))
-      gt_ggc_mx (m);
-    else
-      m = static_cast<tree_vec_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (m->base.from);
   }
 };
 
Index: gcc/ubsan.c
===================================================================
--- gcc/ubsan.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/ubsan.c	2015-06-15 16:04:47.359633844 +0100
@@ -99,16 +99,10 @@ struct tree_type_map_cache_hasher : ggc_
     return a->type.from == b->type.from;
   }
 
-  static void
-  handle_cache_entry (tree_type_map *&m)
+  static int
+  keep_cache_entry (tree_type_map *&m)
   {
-    extern void gt_ggc_mx (tree_type_map *&);
-    if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (m->type.from))
-      gt_ggc_mx (m);
-    else
-      m = static_cast<tree_type_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (m->type.from);
   }
 };
 
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/varasm.c	2015-06-15 16:04:47.375633660 +0100
@@ -5797,16 +5797,10 @@ struct tm_clone_hasher : ggc_cache_hashe
   static hashval_t hash (tree_map *m) { return tree_map_hash (m); }
   static bool equal (tree_map *a, tree_map *b) { return tree_map_eq (a, b); }
 
-  static void
-  handle_cache_entry (tree_map *&e)
+  static int
+  keep_cache_entry (tree_map *&e)
   {
-    extern void gt_ggc_mx (tree_map *&);
-    if (e == HTAB_EMPTY_ENTRY || e == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (e->base.from))
-      gt_ggc_mx (e);
-    else
-      e = static_cast<tree_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (e->base.from);
   }
 };
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2015-06-15 16:04:47.379633614 +0100
+++ gcc/config/i386/i386.c	2015-06-15 16:04:47.371633705 +0100
@@ -14212,16 +14212,10 @@ struct dllimport_hasher : ggc_cache_hash
     return a->base.from == b->base.from;
   }
 
-  static void
-  handle_cache_entry (tree_map *&m)
+  static int
+  keep_cache_entry (tree_map *&m)
   {
-    extern void gt_ggc_mx (tree_map *&);
-    if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
-      return;
-    else if (ggc_marked_p (m->base.from))
-      gt_ggc_mx (m);
-    else
-      m = static_cast<tree_map *> (HTAB_DELETED_ENTRY);
+    return ggc_marked_p (m->base.from);
   }
 };
 

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [03/13] Make ggc_cached_hasher inherit from ggc_hasher
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
  2015-06-16  8:46 ` [01/13] Move hash traits to their own header file Richard Sandiford
  2015-06-16  8:46 ` [02/13] Replace handle_cache_entry with new interface Richard Sandiford
@ 2015-06-16  8:53 ` Richard Sandiford
  2015-06-23 20:56   ` Jeff Law
  2015-06-16  8:55 ` [05/13] Add nofree_ptr_hash Richard Sandiford
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:53 UTC (permalink / raw)
  To: gcc-patches

Most of ggc_cache_hasher is duplicated from ggc_hasher.  This patch
gets the same functionality via inheritance.  It also brings the
ggc_hasher functions in line with ggc_cache_hasher by making remove()
and ggc_mx() take references rather than pointers.  This seems more
consistent with the idea that elements don't need to be pointers and
could be some gc-ed structure instead.

gcc/
	* hash-traits.h (ggc_hasher::remove): Take a reference parameter.
	(ggc_hasher::ggc_mx): Likewise.
	(ggc_cache_hasher): Inherit from ggc_hasher.  Remove definitions
	that duplicate ggc_hasher ones.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 09:48:19.893867495 +0100
+++ gcc/hash-traits.h	2015-06-16 09:48:42.361611494 +0100
@@ -96,10 +96,10 @@ struct ggc_hasher
   typedef T value_type;
   typedef T compare_type;
 
-  static void remove (T) {}
+  static void remove (T &) {}
 
   static void
-  ggc_mx (T p)
+  ggc_mx (T &p)
   {
     extern void gt_ggc_mx (T &);
     gt_ggc_mx (p);
@@ -122,30 +122,11 @@ struct ggc_hasher
 /* Hasher for cache entry in gc memory.  */
 
 template<typename T>
-struct ggc_cache_hasher
+struct ggc_cache_hasher : ggc_hasher<T>
 {
-  typedef T value_type;
-  typedef T compare_type;
-
-  static void remove (T &) {}
-
   /* Entries are weakly held because this is for caches.  */
-
   static void ggc_mx (T &) {}
 
-  static void
-  pch_nx (T &p)
-  {
-    extern void gt_pch_nx (T &);
-    gt_pch_nx (p);
-  }
-
-  static void
-  pch_nx (T &p, gt_pointer_operator op, void *cookie)
-  {
-    op (&p, cookie);
-  }
-
   static int
   keep_cache_entry (T &e)
   {

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [05/13] Add nofree_ptr_hash
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (2 preceding siblings ...)
  2015-06-16  8:53 ` [03/13] Make ggc_cached_hasher inherit from ggc_hasher Richard Sandiford
@ 2015-06-16  8:55 ` Richard Sandiford
  2015-06-23 22:18   ` Jeff Law
  2015-06-16  8:55 ` [04/13] Add {mark,is}_{empty,deleted} to pointer_hash Richard Sandiford
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:55 UTC (permalink / raw)
  To: gcc-patches

This patch stops pointer_hash from inheriting typed_noop_remove and
instead creates a new class nofree_ptr_hash that inherits from both.
It then updates all uses of typed_noop_remove (which are all pointers)
and pointer_hash so that they use this new class instead.

gcc/
	* hash-table.h: Update comments.
	* hash-traits.h (pointer_hash): Don't inherit from typed_noop_remove.
	(nofree_ptr_hash): New class.
	* asan.c (asan_mem_ref_hasher): Inherit from nofree_ptr_hash rather
	than typed_noop_remove.  Remove redudant typedefs.
	* attribs.c (attribute_hasher): Likewise.
	* cfg.c (bb_copy_hasher): Likewise.
	* cselib.c (cselib_hasher): Likewise.
	* dse.c (invariant_group_base_hasher): Likewise.
	* dwarf2cfi.c (trace_info_hasher): Likewise.
	* dwarf2out.c (macinfo_entry_hasher): Likewise.
	(comdat_type_hasher, loc_list_hasher): Likewise.
	* gcse.c (pre_ldst_expr_hasher): Likewise.
	* genmatch.c (id_base): Likewise.
	* genrecog.c (test_pattern_hasher): Likewise.
	* gimple-ssa-strength-reduction.c (cand_chain_hasher): Likewise.
	* haifa-sched.c (delay_i1_hasher): Likewise.
	* hard-reg-set.h (simplifiable_subregs_hasher): Likewise.
	* ipa-icf.h (congruence_class_group_hash): Likewise.
	* ipa-profile.c (histogram_hash): Likewise.
	* ira-color.c (allocno_hard_regs_hasher): Likewise.
	* lto-streamer.h (string_slot_hasher): Likewise.
	* lto-streamer.c (tree_entry_hasher): Likewise.
	* plugin.c (event_hasher): Likewise.
	* postreload-gcse.c (expr_hasher): Likewise.
	* store-motion.c (st_expr_hasher): Likewise.
	* tree-sra.c (uid_decl_hasher): Likewise.
	* tree-ssa-coalesce.c (coalesce_pair_hasher): Likewise.
	(ssa_name_var_hash): Likewise.
	* tree-ssa-live.c (tree_int_map_hasher): Likewise.
	* tree-ssa-loop-im.c (mem_ref_hasher): Likewise.
	* tree-ssa-pre.c (pre_expr_d): Likewise.
	* tree-ssa-sccvn.c (vn_nary_op_hasher): Likewise.
	* vtable-verify.h (registration_hasher): Likewise.
	* vtable-verify.c (vtbl_map_hasher): Likewise.
	* config/arm/arm.c (libcall_hasher): Likewise.
	* config/i386/winnt.c (wrapped_symbol_hasher): Likewise.
	* config/ia64/ia64.c (bundle_state_hasher): Likewise.
	* config/sol2.c (comdat_entry_hasher): Likewise.
	* fold-const.c (fold): Use nofree_ptr_hash instead of pointer_hash.
	(print_fold_checksum, fold_checksum_tree): Likewise.
	(debug_fold_checksum, fold_build1_stat_loc): Likewise.
	(fold_build2_stat_loc, fold_build3_stat_loc): Likewise.
	(fold_build_call_array_loc): Likewise.
	* tree-ssa-ccp.c (gimple_htab): Likewise.
	* tree-browser.c (tree_upper_hasher): Inherit from nofree_ptr_hash
	rather than pointer_type.

gcc/c/
	* c-decl.c (detect_field_duplicates_hash): Use nofree_ptr_hash
	instead of pointer_hash.
	(detect_field_duplicates): Likewise.

gcc/cp/
	* class.c (fixed_type_or_null_ref_ht): Inherit from nofree_ptr_hash
	rather than pointer_hash.
	(fixed_type_or_null): Use nofree_ptr_hash instead of pointer_hash.
	* semantics.c (nrv_data): Likewise.
	* tree.c (verify_stmt_tree_r, verify_stmt_tree): Likewise.

gcc/java/
	* jcf-io.c (charstar_hash): Inherit from nofree_ptr_hash rather
	than typed_noop_remove.  Remove redudant typedefs.

gcc/lto/
	* lto.c (tree_scc_hasher): Inherit from nofree_ptr_hash rather
	than typed_noop_remove.  Remove redudant typedefs.

gcc/objc/
	* objc-act.c (decl_name_hash): Inherit from nofree_ptr_hash rather
	than typed_noop_remove.  Remove redudant typedefs.

libcc1/
	* plugin.cc (string_hasher): Inherit from nofree_ptr_hash rather
	than typed_noop_remove.  Remove redudant typedefs.
	(plugin_context): Use nofree_ptr_hash rather than pointer_hash.
	(plugin_context::mark): Likewise.

Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/hash-table.h	2015-06-16 09:53:47.322092878 +0100
@@ -118,12 +118,10 @@ Software Foundation; either version 3, o
    Suppose you want to put some_type into the hash table.  You could define
    the descriptor type as follows.
 
-      struct some_type_hasher : typed_noop_remove <some_type>
-      // Deriving from typed_noop_remove means that we get a 'remove' that does
+      struct some_type_hasher : nofree_ptr_hash <some_type>
+      // Deriving from nofree_ptr_hash means that we get a 'remove' that does
       // nothing.  This choice is good for raw values.
       {
-        typedef some_type value_type;
-        typedef some_type compare_type;
         static inline hashval_t hash (const value_type *);
         static inline bool equal (const value_type *, const compare_type *);
       };
Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/hash-traits.h	2015-06-16 09:53:47.322092878 +0100
@@ -57,10 +57,12 @@ typed_noop_remove <Type>::remove (Type *
 }
 
 
-/* Pointer hash with a no-op remove method.  */
+/* Pointer hasher based on pointer equality.  Other types of pointer hash
+   can inherit this and override the hash and equal functions with some
+   other form of equality (such as string equality).  */
 
 template <typename Type>
-struct pointer_hash : typed_noop_remove <Type>
+struct pointer_hash
 {
   typedef Type *value_type;
   typedef Type *compare_type;
@@ -165,4 +167,10 @@ struct ggc_cache_hasher : ggc_hasher<T>
   }
 };
 
+/* Traits for pointer elements that should not be freed when an element
+   is deleted.  */
+
+template <typename T>
+struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T> {};
+
 #endif
Index: gcc/asan.c
===================================================================
--- gcc/asan.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/asan.c	2015-06-16 09:53:47.306093064 +0100
@@ -428,12 +428,8 @@ asan_mem_ref_get_end (const asan_mem_ref
   return asan_mem_ref_get_end (ref->start, len);
 }
 
-struct asan_mem_ref_hasher
-  : typed_noop_remove <asan_mem_ref>
+struct asan_mem_ref_hasher : nofree_ptr_hash <asan_mem_ref>
 {
-  typedef asan_mem_ref *value_type;
-  typedef asan_mem_ref *compare_type;
-
   static inline hashval_t hash (const asan_mem_ref *);
   static inline bool equal (const asan_mem_ref *, const asan_mem_ref *);
 };
Index: gcc/attribs.c
===================================================================
--- gcc/attribs.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/attribs.c	2015-06-16 09:53:47.306093064 +0100
@@ -58,9 +58,8 @@ substring_hash (const char *str, int l)
 
 /* Used for attribute_hash.  */
 
-struct attribute_hasher : typed_noop_remove <attribute_spec>
+struct attribute_hasher : nofree_ptr_hash <attribute_spec>
 {
-  typedef attribute_spec *value_type;
   typedef substring *compare_type;
   static inline hashval_t hash (const attribute_spec *);
   static inline bool equal (const attribute_spec *, const substring *);
Index: gcc/cfg.c
===================================================================
--- gcc/cfg.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/cfg.c	2015-06-16 09:53:47.306093064 +0100
@@ -1025,10 +1025,8 @@ struct htab_bb_copy_original_entry
   int index2;
 };
 
-struct bb_copy_hasher : typed_noop_remove <htab_bb_copy_original_entry>
+struct bb_copy_hasher : nofree_ptr_hash <htab_bb_copy_original_entry>
 {
-  typedef htab_bb_copy_original_entry *value_type;
-  typedef htab_bb_copy_original_entry *compare_type;
   static inline hashval_t hash (const htab_bb_copy_original_entry *);
   static inline bool equal (const htab_bb_copy_original_entry *existing,
 			    const htab_bb_copy_original_entry * candidate);
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/cselib.c	2015-06-16 09:53:47.314092970 +0100
@@ -108,9 +108,8 @@ static rtx cselib_expand_value_rtx_1 (rt
      this involves walking the table entries for a given value and comparing
      the locations of the entries with the rtx we are looking up.  */
 
-struct cselib_hasher : typed_noop_remove <cselib_val>
+struct cselib_hasher : nofree_ptr_hash <cselib_val>
 {
-  typedef cselib_val *value_type;
   struct key {
     /* The rtx value and its mode (needed separately for constant
        integers).  */
Index: gcc/dse.c
===================================================================
--- gcc/dse.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/dse.c	2015-06-16 09:53:47.314092970 +0100
@@ -734,10 +734,8 @@ clear_alias_set_lookup (alias_set_type a
 /* Hashtable callbacks for maintaining the "bases" field of
    store_group_info, given that the addresses are function invariants.  */
 
-struct invariant_group_base_hasher : typed_noop_remove <group_info>
+struct invariant_group_base_hasher : nofree_ptr_hash <group_info>
 {
-  typedef group_info *value_type;
-  typedef group_info *compare_type;
   static inline hashval_t hash (const group_info *);
   static inline bool equal (const group_info *, const group_info *);
 };
Index: gcc/dwarf2cfi.c
===================================================================
--- gcc/dwarf2cfi.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/dwarf2cfi.c	2015-06-16 09:53:47.314092970 +0100
@@ -168,10 +168,8 @@ typedef dw_trace_info *dw_trace_info_ref
 
 /* Hashtable helpers.  */
 
-struct trace_info_hasher : typed_noop_remove <dw_trace_info>
+struct trace_info_hasher : nofree_ptr_hash <dw_trace_info>
 {
-  typedef dw_trace_info *value_type;
-  typedef dw_trace_info *compare_type;
   static inline hashval_t hash (const dw_trace_info *);
   static inline bool equal (const dw_trace_info *, const dw_trace_info *);
 };
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/dwarf2out.c	2015-06-16 09:53:47.318092924 +0100
@@ -22784,10 +22784,8 @@ dwarf2out_undef (unsigned int lineno ATT
 
 /* Helpers to manipulate hash table of CUs.  */
 
-struct macinfo_entry_hasher : typed_noop_remove <macinfo_entry>
+struct macinfo_entry_hasher : nofree_ptr_hash <macinfo_entry>
 {
-  typedef macinfo_entry *value_type;
-  typedef macinfo_entry *compare_type;
   static inline hashval_t hash (const macinfo_entry *);
   static inline bool equal (const macinfo_entry *, const macinfo_entry *);
 };
@@ -23876,10 +23874,8 @@ file_table_relative_p (dwarf_file_data *
 
 /* Helpers to manipulate hash table of comdat type units.  */
 
-struct comdat_type_hasher : typed_noop_remove <comdat_type_node>
+struct comdat_type_hasher : nofree_ptr_hash <comdat_type_node>
 {
-  typedef comdat_type_node *value_type;
-  typedef comdat_type_node *compare_type;
   static inline hashval_t hash (const comdat_type_node *);
   static inline bool equal (const comdat_type_node *, const comdat_type_node *);
 };
@@ -24989,10 +24985,8 @@ compare_locs (dw_loc_descr_ref x, dw_loc
 
 /* Hashtable helpers.  */
 
-struct loc_list_hasher : typed_noop_remove <dw_loc_list_struct>
+struct loc_list_hasher : nofree_ptr_hash <dw_loc_list_struct>
 {
-  typedef dw_loc_list_struct *value_type;
-  typedef dw_loc_list_struct *compare_type;
   static inline hashval_t hash (const dw_loc_list_struct *);
   static inline bool equal (const dw_loc_list_struct *,
 			    const dw_loc_list_struct *);
Index: gcc/gcse.c
===================================================================
--- gcc/gcse.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/gcse.c	2015-06-16 09:53:47.318092924 +0100
@@ -375,9 +375,8 @@ struct ls_expr
 /* Head of the list of load/store memory refs.  */
 static struct ls_expr * pre_ldst_mems = NULL;
 
-struct pre_ldst_expr_hasher : typed_noop_remove <ls_expr>
+struct pre_ldst_expr_hasher : nofree_ptr_hash <ls_expr>
 {
-  typedef ls_expr *value_type;
   typedef value_type compare_type;
   static inline hashval_t hash (const ls_expr *);
   static inline bool equal (const ls_expr *, const ls_expr *);
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/genmatch.c	2015-06-16 09:53:47.318092924 +0100
@@ -175,7 +175,7 @@ enum built_in_function {
 
 /* Base class for all identifiers the parser knows.  */
 
-struct id_base : typed_noop_remove<id_base>
+struct id_base : nofree_ptr_hash<id_base>
 {
   enum id_kind { CODE, FN, PREDICATE, USER } kind;
 
@@ -186,8 +186,6 @@ struct id_base : typed_noop_remove<id_ba
   const char *id;
 
   /* hash_table support.  */
-  typedef id_base *value_type;
-  typedef id_base *compare_type;
   static inline hashval_t hash (const id_base *);
   static inline int equal (const id_base *, const id_base *);
 };
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/genrecog.c	2015-06-16 09:53:47.322092878 +0100
@@ -2519,10 +2519,8 @@ merge_relative_positions (position **roo
 
 /* A hasher of states that treats two states as "equal" if they might be
    merged (but trying to be more discriminating than "return true").  */
-struct test_pattern_hasher : typed_noop_remove <merge_state_info>
+struct test_pattern_hasher : nofree_ptr_hash <merge_state_info>
 {
-  typedef merge_state_info *value_type;
-  typedef merge_state_info *compare_type;
   static inline hashval_t hash (const value_type &);
   static inline bool equal (const value_type &, const compare_type &);
 };
Index: gcc/gimple-ssa-strength-reduction.c
===================================================================
--- gcc/gimple-ssa-strength-reduction.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/gimple-ssa-strength-reduction.c	2015-06-16 09:53:47.322092878 +0100
@@ -426,10 +426,8 @@ lookup_cand (cand_idx idx)
 
 /* Helper for hashing a candidate chain header.  */
 
-struct cand_chain_hasher : typed_noop_remove <cand_chain>
+struct cand_chain_hasher : nofree_ptr_hash <cand_chain>
 {
-  typedef cand_chain *value_type;
-  typedef cand_chain *compare_type;
   static inline hashval_t hash (const cand_chain *);
   static inline bool equal (const cand_chain *, const cand_chain *);
 };
Index: gcc/haifa-sched.c
===================================================================
--- gcc/haifa-sched.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/haifa-sched.c	2015-06-16 09:53:47.322092878 +0100
@@ -614,9 +614,8 @@ struct delay_pair
 
 /* Helpers for delay hashing.  */
 
-struct delay_i1_hasher : typed_noop_remove <delay_pair>
+struct delay_i1_hasher : nofree_ptr_hash <delay_pair>
 {
-  typedef delay_pair *value_type;
   typedef void *compare_type;
   static inline hashval_t hash (const delay_pair *);
   static inline bool equal (const delay_pair *, const void *);
Index: gcc/hard-reg-set.h
===================================================================
--- gcc/hard-reg-set.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/hard-reg-set.h	2015-06-16 09:53:47.322092878 +0100
@@ -616,9 +616,8 @@ #define EXECUTE_IF_SET_IN_HARD_REG_SET(S
 struct simplifiable_subreg;
 struct subreg_shape;
 
-struct simplifiable_subregs_hasher : typed_noop_remove <simplifiable_subreg>
+struct simplifiable_subregs_hasher : nofree_ptr_hash <simplifiable_subreg>
 {
-  typedef simplifiable_subreg *value_type;
   typedef const subreg_shape *compare_type;
 
   static inline hashval_t hash (const simplifiable_subreg *);
Index: gcc/ipa-icf.h
===================================================================
--- gcc/ipa-icf.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/ipa-icf.h	2015-06-16 09:53:47.322092878 +0100
@@ -445,11 +445,8 @@ struct congruence_class_group
 };
 
 /* Congruence class set structure.  */
-struct congruence_class_group_hash: typed_noop_remove <congruence_class_group>
+struct congruence_class_group_hash : nofree_ptr_hash <congruence_class_group>
 {
-  typedef congruence_class_group *value_type;
-  typedef congruence_class_group *compare_type;
-
   static inline hashval_t hash (const congruence_class_group *item)
   {
     return item->hash;
Index: gcc/ipa-profile.c
===================================================================
--- gcc/ipa-profile.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/ipa-profile.c	2015-06-16 09:53:47.322092878 +0100
@@ -105,10 +105,8 @@ struct histogram_entry
 
 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR.  */
 
-struct histogram_hash : typed_noop_remove <histogram_entry>
+struct histogram_hash : nofree_ptr_hash <histogram_entry>
 {
-  typedef histogram_entry *value_type;
-  typedef histogram_entry *compare_type;
   static inline hashval_t hash (const histogram_entry *);
   static inline int equal (const histogram_entry *, const histogram_entry *);
 };
Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/ira-color.c	2015-06-16 09:53:47.322092878 +0100
@@ -229,10 +229,8 @@ #define SORTGT(x,y) (((x) > (y)) ? 1 : -
 /* Vector of unique allocno hard registers.  */
 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
 
-struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
+struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
 {
-  typedef allocno_hard_regs *value_type;
-  typedef allocno_hard_regs *compare_type;
   static inline hashval_t hash (const allocno_hard_regs *);
   static inline bool equal (const allocno_hard_regs *,
 			    const allocno_hard_regs *);
Index: gcc/lto-streamer.h
===================================================================
--- gcc/lto-streamer.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/lto-streamer.h	2015-06-16 09:53:47.326092832 +0100
@@ -652,10 +652,8 @@ struct string_slot
 
 /* Hashtable helpers.  */
 
-struct string_slot_hasher : typed_noop_remove <string_slot>
+struct string_slot_hasher : nofree_ptr_hash <string_slot>
 {
-  typedef string_slot *value_type;
-  typedef string_slot *compare_type;
   static inline hashval_t hash (const string_slot *);
   static inline bool equal (const string_slot *, const string_slot *);
 };
Index: gcc/lto-streamer.c
===================================================================
--- gcc/lto-streamer.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/lto-streamer.c	2015-06-16 09:53:47.326092832 +0100
@@ -284,10 +284,8 @@ struct tree_hash_entry
   intptr_t value;
 };
 
-struct tree_entry_hasher : typed_noop_remove <tree_hash_entry>
+struct tree_entry_hasher : nofree_ptr_hash <tree_hash_entry>
 {
-  typedef tree_hash_entry value_type;
-  typedef tree_hash_entry compare_type;
   static inline hashval_t hash (const value_type *);
   static inline bool equal (const value_type *, const compare_type *);
 };
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/plugin.c	2015-06-16 09:53:47.326092832 +0100
@@ -56,10 +56,8 @@ const char **plugin_event_name = plugin_
 
 /* Event hashtable helpers.  */
 
-struct event_hasher : typed_noop_remove <const char *>
+struct event_hasher : nofree_ptr_hash <const char *>
 {
-  typedef const char **value_type;
-  typedef const char **compare_type;
   static inline hashval_t hash (const char **);
   static inline bool equal (const char **, const char **);
 };
Index: gcc/postreload-gcse.c
===================================================================
--- gcc/postreload-gcse.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/postreload-gcse.c	2015-06-16 09:53:47.326092832 +0100
@@ -121,10 +121,8 @@ struct expr
 
 /* Hashtable helpers.  */
 
-struct expr_hasher : typed_noop_remove <expr>
+struct expr_hasher : nofree_ptr_hash <expr>
 {
-  typedef expr *value_type;
-  typedef expr *compare_type;
   static inline hashval_t hash (const expr *);
   static inline bool equal (const expr *, const expr *);
 };
Index: gcc/store-motion.c
===================================================================
--- gcc/store-motion.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/store-motion.c	2015-06-16 09:53:47.326092832 +0100
@@ -123,10 +123,8 @@ static struct st_expr * store_motion_mem
 
 /* Hashtable helpers.  */
 
-struct st_expr_hasher : typed_noop_remove <st_expr>
+struct st_expr_hasher : nofree_ptr_hash <st_expr>
 {
-  typedef st_expr *value_type;
-  typedef st_expr *compare_type;
   static inline hashval_t hash (const st_expr *);
   static inline bool equal (const st_expr *, const st_expr *);
 };
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-sra.c	2015-06-16 09:53:47.326092832 +0100
@@ -343,10 +343,8 @@ pool_allocator<assign_link> assign_link:
 
 /* Candidate hash table helpers.  */
 
-struct uid_decl_hasher : typed_noop_remove <tree_node>
+struct uid_decl_hasher : nofree_ptr_hash <tree_node>
 {
-  typedef tree_node *value_type;
-  typedef tree_node *compare_type;
   static inline hashval_t hash (const tree_node *);
   static inline bool equal (const tree_node *, const tree_node *);
 };
Index: gcc/tree-ssa-coalesce.c
===================================================================
--- gcc/tree-ssa-coalesce.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-coalesce.c	2015-06-16 09:53:47.326092832 +0100
@@ -72,10 +72,8 @@ typedef const struct coalesce_pair *cons
 
 /* Coalesce pair hashtable helpers.  */
 
-struct coalesce_pair_hasher : typed_noop_remove <coalesce_pair>
+struct coalesce_pair_hasher : nofree_ptr_hash <coalesce_pair>
 {
-  typedef coalesce_pair *value_type;
-  typedef coalesce_pair *compare_type;
   static inline hashval_t hash (const coalesce_pair *);
   static inline bool equal (const coalesce_pair *, const coalesce_pair *);
 };
@@ -1242,10 +1240,8 @@ coalesce_partitions (var_map map, ssa_co
 
 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR.  */
 
-struct ssa_name_var_hash : typed_noop_remove <tree_node>
+struct ssa_name_var_hash : nofree_ptr_hash <tree_node>
 {
-  typedef union tree_node *value_type;
-  typedef union tree_node *compare_type;
   static inline hashval_t hash (const tree_node *);
   static inline int equal (const tree_node *, const tree_node *);
 };
Index: gcc/tree-ssa-live.c
===================================================================
--- gcc/tree-ssa-live.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-live.c	2015-06-16 09:53:47.326092832 +0100
@@ -91,10 +91,8 @@ static void  verify_live_on_entry (tree_
 
 /* Hashtable helpers.  */
 
-struct tree_int_map_hasher : typed_noop_remove <tree_int_map>
+struct tree_int_map_hasher : nofree_ptr_hash <tree_int_map>
 {
-  typedef tree_int_map *value_type;
-  typedef tree_int_map *compare_type;
   static inline hashval_t hash (const tree_int_map *);
   static inline bool equal (const tree_int_map *, const tree_int_map *);
 };
Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-loop-im.c	2015-06-16 09:53:47.330092785 +0100
@@ -162,9 +162,8 @@ #define LOOP_DEP_BIT(loopnum, storedp) (
 
 /* Mem_ref hashtable helpers.  */
 
-struct mem_ref_hasher : typed_noop_remove <im_mem_ref>
+struct mem_ref_hasher : nofree_ptr_hash <im_mem_ref>
 {
-  typedef im_mem_ref *value_type;
   typedef tree_node *compare_type;
   static inline hashval_t hash (const im_mem_ref *);
   static inline bool equal (const im_mem_ref *, const tree_node *);
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-pre.c	2015-06-16 09:53:47.330092785 +0100
@@ -209,15 +209,13 @@ typedef union pre_expr_union_d
   vn_reference_t reference;
 } pre_expr_union;
 
-typedef struct pre_expr_d : typed_noop_remove <pre_expr_d>
+typedef struct pre_expr_d : nofree_ptr_hash <pre_expr_d>
 {
   enum pre_expr_kind kind;
   unsigned int id;
   pre_expr_union u;
 
   /* hash_table support.  */
-  typedef pre_expr_d *value_type;
-  typedef pre_expr_d *compare_type;
   static inline hashval_t hash (const pre_expr_d *);
   static inline int equal (const pre_expr_d *, const pre_expr_d *);
 } *pre_expr;
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-sccvn.c	2015-06-16 09:53:47.330092785 +0100
@@ -139,9 +139,8 @@ the Free Software Foundation; either ver
 
 /* vn_nary_op hashtable helpers.  */
 
-struct vn_nary_op_hasher : typed_noop_remove <vn_nary_op_s>
+struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s>
 {
-  typedef vn_nary_op_s *value_type;
   typedef vn_nary_op_s *compare_type;
   static inline hashval_t hash (const vn_nary_op_s *);
   static inline bool equal (const vn_nary_op_s *, const vn_nary_op_s *);
Index: gcc/vtable-verify.h
===================================================================
--- gcc/vtable-verify.h	2015-06-16 09:53:47.338092692 +0100
+++ gcc/vtable-verify.h	2015-06-16 09:53:47.330092785 +0100
@@ -55,10 +55,8 @@ struct vtable_registration
   vec<unsigned> offsets;       /* The offsets array.                        */
 };
 
-struct registration_hasher : typed_noop_remove <struct vtable_registration>
+struct registration_hasher : nofree_ptr_hash <struct vtable_registration>
 {
-  typedef struct vtable_registration *value_type;
-  typedef struct vtable_registration *compare_type;
   static inline hashval_t hash (const vtable_registration *);
   static inline bool equal (const vtable_registration *,
 			    const vtable_registration *);
Index: gcc/vtable-verify.c
===================================================================
--- gcc/vtable-verify.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/vtable-verify.c	2015-06-16 09:53:47.330092785 +0100
@@ -285,10 +285,8 @@ registration_hasher::equal (const vtable
 
 /* Hashtable definition and functions for vtbl_map_hash.  */
 
-struct vtbl_map_hasher : typed_noop_remove <struct vtbl_map_node>
+struct vtbl_map_hasher : nofree_ptr_hash <struct vtbl_map_node>
 {
-  typedef struct vtbl_map_node *value_type;
-  typedef struct vtbl_map_node *compare_type;
   static inline hashval_t hash (const vtbl_map_node *);
   static inline bool equal (const vtbl_map_node *, const vtbl_map_node *);
 };
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/config/arm/arm.c	2015-06-16 09:53:47.314092970 +0100
@@ -5028,10 +5028,8 @@ arm_function_value(const_tree type, cons
 
 /* libcall hashtable helpers.  */
 
-struct libcall_hasher : typed_noop_remove <rtx_def>
+struct libcall_hasher : nofree_ptr_hash <const rtx_def>
 {
-  typedef const rtx_def *value_type;
-  typedef const rtx_def *compare_type;
   static inline hashval_t hash (const rtx_def *);
   static inline bool equal (const rtx_def *, const rtx_def *);
   static inline void remove (rtx_def *);
Index: gcc/config/i386/winnt.c
===================================================================
--- gcc/config/i386/winnt.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/config/i386/winnt.c	2015-06-16 09:53:47.314092970 +0100
@@ -711,10 +711,8 @@ i386_pe_record_stub (const char *name)
 
 /* Hashtable helpers.  */
 
-struct wrapped_symbol_hasher : typed_noop_remove <char>
+struct wrapped_symbol_hasher : nofree_ptr_hash <const char>
 {
-  typedef const char *value_type;
-  typedef const char *compare_type;
   static inline hashval_t hash (const char *);
   static inline bool equal (const char *, const char *);
   static inline void remove (const char *);
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/config/ia64/ia64.c	2015-06-16 09:53:47.314092970 +0100
@@ -8581,10 +8581,8 @@ finish_bundle_states (void)
 
 /* Hashtable helpers.  */
 
-struct bundle_state_hasher : typed_noop_remove <bundle_state>
+struct bundle_state_hasher : nofree_ptr_hash <bundle_state>
 {
-  typedef bundle_state *value_type;
-  typedef bundle_state *compare_type;
   static inline hashval_t hash (const bundle_state *);
   static inline bool equal (const bundle_state *, const bundle_state *);
 };
Index: gcc/config/sol2.c
===================================================================
--- gcc/config/sol2.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/config/sol2.c	2015-06-16 09:53:47.314092970 +0100
@@ -173,10 +173,8 @@ typedef struct comdat_entry
 
 /* Helpers for maintaining solaris_comdat_htab.  */
 
-struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
+struct comdat_entry_hasher : nofree_ptr_hash <comdat_entry>
 {
-  typedef comdat_entry *value_type;
-  typedef comdat_entry *compare_type;
   static inline hashval_t hash (const comdat_entry *);
   static inline bool equal (const comdat_entry *, const comdat_entry *);
   static inline void remove (comdat_entry *);
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/fold-const.c	2015-06-16 09:53:47.334092739 +0100
@@ -13970,7 +13970,7 @@ fold (tree expr)
 #undef fold
 
 static void fold_checksum_tree (const_tree, struct md5_ctx *,
-				hash_table<pointer_hash<const tree_node> > *);
+				hash_table<nofree_ptr_hash<const tree_node> > *);
 static void fold_check_failed (const_tree, const_tree);
 void print_fold_checksum (const_tree);
 
@@ -13984,7 +13984,7 @@ fold (tree expr)
   tree ret;
   struct md5_ctx ctx;
   unsigned char checksum_before[16], checksum_after[16];
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (expr, &ctx, &ht);
@@ -14008,7 +14008,7 @@ print_fold_checksum (const_tree expr)
 {
   struct md5_ctx ctx;
   unsigned char checksum[16], cnt;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (expr, &ctx, &ht);
@@ -14026,7 +14026,7 @@ fold_check_failed (const_tree expr ATTRI
 
 static void
 fold_checksum_tree (const_tree expr, struct md5_ctx *ctx,
-		    hash_table<pointer_hash <const tree_node> > *ht)
+		    hash_table<nofree_ptr_hash <const tree_node> > *ht)
 {
   const tree_node **slot;
   enum tree_code code;
@@ -14187,7 +14187,7 @@ debug_fold_checksum (const_tree t)
   int i;
   unsigned char checksum[16];
   struct md5_ctx ctx;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (t, &ctx, &ht);
@@ -14215,7 +14215,7 @@ fold_build1_stat_loc (location_t loc,
 #ifdef ENABLE_FOLD_CHECKING
   unsigned char checksum_before[16], checksum_after[16];
   struct md5_ctx ctx;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (op0, &ctx, &ht);
@@ -14256,7 +14256,7 @@ fold_build2_stat_loc (location_t loc,
 		checksum_after_op0[16],
 		checksum_after_op1[16];
   struct md5_ctx ctx;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (op0, &ctx, &ht);
@@ -14310,7 +14310,7 @@ fold_build3_stat_loc (location_t loc, en
 		checksum_after_op1[16],
 		checksum_after_op2[16];
   struct md5_ctx ctx;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
 
   md5_init_ctx (&ctx);
   fold_checksum_tree (op0, &ctx, &ht);
@@ -14376,7 +14376,7 @@ fold_build_call_array_loc (location_t lo
 		checksum_after_fn[16],
 		checksum_after_arglist[16];
   struct md5_ctx ctx;
-  hash_table<pointer_hash<const tree_node> > ht (32);
+  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
   int i;
 
   md5_init_ctx (&ctx);
Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-ssa-ccp.c	2015-06-16 09:53:47.338092692 +0100
@@ -1975,7 +1975,7 @@ evaluate_stmt (gimple stmt)
   return val;
 }
 
-typedef hash_table<pointer_hash<gimple_statement_base> > gimple_htab;
+typedef hash_table<nofree_ptr_hash<gimple_statement_base> > gimple_htab;
 
 /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before
    each matching BUILT_IN_STACK_RESTORE.  Mark visited phis in VISITED.  */
Index: gcc/tree-browser.c
===================================================================
--- gcc/tree-browser.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/tree-browser.c	2015-06-16 09:53:47.338092692 +0100
@@ -105,7 +105,7 @@ static tree TB_history_prev (void);
 void browse_tree (tree);
 
 /* Hashtable helpers.  */
-struct tree_upper_hasher : pointer_hash<tree_node>
+struct tree_upper_hasher : nofree_ptr_hash<tree_node>
 {
   static inline bool equal (const value_type &, const compare_type &);
 };
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/c/c-decl.c	2015-06-16 09:53:47.330092785 +0100
@@ -7407,7 +7407,7 @@ is_duplicate_field (tree x, tree y)
 
 static void
 detect_field_duplicates_hash (tree fieldlist,
-			      hash_table<pointer_hash <tree_node> > *htab)
+			      hash_table<nofree_ptr_hash <tree_node> > *htab)
 {
   tree x, y;
   tree_node **slot;
@@ -7507,7 +7507,7 @@ detect_field_duplicates (tree fieldlist)
     }
   else
     {
-      hash_table<pointer_hash <tree_node> > htab (37);
+      hash_table<nofree_ptr_hash <tree_node> > htab (37);
       detect_field_duplicates_hash (fieldlist, &htab);
     }
 }
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/cp/class.c	2015-06-16 09:53:47.334092739 +0100
@@ -6919,7 +6919,7 @@ finish_struct (tree t, tree attributes)
 }
 \f
 /* Hash table to avoid endless recursion when handling references.  */
-static hash_table<pointer_hash<tree_node> > *fixed_type_or_null_ref_ht;
+static hash_table<nofree_ptr_hash<tree_node> > *fixed_type_or_null_ref_ht;
 
 /* Return the dynamic type of INSTANCE, if known.
    Used to determine whether the virtual function table is needed
@@ -7038,7 +7038,7 @@ #define RECUR(T) fixed_type_or_null((T),
 	  /* We only need one hash table because it is always left empty.  */
 	  if (!fixed_type_or_null_ref_ht)
 	    fixed_type_or_null_ref_ht
-	      = new hash_table<pointer_hash<tree_node> > (37); 
+	      = new hash_table<nofree_ptr_hash<tree_node> > (37);
 
 	  /* Reference variables should be references to objects.  */
 	  if (nonnull)
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/cp/semantics.c	2015-06-16 09:53:47.334092739 +0100
@@ -4127,7 +4127,7 @@ struct nrv_data
 
   tree var;
   tree result;
-  hash_table<pointer_hash <tree_node> > visited;
+  hash_table<nofree_ptr_hash <tree_node> > visited;
 };
 
 /* Helper function for walk_tree, used by finalize_nrv below.  */
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/cp/tree.c	2015-06-16 09:53:47.334092739 +0100
@@ -2200,8 +2200,8 @@ count_trees (tree t)
 verify_stmt_tree_r (tree* tp, int * /*walk_subtrees*/, void* data)
 {
   tree t = *tp;
-  hash_table<pointer_hash <tree_node> > *statements
-      = static_cast <hash_table<pointer_hash <tree_node> > *> (data);
+  hash_table<nofree_ptr_hash <tree_node> > *statements
+      = static_cast <hash_table<nofree_ptr_hash <tree_node> > *> (data);
   tree_node **slot;
 
   if (!STATEMENT_CODE_P (TREE_CODE (t)))
@@ -2224,7 +2224,7 @@ verify_stmt_tree_r (tree* tp, int * /*wa
 void
 verify_stmt_tree (tree t)
 {
-  hash_table<pointer_hash <tree_node> > statements (37);
+  hash_table<nofree_ptr_hash <tree_node> > statements (37);
   cp_walk_tree (&t, verify_stmt_tree_r, &statements, NULL);
 }
 
Index: gcc/java/jcf-io.c
===================================================================
--- gcc/java/jcf-io.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/java/jcf-io.c	2015-06-16 09:53:47.322092878 +0100
@@ -276,10 +276,8 @@ find_classfile (char *filename, JCF *jcf
 
 /* Hash table helper.  */
 
-struct charstar_hash : typed_noop_remove <char>
+struct charstar_hash : nofree_ptr_hash <const char>
 {
-  typedef const char *value_type;
-  typedef const char *compare_type;
   static inline hashval_t hash (const char *candidate);
   static inline bool equal (const char *existing, const char *candidate);
 };
Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/lto/lto.c	2015-06-16 09:53:47.326092832 +0100
@@ -940,10 +940,8 @@ struct tree_scc
   tree entries[1];
 };
 
-struct tree_scc_hasher : typed_noop_remove <tree_scc>
+struct tree_scc_hasher : nofree_ptr_hash <tree_scc>
 {
-  typedef tree_scc *value_type;
-  typedef tree_scc *compare_type;
   static inline hashval_t hash (const tree_scc *);
   static inline bool equal (const tree_scc *, const tree_scc *);
 };
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	2015-06-16 09:53:47.338092692 +0100
+++ gcc/objc/objc-act.c	2015-06-16 09:53:47.326092832 +0100
@@ -3859,10 +3859,8 @@ objc_get_class_ivars (tree class_name)
    more like a set).  So, we store the DECLs, but define equality as
    DECLs having the same name, and hash as the hash of the name.  */
 
-struct decl_name_hash : typed_noop_remove <tree_node>
+struct decl_name_hash : nofree_ptr_hash <tree_node>
 {
-  typedef tree_node *value_type;
-  typedef tree_node *compare_type;
   static inline hashval_t hash (const tree_node *);
   static inline bool equal (const tree_node *, const tree_node *);
 };
Index: libcc1/plugin.cc
===================================================================
--- libcc1/plugin.cc	2015-06-16 09:53:47.338092692 +0100
+++ libcc1/plugin.cc	2015-06-16 09:53:47.338092692 +0100
@@ -134,11 +134,8 @@ decl_addr_hasher::equal (const decl_addr
 
 \f
 
-struct string_hasher : typed_noop_remove<const char>
+struct string_hasher : nofree_ptr_hash<const char>
 {
-  typedef const char *value_type;
-  typedef const char *compare_type;
-
   static inline hashval_t hash (const char *s)
   {
     return htab_hash_string (s);
@@ -176,7 +173,7 @@ struct plugin_context : public cc1_plugi
   hash_table<decl_addr_hasher> address_map;
 
   // A collection of trees that are preserved for the GC.
-  hash_table< pointer_hash<tree_node> > preserved;
+  hash_table< nofree_ptr_hash<tree_node> > preserved;
 
   // File name cache.
   hash_table<string_hasher> file_names;
@@ -245,9 +242,8 @@ plugin_context::mark ()
       ggc_mark ((*it)->address);
     }
 
-  for (hash_table< pointer_hash<tree_node> >::iterator it = preserved.begin ();
-       it != preserved.end ();
-       ++it)
+  for (hash_table< nofree_ptr_hash<tree_node> >::iterator
+	 it = preserved.begin (); it != preserved.end (); ++it)
     ggc_mark (&*it);
 }
 

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [04/13] Add {mark,is}_{empty,deleted} to pointer_hash
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (3 preceding siblings ...)
  2015-06-16  8:55 ` [05/13] Add nofree_ptr_hash Richard Sandiford
@ 2015-06-16  8:55 ` Richard Sandiford
  2015-06-23 21:00   ` Jeff Law
  2015-06-16  8:58 ` [06/13] Add free_ptr_hash Richard Sandiford
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:55 UTC (permalink / raw)
  To: gcc-patches

This patch just adds the standard pointer handling of empty and deleted
entries.  As the series goes on, more and more traits classes will inherit
these definitions, to the point where we can require the functions to exist.

gcc/
	* hash-traits.h (pointer_hash::mark_deleted, pointer_hash::mark_empty)
	(pointer_hash::is_deleted, pointer_hash::is_empty): New functions.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-15 16:04:53.375564430 +0100
+++ gcc/hash-traits.h	2015-06-15 16:04:53.371564477 +0100
@@ -66,9 +66,12 @@ struct pointer_hash : typed_noop_remove
   typedef Type *compare_type;
 
   static inline hashval_t hash (const value_type &);
-
   static inline bool equal (const value_type &existing,
 			    const compare_type &candidate);
+  static inline void mark_deleted (Type *&);
+  static inline void mark_empty (Type *&);
+  static inline bool is_deleted (Type *);
+  static inline bool is_empty (Type *);
 };
 
 template <typename Type>
@@ -88,6 +91,34 @@ pointer_hash <Type>::equal (const value_
   return existing == candidate;
 }
 
+template <typename Type>
+inline void
+pointer_hash <Type>::mark_deleted (Type *&e)
+{
+  e = reinterpret_cast<Type *> (1);
+}
+
+template <typename Type>
+inline void
+pointer_hash <Type>::mark_empty (Type *&e)
+{
+  e = NULL;
+}
+
+template <typename Type>
+inline bool
+pointer_hash <Type>::is_deleted (Type *e)
+{
+  return e == reinterpret_cast<Type *> (1);
+}
+
+template <typename Type>
+inline bool
+pointer_hash <Type>::is_empty (Type *e)
+{
+  return e == NULL;
+}
+
 /* Hasher for entry in gc memory.  */
 
 template<typename T>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [06/13] Add free_ptr_hash
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (4 preceding siblings ...)
  2015-06-16  8:55 ` [04/13] Add {mark,is}_{empty,deleted} to pointer_hash Richard Sandiford
@ 2015-06-16  8:58 ` Richard Sandiford
  2015-06-23 23:14   ` Jeff Law
  2015-06-16  9:03 ` [07/13] Add ggc_ptr_hash Richard Sandiford
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  8:58 UTC (permalink / raw)
  To: gcc-patches

Similarly to the last patch, this one adds a free_ptr_hash that inherits
from both pointer_hash and typed_free_remove.

gcc/
	* hash-traits.h (free_ptr_hash): New class.
	* dwarf2out.c (decl_table_entry_hasher): Inherit from free_ptr_hash
	rather than typed_free_remove.  Remove redudant typedefs.
	(external_ref_hasher): Likewise.
	* except.c (action_record_hasher, ttypes_filter_hasher): Likewise.
	(ehspec_hasher): Likewise.
	* ggc-common.c (saving_hasher): Likewise.
	* gimplify.c (gimplify_hasher): Likewise.
	* haifa-sched.c (delay_i2_hasher): Likewise.
	* loop-invariant.c (invariant_expr_hasher): Likewise.
	* loop-iv.c (biv_entry_hasher): Likewise.
	* loop-unroll.c (iv_split_hasher, var_expand_hasher): Likewise.
	* trans-mem.c (tm_mem_map_hasher, tm_memop_hasher): Likewise.
	* tree-cfg.c (locus_discrim_hasher): Likewise.
	* tree-eh.c (finally_tree_hasher): Likewise.
	* tree-into-ssa.c (var_info_hasher): Likewise.
	* tree-parloops.c (reduction_hasher, name_to_copy_hasher): Likewise.
	* tree-ssa-loop-ivopts.c (iv_inv_expr_hasher): Likewise.
	* tree-ssa-phiopt.c (ssa_names_hasher): Likewise.
	* tree-ssa-pre.c (expr_pred_trans_d): Likewise.
	* tree-ssa-sccvn.c (vn_constant_hasher): Likewise.
	* tree-ssa-structalias.c (equiv_class_hasher): Likewise.
	(shared_bitmap_hasher): Likewise.
	* tree-ssa-threadupdate.c (redirection_data): Likewise.
	* tree-vectorizer.h (peel_info_hasher): Likewise.
	* tree-vectorizer.c (simduid_to_vf, simd_array_to_simduid): Likewise.
	* config/mips/mips.c (mips_lo_sum_offset_hasher): Likewise.

libcc1/
	* plugin.cc (decl_addr_hasher): Inherit from free_ptr_hash
	rather than typed_free_remove.  Remove redudant typedefs.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 09:55:59.084568044 +0100
+++ gcc/hash-traits.h	2015-06-16 09:55:59.084568044 +0100
@@ -173,4 +173,10 @@ struct ggc_cache_hasher : ggc_hasher<T>
 template <typename T>
 struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T> {};
 
+/* Traits for pointer elements that should be freed via free() when an
+   element is deleted.  */
+
+template <typename T>
+struct free_ptr_hash : pointer_hash <T>, typed_free_remove <T> {};
+
 #endif
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/dwarf2out.c	2015-06-16 09:55:59.072568191 +0100
@@ -7296,9 +7296,8 @@ struct decl_table_entry
 
 /* Hashtable helpers.  */
 
-struct decl_table_entry_hasher : typed_free_remove <decl_table_entry>
+struct decl_table_entry_hasher : free_ptr_hash <decl_table_entry>
 {
-  typedef decl_table_entry *value_type;
   typedef die_struct *compare_type;
   static inline hashval_t hash (const decl_table_entry *);
   static inline bool equal (const decl_table_entry *, const die_struct *);
@@ -7838,10 +7837,8 @@ struct external_ref
 
 /* Hashtable helpers.  */
 
-struct external_ref_hasher : typed_free_remove <external_ref>
+struct external_ref_hasher : free_ptr_hash <external_ref>
 {
-  typedef external_ref *value_type;
-  typedef external_ref *compare_type;
   static inline hashval_t hash (const external_ref *);
   static inline bool equal (const external_ref *, const external_ref *);
 };
Index: gcc/except.c
===================================================================
--- gcc/except.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/except.c	2015-06-16 09:55:59.072568191 +0100
@@ -207,10 +207,8 @@ struct action_record
 
 /* Hashtable helpers.  */
 
-struct action_record_hasher : typed_free_remove <action_record>
+struct action_record_hasher : free_ptr_hash <action_record>
 {
-  typedef action_record *value_type;
-  typedef action_record *compare_type;
   static inline hashval_t hash (const action_record *);
   static inline bool equal (const action_record *, const action_record *);
 };
@@ -723,9 +721,8 @@ struct ttypes_filter {
 
 /* Helper for ttypes_filter hashing.  */
 
-struct ttypes_filter_hasher : typed_free_remove <ttypes_filter>
+struct ttypes_filter_hasher : free_ptr_hash <ttypes_filter>
 {
-  typedef ttypes_filter *value_type;
   typedef tree_node *compare_type;
   static inline hashval_t hash (const ttypes_filter *);
   static inline bool equal (const ttypes_filter *, const tree_node *);
@@ -751,10 +748,8 @@ typedef hash_table<ttypes_filter_hasher>
 
 /* Helper for ehspec hashing.  */
 
-struct ehspec_hasher : typed_free_remove <ttypes_filter>
+struct ehspec_hasher : free_ptr_hash <ttypes_filter>
 {
-  typedef ttypes_filter *value_type;
-  typedef ttypes_filter *compare_type;
   static inline hashval_t hash (const ttypes_filter *);
   static inline bool equal (const ttypes_filter *, const ttypes_filter *);
 };
Index: gcc/ggc-common.c
===================================================================
--- gcc/ggc-common.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/ggc-common.c	2015-06-16 09:55:59.072568191 +0100
@@ -237,9 +237,8 @@ #define POINTER_HASH(x) (hashval_t)((int
 
 /* Helper for hashing saving_htab.  */
 
-struct saving_hasher : typed_free_remove <ptr_data>
+struct saving_hasher : free_ptr_hash <ptr_data>
 {
-  typedef ptr_data *value_type;
   typedef void *compare_type;
   static inline hashval_t hash (const ptr_data *);
   static inline bool equal (const ptr_data *, const void *);
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/gimplify.c	2015-06-16 09:55:59.072568191 +0100
@@ -128,10 +128,8 @@ enum omp_region_type
 
 /* Gimplify hashtable helper.  */
 
-struct gimplify_hasher : typed_free_remove <elt_t>
+struct gimplify_hasher : free_ptr_hash <elt_t>
 {
-  typedef elt_t *value_type;
-  typedef elt_t *compare_type;
   static inline hashval_t hash (const elt_t *);
   static inline bool equal (const elt_t *, const elt_t *);
 };
Index: gcc/haifa-sched.c
===================================================================
--- gcc/haifa-sched.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/haifa-sched.c	2015-06-16 09:55:59.076568143 +0100
@@ -637,9 +637,8 @@ delay_i1_hasher::equal (const delay_pair
   return x->i1 == y;
 }
 
-struct delay_i2_hasher : typed_free_remove <delay_pair>
+struct delay_i2_hasher : free_ptr_hash <delay_pair>
 {
-  typedef delay_pair *value_type;
   typedef void *compare_type;
   static inline hashval_t hash (const delay_pair *);
   static inline bool equal (const delay_pair *, const void *);
Index: gcc/loop-invariant.c
===================================================================
--- gcc/loop-invariant.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/loop-invariant.c	2015-06-16 09:55:59.076568143 +0100
@@ -442,10 +442,8 @@ invariant_expr_equal_p (rtx_insn *insn1,
   return true;
 }
 
-struct invariant_expr_hasher : typed_free_remove <invariant_expr_entry>
+struct invariant_expr_hasher : free_ptr_hash <invariant_expr_entry>
 {
-  typedef invariant_expr_entry *value_type;
-  typedef invariant_expr_entry *compare_type;
   static inline hashval_t hash (const invariant_expr_entry *);
   static inline bool equal (const invariant_expr_entry *,
 			    const invariant_expr_entry *);
Index: gcc/loop-iv.c
===================================================================
--- gcc/loop-iv.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/loop-iv.c	2015-06-16 09:55:59.076568143 +0100
@@ -125,9 +125,8 @@ #define DF_REF_IV_SET(REF, IV) iv_ref_ta
 
 /* Hashtable helper.  */
 
-struct biv_entry_hasher : typed_free_remove <biv_entry>
+struct biv_entry_hasher : free_ptr_hash <biv_entry>
 {
-  typedef biv_entry *value_type;
   typedef rtx_def *compare_type;
   static inline hashval_t hash (const biv_entry *);
   static inline bool equal (const biv_entry *, const rtx_def *);
Index: gcc/loop-unroll.c
===================================================================
--- gcc/loop-unroll.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/loop-unroll.c	2015-06-16 09:55:59.076568143 +0100
@@ -113,10 +113,8 @@ struct var_to_expand
 
 /* Hashtable helper for iv_to_split.  */
 
-struct iv_split_hasher : typed_free_remove <iv_to_split>
+struct iv_split_hasher : free_ptr_hash <iv_to_split>
 {
-  typedef iv_to_split *value_type;
-  typedef iv_to_split *compare_type;
   static inline hashval_t hash (const iv_to_split *);
   static inline bool equal (const iv_to_split *, const iv_to_split *);
 };
@@ -140,10 +138,8 @@ iv_split_hasher::equal (const iv_to_spli
 
 /* Hashtable helper for iv_to_split.  */
 
-struct var_expand_hasher : typed_free_remove <var_to_expand>
+struct var_expand_hasher : free_ptr_hash <var_to_expand>
 {
-  typedef var_to_expand *value_type;
-  typedef var_to_expand *compare_type;
   static inline hashval_t hash (const var_to_expand *);
   static inline bool equal (const var_to_expand *, const var_to_expand *);
 };
Index: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/trans-mem.c	2015-06-16 09:55:59.076568143 +0100
@@ -1033,10 +1033,8 @@ typedef struct tm_new_mem_map
 
 /* Hashtable helpers.  */
 
-struct tm_mem_map_hasher : typed_free_remove <tm_new_mem_map_t>
+struct tm_mem_map_hasher : free_ptr_hash <tm_new_mem_map_t>
 {
-  typedef tm_new_mem_map_t *value_type;
-  typedef tm_new_mem_map_t *compare_type;
   static inline hashval_t hash (const tm_new_mem_map_t *);
   static inline bool equal (const tm_new_mem_map_t *, const tm_new_mem_map_t *);
 };
@@ -3334,10 +3332,8 @@ typedef struct tm_memop
 
 /* TM memory operation hashtable helpers.  */
 
-struct tm_memop_hasher : typed_free_remove <tm_memop>
+struct tm_memop_hasher : free_ptr_hash <tm_memop>
 {
-  typedef tm_memop *value_type;
-  typedef tm_memop *compare_type;
   static inline hashval_t hash (const tm_memop *);
   static inline bool equal (const tm_memop *, const tm_memop *);
 };
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-cfg.c	2015-06-16 09:55:59.076568143 +0100
@@ -134,10 +134,8 @@ struct locus_discrim_map
 
 /* Hashtable helpers.  */
 
-struct locus_discrim_hasher : typed_free_remove <locus_discrim_map>
+struct locus_discrim_hasher : free_ptr_hash <locus_discrim_map>
 {
-  typedef locus_discrim_map *value_type;
-  typedef locus_discrim_map *compare_type;
   static inline hashval_t hash (const locus_discrim_map *);
   static inline bool equal (const locus_discrim_map *,
 			    const locus_discrim_map *);
Index: gcc/tree-eh.c
===================================================================
--- gcc/tree-eh.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-eh.c	2015-06-16 09:55:59.076568143 +0100
@@ -200,10 +200,8 @@ struct finally_tree_node
 
 /* Hashtable helpers.  */
 
-struct finally_tree_hasher : typed_free_remove <finally_tree_node>
+struct finally_tree_hasher : free_ptr_hash <finally_tree_node>
 {
-  typedef finally_tree_node *value_type;
-  typedef finally_tree_node *compare_type;
   static inline hashval_t hash (const finally_tree_node *);
   static inline bool equal (const finally_tree_node *,
 			    const finally_tree_node *);
Index: gcc/tree-into-ssa.c
===================================================================
--- gcc/tree-into-ssa.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-into-ssa.c	2015-06-16 09:55:59.080568093 +0100
@@ -217,10 +217,8 @@ typedef struct var_info_d *var_info_p;
 
 /* VAR_INFOS hashtable helpers.  */
 
-struct var_info_hasher : typed_free_remove <var_info_d>
+struct var_info_hasher : free_ptr_hash <var_info_d>
 {
-  typedef var_info_d *value_type;
-  typedef var_info_d *compare_type;
   static inline hashval_t hash (const value_type &);
   static inline bool equal (const value_type &, const compare_type &);
 };
Index: gcc/tree-parloops.c
===================================================================
--- gcc/tree-parloops.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-parloops.c	2015-06-16 09:55:59.080568093 +0100
@@ -221,10 +221,8 @@ struct reduction_info
 
 /* Reduction info hashtable helpers.  */
 
-struct reduction_hasher : typed_free_remove <reduction_info>
+struct reduction_hasher : free_ptr_hash <reduction_info>
 {
-  typedef reduction_info *value_type;
-  typedef reduction_info *compare_type;
   static inline hashval_t hash (const reduction_info *);
   static inline bool equal (const reduction_info *, const reduction_info *);
 };
@@ -273,10 +271,8 @@ struct name_to_copy_elt
 
 /* Name copies hashtable helpers.  */
 
-struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
+struct name_to_copy_hasher : free_ptr_hash <name_to_copy_elt>
 {
-  typedef name_to_copy_elt *value_type;
-  typedef name_to_copy_elt *compare_type;
   static inline hashval_t hash (const name_to_copy_elt *);
   static inline bool equal (const name_to_copy_elt *, const name_to_copy_elt *);
 };
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-loop-ivopts.c	2015-06-16 09:55:59.080568093 +0100
@@ -285,10 +285,8 @@ typedef struct iv_cand *iv_cand_p;
 
 /* Hashtable helpers.  */
 
-struct iv_inv_expr_hasher : typed_free_remove <iv_inv_expr_ent>
+struct iv_inv_expr_hasher : free_ptr_hash <iv_inv_expr_ent>
 {
-  typedef iv_inv_expr_ent *value_type;
-  typedef iv_inv_expr_ent *compare_type;
   static inline hashval_t hash (const iv_inv_expr_ent *);
   static inline bool equal (const iv_inv_expr_ent *, const iv_inv_expr_ent *);
 };
Index: gcc/tree-ssa-phiopt.c
===================================================================
--- gcc/tree-ssa-phiopt.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-phiopt.c	2015-06-16 09:55:59.080568093 +0100
@@ -1315,10 +1315,8 @@ struct name_to_bb
 
 /* Hashtable helpers.  */
 
-struct ssa_names_hasher : typed_free_remove <name_to_bb>
+struct ssa_names_hasher : free_ptr_hash <name_to_bb>
 {
-  typedef name_to_bb *value_type;
-  typedef name_to_bb *compare_type;
   static inline hashval_t hash (const name_to_bb *);
   static inline bool equal (const name_to_bb *, const name_to_bb *);
 };
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-pre.c	2015-06-16 09:55:59.080568093 +0100
@@ -517,7 +517,7 @@ static pool_allocator<bitmap_set> bitmap
 /* A three tuple {e, pred, v} used to cache phi translations in the
    phi_translate_table.  */
 
-typedef struct expr_pred_trans_d : typed_free_remove<expr_pred_trans_d>
+typedef struct expr_pred_trans_d : free_ptr_hash<expr_pred_trans_d>
 {
   /* The expression.  */
   pre_expr e;
@@ -533,8 +533,6 @@ typedef struct expr_pred_trans_d : typed
   hashval_t hashcode;
 
   /* hash_table support.  */
-  typedef expr_pred_trans_d *value_type;
-  typedef expr_pred_trans_d *compare_type;
   static inline hashval_t hash (const expr_pred_trans_d *);
   static inline int equal (const expr_pred_trans_d *, const expr_pred_trans_d *);
 } *expr_pred_trans_t;
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-sccvn.c	2015-06-16 09:55:59.080568093 +0100
@@ -288,10 +288,8 @@ typedef struct vn_tables_s
 
 /* vn_constant hashtable helpers.  */
 
-struct vn_constant_hasher : typed_free_remove <vn_constant_s>
+struct vn_constant_hasher : free_ptr_hash <vn_constant_s>
 { 
-  typedef vn_constant_s *value_type;
-  typedef vn_constant_s *compare_type;
   static inline hashval_t hash (const vn_constant_s *);
   static inline bool equal (const vn_constant_s *, const vn_constant_s *);
 };
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-structalias.c	2015-06-16 09:55:59.084568044 +0100
@@ -1927,10 +1927,8 @@ typedef const struct equiv_class_label *
 
 /* Equiv_class_label hashtable helpers.  */
 
-struct equiv_class_hasher : typed_free_remove <equiv_class_label>
+struct equiv_class_hasher : free_ptr_hash <equiv_class_label>
 {
-  typedef equiv_class_label *value_type;
-  typedef equiv_class_label *compare_type;
   static inline hashval_t hash (const equiv_class_label *);
   static inline bool equal (const equiv_class_label *,
 			    const equiv_class_label *);
@@ -5952,10 +5950,8 @@ typedef const struct shared_bitmap_info
 
 /* Shared_bitmap hashtable helpers.  */
 
-struct shared_bitmap_hasher : typed_free_remove <shared_bitmap_info>
+struct shared_bitmap_hasher : free_ptr_hash <shared_bitmap_info>
 {
-  typedef shared_bitmap_info *value_type;
-  typedef shared_bitmap_info *compare_type;
   static inline hashval_t hash (const shared_bitmap_info *);
   static inline bool equal (const shared_bitmap_info *,
 			    const shared_bitmap_info *);
Index: gcc/tree-ssa-threadupdate.c
===================================================================
--- gcc/tree-ssa-threadupdate.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-ssa-threadupdate.c	2015-06-16 09:55:59.084568044 +0100
@@ -128,7 +128,7 @@ struct el
    may have many incoming edges threaded to the same outgoing edge.  This
    can be naturally implemented with a hash table.  */
 
-struct redirection_data : typed_free_remove<redirection_data>
+struct redirection_data : free_ptr_hash<redirection_data>
 {
   /* We support wiring up two block duplicates in a jump threading path.
 
@@ -153,8 +153,6 @@ struct redirection_data : typed_free_rem
   struct el *incoming_edges;
 
   /* hash_table support.  */
-  typedef redirection_data *value_type;
-  typedef redirection_data *compare_type;
   static inline hashval_t hash (const redirection_data *);
   static inline int equal (const redirection_data *, const redirection_data *);
 };
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-vectorizer.h	2015-06-16 09:55:59.084568044 +0100
@@ -212,10 +212,8 @@ typedef struct _vect_peel_extended_info
 
 /* Peeling hashtable helpers.  */
 
-struct peel_info_hasher : typed_free_remove <_vect_peel_info>
+struct peel_info_hasher : free_ptr_hash <_vect_peel_info>
 {
-  typedef _vect_peel_info *value_type;
-  typedef _vect_peel_info *compare_type;
   static inline hashval_t hash (const _vect_peel_info *);
   static inline bool equal (const _vect_peel_info *, const _vect_peel_info *);
 };
Index: gcc/tree-vectorizer.c
===================================================================
--- gcc/tree-vectorizer.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/tree-vectorizer.c	2015-06-16 09:55:59.084568044 +0100
@@ -105,14 +105,12 @@ Software Foundation; either version 3, o
 \f
 /* For mapping simduid to vectorization factor.  */
 
-struct simduid_to_vf : typed_free_remove<simduid_to_vf>
+struct simduid_to_vf : free_ptr_hash<simduid_to_vf>
 {
   unsigned int simduid;
   int vf;
 
   /* hash_table support.  */
-  typedef simduid_to_vf *value_type;
-  typedef simduid_to_vf *compare_type;
   static inline hashval_t hash (const simduid_to_vf *);
   static inline int equal (const simduid_to_vf *, const simduid_to_vf *);
 };
@@ -141,14 +139,12 @@ simduid_to_vf::equal (const simduid_to_v
    This hash maps from the OMP simd array (D.1737[]) to DECL_UID of
    simduid.0.  */
 
-struct simd_array_to_simduid : typed_free_remove<simd_array_to_simduid>
+struct simd_array_to_simduid : free_ptr_hash<simd_array_to_simduid>
 {
   tree decl;
   unsigned int simduid;
 
   /* hash_table support.  */
-  typedef simd_array_to_simduid *value_type;
-  typedef simd_array_to_simduid *compare_type;
   static inline hashval_t hash (const simd_array_to_simduid *);
   static inline int equal (const simd_array_to_simduid *,
 			   const simd_array_to_simduid *);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2015-06-16 09:55:59.084568044 +0100
+++ gcc/config/mips/mips.c	2015-06-16 09:55:59.068568237 +0100
@@ -16350,9 +16350,8 @@ mips_hash_base (rtx base)
 
 /* Hashtable helpers.  */
 
-struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
+struct mips_lo_sum_offset_hasher : free_ptr_hash <mips_lo_sum_offset>
 {
-  typedef mips_lo_sum_offset *value_type;
   typedef rtx_def *compare_type;
   static inline hashval_t hash (const mips_lo_sum_offset *);
   static inline bool equal (const mips_lo_sum_offset *, const rtx_def *);
Index: libcc1/plugin.cc
===================================================================
--- libcc1/plugin.cc	2015-06-16 09:55:59.084568044 +0100
+++ libcc1/plugin.cc	2015-06-16 09:55:59.084568044 +0100
@@ -111,11 +111,8 @@ struct decl_addr_value
   tree address;
 };
 
-struct decl_addr_hasher : typed_free_remove<decl_addr_value>
+struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
 {
-  typedef decl_addr_value *value_type;
-  typedef decl_addr_value *compare_type;
-
   static inline hashval_t hash (const decl_addr_value *);
   static inline bool equal (const decl_addr_value *, const decl_addr_value *);
 };

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [07/13] Add ggc_ptr_hash
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (5 preceding siblings ...)
  2015-06-16  8:58 ` [06/13] Add free_ptr_hash Richard Sandiford
@ 2015-06-16  9:03 ` Richard Sandiford
  2015-06-23 23:16   ` Jeff Law
  2015-06-16  9:05 ` [09/13] Make remaining pointer hashes inherit from a generic class Richard Sandiford
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:03 UTC (permalink / raw)
  To: gcc-patches

This patch renames ggc_hasher to ggc_remove and removes the typedefs,
to make it provide the same kind of interface as typed_noop_remove and
typed_free_remove.  It then defines a new class ggc_ptr_hash that
inherits from both pointer_hash and ggc_remove.  It changes all uses of
ggc_hasher to use ggc_ptr_hash instead.

gcc/
	* hash-traits.h (ggc_hasher): Rename to...
	(ggc_remover): ...this and remove typedefs.
	(ggc_cache_hasher): Update accordingly.  Add typedefs.
	(ggc_ptr_hash): New class.
	* hash-table.h: Update comment.
	* cfgloop.h (loop_exit_hasher): Inherit from ggc_ptr_hash rather than
	ggc_hasher.
	* cgraph.h (section_name_hasher, cgraph_edge_hasher): Likewise.
	(tree_descriptor_hasher): Likewise.
	* cgraph.c (function_version_hasher): Likewise.
	* dwarf2out.c (indirect_string_hasher, dwarf_file_hasher): Likewise.
	(decl_die_hasher, block_die_hasher, decl_loc_hasher): Likewise.
	(dw_loc_list_hasher, addr_hasher): Likewise.
	* function.h (used_type_hasher): Likewise.
	* function.c (temp_address_hasher): Likewise.
	* gimple-ssa.h (tm_restart_hasher, ssa_name_hasher): Likewise.
	* libfuncs.h (libfunc_hasher): Likewise.
	* lto-streamer.h (decl_state_hasher): Likewise.
	* optabs.c (libfunc_decl_hasher): Likewise.
	* tree-scalar-evolution.c (scev_info_hasher): Likewise.
	* varasm.c (section_hasher, object_block_hasher): Likewise.
	(const_rtx_desc_hasher): Likewise.
	* config/darwin.c (indirection_hasher, cfstring_hasher): Likewise.
	* config/rs6000/rs6000.c (toc_hasher, builtin_hasher): Likewise.

gcc/c-family/
	* c-common.c (c_type_hasher): Inherit from ggc_ptr_hash rather than
	ggc_hasher.

gcc/cp/
	* constexpr.c (constexpr_fundef_hasher): Inherit from ggc_ptr_hash
	rather than ggc_hasher.
	(constexpr_call_hasher): Likewise.
	* cp-tree.h (cxx_int_tree_map_hasher, named_label_hasher): Likewise.
	* decl.c (typename_hasher): Likewise.
	* mangle.c (conv_type_hasher): Likewise.
	* pt.c (spec_hasher): Likewise.
	* tree.c (cplus_array_hasher, list_hasher): Likewise.
	* typeck2.c (abstract_type_hasher): Likewise.

gcc/fortran/
	* trans-decl.c (module_hasher): Likewise.
	* trans.h (module_decl_hasher): Likewise.

gcc/java/
	* java-tree.h (treetreehasher): Inherit from ggc_ptr_hash
	rather than ggc_hasher.
	(ict_hasher, type_assertion_hasher): Likewise.

gcc/objc/
	* objc-act.c (objc_string_hasher): Inherit from ggc_ptr_hash
	rather than ggc_hasher.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/hash-traits.h	2015-06-16 09:58:55.658524164 +0100
@@ -121,14 +121,11 @@ pointer_hash <Type>::is_empty (Type *e)
   return e == NULL;
 }
 
-/* Hasher for entry in gc memory.  */
+/* Remover and marker for entries in gc memory.  */
 
 template<typename T>
-struct ggc_hasher
+struct ggc_remove
 {
-  typedef T value_type;
-  typedef T compare_type;
-
   static void remove (T &) {}
 
   static void
@@ -155,8 +152,11 @@ struct ggc_hasher
 /* Hasher for cache entry in gc memory.  */
 
 template<typename T>
-struct ggc_cache_hasher : ggc_hasher<T>
+struct ggc_cache_hasher : ggc_remove<T>
 {
+  typedef T value_type;
+  typedef T compare_type;
+
   /* Entries are weakly held because this is for caches.  */
   static void ggc_mx (T &) {}
 
@@ -179,4 +179,10 @@ struct nofree_ptr_hash : pointer_hash <T
 template <typename T>
 struct free_ptr_hash : pointer_hash <T>, typed_free_remove <T> {};
 
+/* Traits for elements that point to gc memory.  The pointed-to data
+   must be kept across collections.  */
+
+template <typename T>
+struct ggc_ptr_hash : pointer_hash <T>, ggc_remove <T *> {};
+
 #endif
Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/hash-table.h	2015-06-16 10:00:54.221151068 +0100
@@ -91,8 +91,8 @@ Software Foundation; either version 3, o
    We compose this into a few steps.
 
       1. Decide on a removal policy for values stored in the table.
-         hash-traits.h provides class templates for the two most common
-         policies.
+         hash-traits.h provides class templates for the three most common
+         policies:
 
          * typed_free_remove implements the static 'remove' member function
          by calling free().
@@ -100,6 +100,11 @@ Software Foundation; either version 3, o
          * typed_noop_remove implements the static 'remove' member function
          by doing nothing.
 
+         * ggc_remove implements the static 'remove' member by doing nothing,
+         but instead provides routines for gc marking and for PCH streaming.
+         Use this for garbage-collected data that needs to be preserved across
+         collections.
+
          You can use these policies by simply deriving the descriptor type
          from one of those class template, with the appropriate argument.
 
Index: gcc/cfgloop.h
===================================================================
--- gcc/cfgloop.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cfgloop.h	2015-06-16 09:57:55.867216425 +0100
@@ -88,7 +88,7 @@ struct GTY ((for_user)) loop_exit {
   struct loop_exit *next_e;
 };
 
-struct loop_exit_hasher : ggc_hasher<loop_exit *>
+struct loop_exit_hasher : ggc_ptr_hash<loop_exit>
 {
   typedef edge compare_type;
 
Index: gcc/cgraph.h
===================================================================
--- gcc/cgraph.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cgraph.h	2015-06-16 09:57:55.871216378 +0100
@@ -44,7 +44,7 @@ struct GTY((for_user)) section_hash_entr
 
 typedef struct section_hash_entry_d section_hash_entry;
 
-struct section_name_hasher : ggc_hasher<section_hash_entry *>
+struct section_name_hasher : ggc_ptr_hash<section_hash_entry>
 {
   typedef const char *compare_type;
 
@@ -783,7 +783,7 @@ enum cgraph_inline_failed_type_t
 
 struct cgraph_edge;
 
-struct cgraph_edge_hasher : ggc_hasher<cgraph_edge *>
+struct cgraph_edge_hasher : ggc_ptr_hash<cgraph_edge>
 {
   typedef gimple compare_type;
 
@@ -2815,7 +2815,7 @@ varpool_node::all_refs_explicit_p ()
 	  && !force_output);
 }
 
-struct tree_descriptor_hasher : ggc_hasher<constant_descriptor_tree *>
+struct tree_descriptor_hasher : ggc_ptr_hash<constant_descriptor_tree>
 {
   static hashval_t hash (constant_descriptor_tree *);
   static bool equal (constant_descriptor_tree *, constant_descriptor_tree *);
Index: gcc/cgraph.c
===================================================================
--- gcc/cgraph.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cgraph.c	2015-06-16 09:57:55.871216378 +0100
@@ -128,7 +128,7 @@ struct cgraph_2node_hook_list {
 
 /* Hash descriptor for cgraph_function_version_info.  */
 
-struct function_version_hasher : ggc_hasher<cgraph_function_version_info *>
+struct function_version_hasher : ggc_ptr_hash<cgraph_function_version_info>
 {
   static hashval_t hash (cgraph_function_version_info *);
   static bool equal (cgraph_function_version_info *,
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/dwarf2out.c	2015-06-16 09:57:55.891216136 +0100
@@ -222,7 +222,7 @@ struct GTY((for_user)) indirect_string_n
   unsigned int index;
 };
 
-struct indirect_string_hasher : ggc_hasher<indirect_string_node *>
+struct indirect_string_hasher : ggc_ptr_hash<indirect_string_node>
 {
   typedef const char *compare_type;
 
@@ -2798,7 +2798,7 @@ static GTY(()) limbo_die_node *limbo_die
    DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set.  */
 static GTY(()) limbo_die_node *deferred_asm_name;
 
-struct dwarf_file_hasher : ggc_hasher<dwarf_file_data *>
+struct dwarf_file_hasher : ggc_ptr_hash<dwarf_file_data>
 {
   typedef const char *compare_type;
 
@@ -2809,7 +2809,7 @@ struct dwarf_file_hasher : ggc_hasher<dw
 /* Filenames referenced by this compilation unit.  */
 static GTY(()) hash_table<dwarf_file_hasher> *file_table;
 
-struct decl_die_hasher : ggc_hasher<die_node *>
+struct decl_die_hasher : ggc_ptr_hash<die_node>
 {
   typedef tree compare_type;
 
@@ -2820,7 +2820,7 @@ struct decl_die_hasher : ggc_hasher<die_
    The key is a DECL_UID() which is a unique number identifying each decl.  */
 static GTY (()) hash_table<decl_die_hasher> *decl_die_table;
 
-struct block_die_hasher : ggc_hasher<die_struct *>
+struct block_die_hasher : ggc_ptr_hash<die_struct>
 {
   static hashval_t hash (die_struct *);
   static bool equal (die_struct *, die_struct *);
@@ -2884,7 +2884,7 @@ struct GTY ((chain_next ("%h.next"))) ca
 };
 
 
-struct decl_loc_hasher : ggc_hasher<var_loc_list *>
+struct decl_loc_hasher : ggc_ptr_hash<var_loc_list>
 {
   typedef const_tree compare_type;
 
@@ -2914,7 +2914,7 @@ struct GTY ((for_user)) cached_dw_loc_li
 };
 typedef struct cached_dw_loc_list_def cached_dw_loc_list;
 
-struct dw_loc_list_hasher : ggc_hasher<cached_dw_loc_list *>
+struct dw_loc_list_hasher : ggc_ptr_hash<cached_dw_loc_list>
 {
 
   typedef const_tree compare_type;
@@ -4240,7 +4240,7 @@ AT_loc_list_ptr (dw_attr_ref a)
   return &a->dw_attr_val.v.val_loc_list;
 }
 
-struct addr_hasher : ggc_hasher<addr_table_entry *>
+struct addr_hasher : ggc_ptr_hash<addr_table_entry>
 {
   static hashval_t hash (addr_table_entry *);
   static bool equal (addr_table_entry *, addr_table_entry *);
Index: gcc/function.h
===================================================================
--- gcc/function.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/function.h	2015-06-16 09:57:55.891216136 +0100
@@ -700,7 +700,7 @@ struct GTY((for_user)) types_used_by_var
   tree var_decl;
 };
 
-struct used_type_hasher : ggc_hasher<types_used_by_vars_entry *>
+struct used_type_hasher : ggc_ptr_hash<types_used_by_vars_entry>
 {
   static hashval_t hash (types_used_by_vars_entry *);
   static bool equal (types_used_by_vars_entry *, types_used_by_vars_entry *);
Index: gcc/function.c
===================================================================
--- gcc/function.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/function.c	2015-06-16 09:57:55.891216136 +0100
@@ -575,7 +575,7 @@ struct GTY((for_user)) temp_slot_address
   struct temp_slot *temp_slot;
 };
 
-struct temp_address_hasher : ggc_hasher<temp_slot_address_entry *>
+struct temp_address_hasher : ggc_ptr_hash<temp_slot_address_entry>
 {
   static hashval_t hash (temp_slot_address_entry *);
   static bool equal (temp_slot_address_entry *, temp_slot_address_entry *);
Index: gcc/gimple-ssa.h
===================================================================
--- gcc/gimple-ssa.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/gimple-ssa.h	2015-06-16 09:57:55.891216136 +0100
@@ -34,7 +34,7 @@ struct GTY((for_user)) tm_restart_node {
 
 /* Hasher for tm_restart_node.  */
 
-struct tm_restart_hasher : ggc_hasher<tm_restart_node *>
+struct tm_restart_hasher : ggc_ptr_hash<tm_restart_node>
 {
   static hashval_t hash (tm_restart_node *n) { return htab_hash_pointer (n); }
 
@@ -45,7 +45,7 @@ struct tm_restart_hasher : ggc_hasher<tm
   }
 };
 
-struct ssa_name_hasher : ggc_hasher<tree>
+struct ssa_name_hasher : ggc_ptr_hash<tree_node>
 {
   /* Hash a tree in a uid_decl_map.  */
 
Index: gcc/libfuncs.h
===================================================================
--- gcc/libfuncs.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/libfuncs.h	2015-06-16 09:57:55.891216136 +0100
@@ -61,7 +61,7 @@ struct GTY((for_user)) libfunc_entry {
 
 /* Descriptor for libfunc_entry.  */
 
-struct libfunc_hasher : ggc_hasher<libfunc_entry *>
+struct libfunc_hasher : ggc_ptr_hash<libfunc_entry>
 {
   static hashval_t hash (libfunc_entry *);
   static bool equal (libfunc_entry *, libfunc_entry *);
Index: gcc/lto-streamer.h
===================================================================
--- gcc/lto-streamer.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/lto-streamer.h	2015-06-16 09:57:55.891216136 +0100
@@ -508,7 +508,7 @@ struct GTY((for_user)) lto_in_decl_state
 
 typedef struct lto_in_decl_state *lto_in_decl_state_ptr;
 
-struct decl_state_hasher : ggc_hasher<lto_in_decl_state *>
+struct decl_state_hasher : ggc_ptr_hash<lto_in_decl_state>
 {
   static hashval_t
   hash (lto_in_decl_state *s)
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/optabs.c	2015-06-16 09:57:55.895216093 +0100
@@ -6053,7 +6053,7 @@ gen_satfractuns_conv_libfunc (convert_op
 
 /* Hashtable callbacks for libfunc_decls.  */
 
-struct libfunc_decl_hasher : ggc_hasher<tree>
+struct libfunc_decl_hasher : ggc_ptr_hash<tree_node>
 {
   static hashval_t
   hash (tree entry)
Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/tree-scalar-evolution.c	2015-06-16 09:57:55.895216093 +0100
@@ -341,7 +341,7 @@ static unsigned nb_get_scev = 0;
    happen, then it qualifies it with chrec_known.  */
 tree chrec_known;
 
-struct scev_info_hasher : ggc_hasher<scev_info_str *>
+struct scev_info_hasher : ggc_ptr_hash<scev_info_str>
 {
   static hashval_t hash (scev_info_str *i);
   static bool equal (const scev_info_str *a, const scev_info_str *b);
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/varasm.c	2015-06-16 09:57:55.895216093 +0100
@@ -190,7 +190,7 @@ #define IN_NAMED_SECTION(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
    && DECL_SECTION_NAME (DECL) != NULL)
 
-struct section_hasher : ggc_hasher<section *>
+struct section_hasher : ggc_ptr_hash<section>
 {
   typedef const char *compare_type;
 
@@ -201,7 +201,7 @@ struct section_hasher : ggc_hasher<secti
 /* Hash table of named sections.  */
 static GTY(()) hash_table<section_hasher> *section_htab;
 
-struct object_block_hasher : ggc_hasher<object_block *>
+struct object_block_hasher : ggc_ptr_hash<object_block>
 {
   typedef const section *compare_type;
 
@@ -3541,7 +3541,7 @@ struct GTY((chain_next ("%h.next"), for_
   int mark;
 };
 
-struct const_rtx_desc_hasher : ggc_hasher<constant_descriptor_rtx *>
+struct const_rtx_desc_hasher : ggc_ptr_hash<constant_descriptor_rtx>
 {
   static hashval_t hash (constant_descriptor_rtx *);
   static bool equal (constant_descriptor_rtx *, constant_descriptor_rtx *);
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/config/darwin.c	2015-06-16 09:57:55.871216378 +0100
@@ -479,7 +479,7 @@ typedef struct GTY ((for_user)) machopic
   bool used;
 } machopic_indirection;
 
-struct indirection_hasher : ggc_hasher<machopic_indirection *>
+struct indirection_hasher : ggc_ptr_hash<machopic_indirection>
 {
   typedef const char *compare_type;
   static hashval_t hash (machopic_indirection *);
@@ -3273,7 +3273,7 @@ typedef struct GTY ((for_user)) cfstring
   tree constructor;
 } cfstring_descriptor;
 
-struct cfstring_hasher : ggc_hasher<cfstring_descriptor *>
+struct cfstring_hasher : ggc_ptr_hash<cfstring_descriptor>
 {
   static hashval_t hash (cfstring_descriptor *);
   static bool equal (cfstring_descriptor *, cfstring_descriptor *);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/config/rs6000/rs6000.c	2015-06-16 09:57:55.879216280 +0100
@@ -1230,7 +1230,7 @@ struct GTY((for_user)) toc_hash_struct
   int labelno;
 };
 
-struct toc_hasher : ggc_hasher<toc_hash_struct *>
+struct toc_hasher : ggc_ptr_hash<toc_hash_struct>
 {
   static hashval_t hash (toc_hash_struct *);
   static bool equal (toc_hash_struct *, toc_hash_struct *);
@@ -1247,7 +1247,7 @@ struct GTY((for_user)) builtin_hash_stru
   unsigned char uns_p[4];	/* and whether the types are unsigned.  */
 };
 
-struct builtin_hasher : ggc_hasher<builtin_hash_struct *>
+struct builtin_hasher : ggc_ptr_hash<builtin_hash_struct>
 {
   static hashval_t hash (builtin_hash_struct *);
   static bool equal (builtin_hash_struct *, builtin_hash_struct *);
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/c-family/c-common.c	2015-06-16 09:57:55.867216425 +0100
@@ -5092,7 +5092,7 @@ c_apply_type_quals_to_decl (int type_qua
     }
 }
 
-struct c_type_hasher : ggc_hasher<tree>
+struct c_type_hasher : ggc_ptr_hash<tree_node>
 {
   static hashval_t hash (tree);
   static bool equal (tree, tree);
Index: gcc/cp/constexpr.c
===================================================================
--- gcc/cp/constexpr.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/constexpr.c	2015-06-16 09:57:55.879216280 +0100
@@ -124,7 +124,7 @@ struct GTY((for_user)) constexpr_fundef
   tree body;
 };
 
-struct constexpr_fundef_hasher : ggc_hasher<constexpr_fundef *>
+struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
 {
   static hashval_t hash (constexpr_fundef *);
   static bool equal (constexpr_fundef *, constexpr_fundef *);
@@ -873,7 +873,7 @@ struct GTY((for_user)) constexpr_call {
   hashval_t hash;
 };
 
-struct constexpr_call_hasher : ggc_hasher<constexpr_call *>
+struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
 {
   static hashval_t hash (constexpr_call *);
   static bool equal (constexpr_call *, constexpr_call *);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/cp-tree.h	2015-06-16 09:57:55.879216280 +0100
@@ -1181,7 +1181,7 @@ struct GTY((for_user)) cxx_int_tree_map
   tree to;
 };
 
-struct cxx_int_tree_map_hasher : ggc_hasher<cxx_int_tree_map *>
+struct cxx_int_tree_map_hasher : ggc_ptr_hash<cxx_int_tree_map>
 {
   static hashval_t hash (cxx_int_tree_map *);
   static bool equal (cxx_int_tree_map *, cxx_int_tree_map *);
@@ -1189,7 +1189,7 @@ struct cxx_int_tree_map_hasher : ggc_has
 
 struct named_label_entry;
 
-struct named_label_hasher : ggc_hasher<named_label_entry *>
+struct named_label_hasher : ggc_ptr_hash<named_label_entry>
 {
   static hashval_t hash (named_label_entry *);
   static bool equal (named_label_entry *, named_label_entry *);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/decl.c	2015-06-16 09:57:55.883216229 +0100
@@ -3332,7 +3332,7 @@ struct typename_info {
   bool class_p;
 };
 
-struct typename_hasher : ggc_hasher<tree>
+struct typename_hasher : ggc_ptr_hash<tree_node>
 {
   typedef typename_info *compare_type;
 
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/mangle.c	2015-06-16 09:57:55.883216229 +0100
@@ -3844,7 +3844,7 @@ mangle_thunk (tree fn_decl, const int th
   return result;
 }
 
-struct conv_type_hasher : ggc_hasher<tree>
+struct conv_type_hasher : ggc_ptr_hash<tree_node>
 {
   static hashval_t hash (tree);
   static bool equal (tree, tree);
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/pt.c	2015-06-16 09:57:55.887216180 +0100
@@ -90,7 +90,7 @@ struct GTY((for_user)) spec_entry
   tree spec;
 };
 
-struct spec_hasher : ggc_hasher<spec_entry *>
+struct spec_hasher : ggc_ptr_hash<spec_entry>
 {
   static hashval_t hash (spec_entry *);
   static bool equal (spec_entry *, spec_entry *);
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/tree.c	2015-06-16 09:57:55.887216180 +0100
@@ -737,7 +737,7 @@ struct cplus_array_info
   tree domain;
 };
 
-struct cplus_array_hasher : ggc_hasher<tree>
+struct cplus_array_hasher : ggc_ptr_hash<tree_node>
 {
   typedef cplus_array_info *compare_type;
 
@@ -1715,7 +1715,7 @@ struct list_proxy
   tree chain;
 };
 
-struct list_hasher : ggc_hasher<tree>
+struct list_hasher : ggc_ptr_hash<tree_node>
 {
   typedef list_proxy *compare_type;
 
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/cp/typeck2.c	2015-06-16 09:57:55.887216180 +0100
@@ -157,7 +157,7 @@ struct GTY((chain_next ("%h.next"), for_
   struct pending_abstract_type* next;
 };
 
-struct abstract_type_hasher : ggc_hasher<pending_abstract_type *>
+struct abstract_type_hasher : ggc_ptr_hash<pending_abstract_type>
 {
   typedef tree compare_type;
   static hashval_t hash (pending_abstract_type *);
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/fortran/trans-decl.c	2015-06-16 09:57:55.891216136 +0100
@@ -4363,7 +4363,7 @@ gfc_trans_deferred_vars (gfc_symbol * pr
   gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
 }
 
-struct module_hasher : ggc_hasher<module_htab_entry *>
+struct module_hasher : ggc_ptr_hash<module_htab_entry>
 {
   typedef const char *compare_type;
 
Index: gcc/fortran/trans.h
===================================================================
--- gcc/fortran/trans.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/fortran/trans.h	2015-06-16 09:57:55.891216136 +0100
@@ -598,7 +598,7 @@ void gfc_generate_module_vars (gfc_names
 /* Get the appropriate return statement for a procedure.  */
 tree gfc_generate_return (void);
 
-struct module_decl_hasher : ggc_hasher<tree_node *>
+struct module_decl_hasher : ggc_ptr_hash<tree_node>
 {
   typedef const char *compare_type;
 
Index: gcc/java/java-tree.h
===================================================================
--- gcc/java/java-tree.h	2015-06-16 09:57:55.899216049 +0100
+++ gcc/java/java-tree.h	2015-06-16 09:57:55.891216136 +0100
@@ -714,7 +714,7 @@ struct GTY((for_user)) treetreehash_entr
   tree value;
 };
 
-struct treetreehasher : ggc_hasher<treetreehash_entry *>
+struct treetreehasher : ggc_ptr_hash<treetreehash_entry>
 {
   typedef tree compare_type;
 
@@ -722,7 +722,7 @@ struct treetreehasher : ggc_hasher<treet
   static bool equal (treetreehash_entry *, tree);
 };
 
-struct ict_hasher : ggc_hasher<tree_node *>
+struct ict_hasher : ggc_ptr_hash<tree_node>
 {
   static hashval_t hash (tree t) { return htab_hash_pointer (t); }
   static bool equal (tree a, tree b) { return a == b; }
@@ -797,7 +797,7 @@ typedef struct GTY((for_user)) type_asse
   tree op2;           /* Second operand. */
 } type_assertion;
 
-struct type_assertion_hasher : ggc_hasher<type_assertion *>
+struct type_assertion_hasher : ggc_ptr_hash<type_assertion>
 {
   static hashval_t hash (type_assertion *);
   static bool equal (type_assertion *, type_assertion *);
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	2015-06-16 09:57:55.899216049 +0100
+++ gcc/objc/objc-act.c	2015-06-16 09:57:55.895216093 +0100
@@ -268,7 +268,7 @@ struct GTY((for_user)) string_descriptor
   tree constructor;
 };
 
-struct objc_string_hasher : ggc_hasher<string_descriptor *>
+struct objc_string_hasher : ggc_ptr_hash<string_descriptor>
 {
   static hashval_t hash (string_descriptor *);
   static bool equal (string_descriptor *, string_descriptor *);

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [09/13] Make remaining pointer hashes inherit from a generic class
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (6 preceding siblings ...)
  2015-06-16  9:03 ` [07/13] Add ggc_ptr_hash Richard Sandiford
@ 2015-06-16  9:05 ` Richard Sandiford
  2015-06-23 23:18   ` Jeff Law
  2015-06-16  9:05 ` [08/13] Add a ggc_cache_ptr_hash Richard Sandiford
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:05 UTC (permalink / raw)
  To: gcc-patches

This patch mops up the remaining pointer traits classes that didn't
inherit from any of the standard ones and just did their own thing.

gcc/
	* cgraph.h (asmname_hasher): Inherit from ggc_ptr_hash.  Remove
	redundant typedefs and members.
	* coverage.c (counts_entry): Inherit from pointer_hash.  Remove
	redundant typedefs.
	* dwarf2out.c (cu_hash_table_entry_hasher): Likewise.
	* ipa-devirt.c (odr_name_hasher): Likewise.
	(polymorphic_call_target_hasher): Likewise.
	* ira-costs.c (cost_classes_hasher): Likewise.
	* statistics.c (stats_counter_hasher): Likewise.
	* trans-mem.c (log_entry_hasher): Likewise.
	* tree-ssa-dom.c (expr_elt_hasher): Likewise.
	* tree-ssa-sccvn.c (vn_phi_hasher, vn_reference_hasher): Likewise.
	* tree-ssa-tail-merge.c (same_succ_def): Likewise.
	* var-tracking.c (variable_hasher): Likewise.
	* valtrack.h (dead_debug_hash_descr): Inherit from free_ptr_hash.
	Remove redundant typedefs and members.

Index: gcc/cgraph.h
===================================================================
--- gcc/cgraph.h	2015-06-15 16:05:17.879281703 +0100
+++ gcc/cgraph.h	2015-06-15 16:05:17.863281887 +0100
@@ -1868,17 +1868,12 @@ enum symtab_state
   FINISHED
 };
 
-struct asmname_hasher
+struct asmname_hasher : ggc_ptr_hash <symtab_node>
 {
-  typedef symtab_node *value_type;
   typedef const_tree compare_type;
 
   static hashval_t hash (symtab_node *n);
   static bool equal (symtab_node *n, const_tree t);
-  static void ggc_mx (symtab_node *n);
-  static void pch_nx (symtab_node *&);
-  static void pch_nx (symtab_node *&, gt_pointer_operator, void *);
-  static void remove (symtab_node *) {}
 };
 
 class GTY((tag ("SYMTAB"))) symbol_table
@@ -2188,28 +2183,6 @@ asmname_hasher::equal (symtab_node *n, c
   return symbol_table::decl_assembler_name_equal (n->decl, t);
 }
 
-extern void gt_ggc_mx (symtab_node *&);
-
-inline void
-asmname_hasher::ggc_mx (symtab_node *n)
-{
-  gt_ggc_mx (n);
-}
-
-extern void gt_pch_nx (symtab_node *&);
-
-inline void
-asmname_hasher::pch_nx (symtab_node *&n)
-{
-  gt_pch_nx (n);
-}
-
-inline void
-asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie)
-{
-  op (&n, cookie);
-}
-
 /* In cgraph.c  */
 void cgraph_c_finalize (void);
 void release_function_body (tree);
Index: gcc/coverage.c
===================================================================
--- gcc/coverage.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/coverage.c	2015-06-15 16:05:17.867281842 +0100
@@ -88,7 +88,7 @@ struct GTY((chain_next ("%h.next"))) cov
 };
 
 /* Counts information for a function.  */
-typedef struct counts_entry
+typedef struct counts_entry : pointer_hash <counts_entry>
 {
   /* We hash by  */
   unsigned ident;
@@ -101,8 +101,6 @@ typedef struct counts_entry
   struct gcov_ctr_summary summary;
 
   /* hash_table support.  */
-  typedef counts_entry *value_type;
-  typedef counts_entry *compare_type;
   static inline hashval_t hash (const counts_entry *);
   static int equal (const counts_entry *, const counts_entry *);
   static void remove (counts_entry *);
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/dwarf2out.c	2015-06-15 16:05:17.875281749 +0100
@@ -6959,9 +6959,8 @@ struct cu_hash_table_entry
 
 /* Helpers to manipulate hash table of CUs.  */
 
-struct cu_hash_table_entry_hasher
+struct cu_hash_table_entry_hasher : pointer_hash <cu_hash_table_entry>
 {
-  typedef cu_hash_table_entry *value_type;
   typedef die_struct *compare_type;
   static inline hashval_t hash (const cu_hash_table_entry *);
   static inline bool equal (const cu_hash_table_entry *, const die_struct *);
Index: gcc/ipa-devirt.c
===================================================================
--- gcc/ipa-devirt.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/ipa-devirt.c	2015-06-15 16:05:17.875281749 +0100
@@ -385,9 +385,8 @@ type_possibly_instantiated_p (tree t)
 /* Hash used to unify ODR types based on their mangled name and for anonymous
    namespace types.  */
 
-struct odr_name_hasher
+struct odr_name_hasher : pointer_hash <odr_type_d>
 {
-  typedef odr_type_d *value_type;
   typedef union tree_node *compare_type;
   static inline hashval_t hash (const odr_type_d *);
   static inline bool equal (const odr_type_d *, const tree_node *);
@@ -2731,10 +2730,9 @@ struct polymorphic_call_target_d
 
 /* Polymorphic call target cache helpers.  */
 
-struct polymorphic_call_target_hasher 
+struct polymorphic_call_target_hasher
+  : pointer_hash <polymorphic_call_target_d>
 {
-  typedef polymorphic_call_target_d *value_type;
-  typedef polymorphic_call_target_d *compare_type;
   static inline hashval_t hash (const polymorphic_call_target_d *);
   static inline bool equal (const polymorphic_call_target_d *,
 			    const polymorphic_call_target_d *);
Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/ira-costs.c	2015-06-15 16:05:17.875281749 +0100
@@ -148,10 +148,8 @@ typedef const struct cost_classes *const
 
 /* Helper for cost_classes hashing.  */
 
-struct cost_classes_hasher
+struct cost_classes_hasher : pointer_hash <cost_classes>
 {
-  typedef cost_classes *value_type;
-  typedef cost_classes *compare_type;
   static inline hashval_t hash (const cost_classes *);
   static inline bool equal (const cost_classes *, const cost_classes *);
   static inline void remove (cost_classes *);
Index: gcc/statistics.c
===================================================================
--- gcc/statistics.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/statistics.c	2015-06-15 16:05:17.863281887 +0100
@@ -47,10 +47,8 @@ typedef struct statistics_counter_s {
 
 /* Hashtable helpers.  */
 
-struct stats_counter_hasher
+struct stats_counter_hasher : pointer_hash <statistics_counter_t>
 {
-  typedef statistics_counter_t *value_type;
-  typedef statistics_counter_t *compare_type;
   static inline hashval_t hash (const statistics_counter_t *);
   static inline bool equal (const statistics_counter_t *,
 			    const statistics_counter_t *);
Index: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/trans-mem.c	2015-06-15 16:05:17.867281842 +0100
@@ -958,10 +958,8 @@ typedef struct tm_log_entry
 
 /* Log entry hashtable helpers.  */
 
-struct log_entry_hasher
+struct log_entry_hasher : pointer_hash <tm_log_entry>
 {
-  typedef tm_log_entry *value_type;
-  typedef tm_log_entry *compare_type;
   static inline hashval_t hash (const tm_log_entry *);
   static inline bool equal (const tm_log_entry *, const tm_log_entry *);
   static inline void remove (tm_log_entry *);
Index: gcc/tree-ssa-dom.c
===================================================================
--- gcc/tree-ssa-dom.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/tree-ssa-dom.c	2015-06-15 16:05:17.875281749 +0100
@@ -169,10 +169,8 @@ static bool hashable_expr_equal_p (const
 				   const struct hashable_expr *);
 static void free_expr_hash_elt (void *);
 
-struct expr_elt_hasher
+struct expr_elt_hasher : pointer_hash <expr_hash_elt>
 {
-  typedef expr_hash_elt *value_type;
-  typedef expr_hash_elt *compare_type;
   static inline hashval_t hash (const value_type &);
   static inline bool equal (const value_type &, const compare_type &);
   static inline void remove (value_type &);
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/tree-ssa-sccvn.c	2015-06-15 16:05:17.875281749 +0100
@@ -172,10 +172,8 @@ typedef vn_nary_op_table_type::iterator
 static int
 vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
 
-struct vn_phi_hasher
+struct vn_phi_hasher : pointer_hash <vn_phi_s>
 { 
-  typedef vn_phi_s *value_type;
-  typedef vn_phi_s *compare_type;
   static inline hashval_t hash (const vn_phi_s *);
   static inline bool equal (const vn_phi_s *, const vn_phi_s *);
   static inline void remove (vn_phi_s *);
@@ -240,10 +238,8 @@ free_reference (vn_reference_s *vr)
 
 /* vn_reference hashtable helpers.  */
 
-struct vn_reference_hasher
+struct vn_reference_hasher : pointer_hash <vn_reference_s>
 {
-  typedef vn_reference_s *value_type;
-  typedef vn_reference_s *compare_type;
   static inline hashval_t hash (const vn_reference_s *);
   static inline bool equal (const vn_reference_s *, const vn_reference_s *);
   static inline void remove (vn_reference_s *);
Index: gcc/tree-ssa-tail-merge.c
===================================================================
--- gcc/tree-ssa-tail-merge.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/tree-ssa-tail-merge.c	2015-06-15 16:05:17.875281749 +0100
@@ -234,7 +234,7 @@ the Free Software Foundation; either ver
    Additionally, the hash value for the struct is cached in hashval, and
    in_worklist indicates whether it's currently part of worklist.  */
 
-struct same_succ_def
+struct same_succ_def : pointer_hash <same_succ_def>
 {
   /* The bbs that have the same successor bbs.  */
   bitmap bbs;
@@ -251,8 +251,6 @@ struct same_succ_def
   hashval_t hashval;
 
   /* hash_table support.  */
-  typedef same_succ_def *value_type;
-  typedef same_succ_def *compare_type;
   static inline hashval_t hash (const same_succ_def *);
   static int equal (const same_succ_def *, const same_succ_def *);
   static void remove (same_succ_def *);
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2015-06-15 16:05:17.879281703 +0100
+++ gcc/var-tracking.c	2015-06-15 16:05:17.875281749 +0100
@@ -525,9 +525,8 @@ static void variable_htab_free (void *);
 
 /* Variable hashtable helpers.  */
 
-struct variable_hasher
+struct variable_hasher : pointer_hash <variable_def>
 {
-  typedef variable_def *value_type;
   typedef void *compare_type;
   static inline hashval_t hash (const variable_def *);
   static inline bool equal (const variable_def *, const void *);
Index: gcc/valtrack.h
===================================================================
--- gcc/valtrack.h	2015-06-15 16:05:17.879281703 +0100
+++ gcc/valtrack.h	2015-06-15 16:05:17.875281749 +0100
@@ -41,18 +41,13 @@ struct dead_debug_global_entry
 /* Descriptor for hash_table to hash by dead_debug_global_entry's REG
    and map to DTEMP.  */
 
-struct dead_debug_hash_descr
+struct dead_debug_hash_descr : free_ptr_hash <dead_debug_global_entry>
 {
-  /* The hash table contains pointers to entries of this type.  */
-  typedef struct dead_debug_global_entry *value_type;
-  typedef struct dead_debug_global_entry *compare_type;
   /* Hash on the pseudo number.  */
   static inline hashval_t hash (const dead_debug_global_entry *my);
   /* Entries are identical if they refer to the same pseudo.  */
   static inline bool equal (const dead_debug_global_entry *my,
 			    const dead_debug_global_entry *other);
-  /* Release entries when they're removed.  */
-  static inline void remove (dead_debug_global_entry *p);
 };
 
 /* Hash on the pseudo number.  */
@@ -70,13 +65,6 @@ dead_debug_hash_descr::equal (const dead
   return my->reg == other->reg;
 }
 
-/* Release entries when they're removed.  */
-inline void
-dead_debug_hash_descr::remove (dead_debug_global_entry *p)
-{
-  XDELETE (p);
-}
-
 /* Maintain a global table of pseudos used in debug insns after their
    deaths in other blocks, and debug temps their deathpoint values are
    to be bound to.  */

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [08/13] Add a ggc_cache_ptr_hash
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (7 preceding siblings ...)
  2015-06-16  9:05 ` [09/13] Make remaining pointer hashes inherit from a generic class Richard Sandiford
@ 2015-06-16  9:05 ` Richard Sandiford
  2015-06-23 23:17   ` Jeff Law
  2015-06-16  9:12 ` [10/13] Require {mark,id}_{deleted,empty} functions Richard Sandiford
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:05 UTC (permalink / raw)
  To: gcc-patches

Like the previous patch, but for ggc_cache_hasher.

gcc/
	* hash-traits.h (ggc_cache_hasher): Rename to...
	(ggc_cache_remove): ...this and remove typedefs.
	(ggc_cache_ptr_hash): New class.
	* hash-table.h: Update commentary.
	* emit-rtl.c (const_int_hasher): Inherit from ggc_cache_ptr_hash
	rather than ggc_cache_hasher.
	(const_wide_int_hasher, reg_attr_hasher): Likewise.
	(const_double_hasher, const_fixed_hasher): Likewise.
	* function.c (insn_cache_hasher): Likewise.
	* trans-mem.c (tm_wrapper_hasher): Likewise.
	* tree.h (tree_decl_map_cache_hasher): Likewise.
	* tree.c (type_cache_hasher, int_cst_hasher): Likewise.
	(cl_option_hasher, tree_vec_map_cache_hasher): Likewise.
	* ubsan.c (tree_type_map_cache_hasher): Likewise.
	* varasm.c (tm_clone_hasher): Likewise.
	* config/i386/i386.c (dllimport_hasher): Likewise.
	* config/nvptx/nvptx.c (declared_libfunc_hasher): Likewise.
	(tree_hasher): Likewise.

gcc/ada/
	* gcc-interface/decl.c (value_annotation_hasher): Inherit from
	ggc_cache_ptr_hash rather than ggc_cache_hasher.
	* gcc-interface/utils.c (pad_type_hasher): Likewise.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 10:02:04.196341817 +0100
+++ gcc/hash-traits.h	2015-06-16 10:02:04.192341864 +0100
@@ -149,14 +149,12 @@ struct ggc_remove
   }
 };
 
-/* Hasher for cache entry in gc memory.  */
+/* Remover and marker for "cache" entries in gc memory.  These entries can
+   be deleted if there are no non-cache references to the data.  */
 
 template<typename T>
-struct ggc_cache_hasher : ggc_remove<T>
+struct ggc_cache_remove : ggc_remove<T>
 {
-  typedef T value_type;
-  typedef T compare_type;
-
   /* Entries are weakly held because this is for caches.  */
   static void ggc_mx (T &) {}
 
@@ -185,4 +183,11 @@ struct free_ptr_hash : pointer_hash <T>,
 template <typename T>
 struct ggc_ptr_hash : pointer_hash <T>, ggc_remove <T *> {};
 
+/* Traits for elements that point to gc memory.  The elements don't
+   in themselves keep the pointed-to data alive and they can be deleted
+   if the pointed-to data is going to be collected.  */
+
+template <typename T>
+struct ggc_cache_ptr_hash : pointer_hash <T>, ggc_cache_remove <T *> {};
+
 #endif
Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-16 10:02:04.196341817 +0100
+++ gcc/hash-table.h	2015-06-16 10:02:40.715918847 +0100
@@ -91,7 +91,7 @@ Software Foundation; either version 3, o
    We compose this into a few steps.
 
       1. Decide on a removal policy for values stored in the table.
-         hash-traits.h provides class templates for the three most common
+         hash-traits.h provides class templates for the four most common
          policies:
 
          * typed_free_remove implements the static 'remove' member function
@@ -105,6 +105,13 @@ Software Foundation; either version 3, o
          Use this for garbage-collected data that needs to be preserved across
          collections.
 
+         * ggc_cache_remove is like ggc_remove, except that it does not
+         mark the entries during the normal gc mark phase.  Instead it
+         uses 'keep_cache_entry' (described above) to keep elements that
+         were not collected and delete those that were.  Use this for
+         garbage-collected caches that should not in themselves stop
+         the data from being collected.
+
          You can use these policies by simply deriving the descriptor type
          from one of those class template, with the appropriate argument.
 
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/emit-rtl.c	2015-06-16 10:02:04.188341910 +0100
@@ -141,7 +141,7 @@ rtx const_tiny_rtx[4][(int) MAX_MACHINE_
 /* A hash table storing CONST_INTs whose absolute value is greater
    than MAX_SAVED_CONST_INT.  */
 
-struct const_int_hasher : ggc_cache_hasher<rtx>
+struct const_int_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   typedef HOST_WIDE_INT compare_type;
 
@@ -151,7 +151,7 @@ struct const_int_hasher : ggc_cache_hash
 
 static GTY ((cache)) hash_table<const_int_hasher> *const_int_htab;
 
-struct const_wide_int_hasher : ggc_cache_hasher<rtx>
+struct const_wide_int_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   static hashval_t hash (rtx x);
   static bool equal (rtx x, rtx y);
@@ -160,7 +160,7 @@ struct const_wide_int_hasher : ggc_cache
 static GTY ((cache)) hash_table<const_wide_int_hasher> *const_wide_int_htab;
 
 /* A hash table storing register attribute structures.  */
-struct reg_attr_hasher : ggc_cache_hasher<reg_attrs *>
+struct reg_attr_hasher : ggc_cache_ptr_hash<reg_attrs>
 {
   static hashval_t hash (reg_attrs *x);
   static bool equal (reg_attrs *a, reg_attrs *b);
@@ -169,7 +169,7 @@ struct reg_attr_hasher : ggc_cache_hashe
 static GTY ((cache)) hash_table<reg_attr_hasher> *reg_attrs_htab;
 
 /* A hash table storing all CONST_DOUBLEs.  */
-struct const_double_hasher : ggc_cache_hasher<rtx>
+struct const_double_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   static hashval_t hash (rtx x);
   static bool equal (rtx x, rtx y);
@@ -178,7 +178,7 @@ struct const_double_hasher : ggc_cache_h
 static GTY ((cache)) hash_table<const_double_hasher> *const_double_htab;
 
 /* A hash table storing all CONST_FIXEDs.  */
-struct const_fixed_hasher : ggc_cache_hasher<rtx>
+struct const_fixed_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   static hashval_t hash (rtx x);
   static bool equal (rtx x, rtx y);
Index: gcc/function.c
===================================================================
--- gcc/function.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/function.c	2015-06-16 10:02:04.188341910 +0100
@@ -123,7 +123,7 @@ struct function *cfun = 0;
 
 /* These hashes record the prologue and epilogue insns.  */
 
-struct insn_cache_hasher : ggc_cache_hasher<rtx>
+struct insn_cache_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   static hashval_t hash (rtx x) { return htab_hash_pointer (x); }
   static bool equal (rtx a, rtx b) { return a == b; }
Index: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/trans-mem.c	2015-06-16 10:02:04.188341910 +0100
@@ -474,7 +474,7 @@ build_tm_abort_call (location_t loc, boo
 /* Map for aribtrary function replacement under TM, as created
    by the tm_wrap attribute.  */
 
-struct tm_wrapper_hasher : ggc_cache_hasher<tree_map *>
+struct tm_wrapper_hasher : ggc_cache_ptr_hash<tree_map>
 {
   static inline hashval_t hash (tree_map *m) { return m->hash; }
   static inline bool
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	2015-06-16 10:02:04.196341817 +0100
+++ gcc/tree.h	2015-06-16 10:02:04.192341864 +0100
@@ -4628,7 +4628,7 @@ #define tree_decl_map_eq tree_map_base_e
 extern unsigned int tree_decl_map_hash (const void *);
 #define tree_decl_map_marked_p tree_map_base_marked_p
 
-struct tree_decl_map_cache_hasher : ggc_cache_hasher<tree_decl_map *>
+struct tree_decl_map_cache_hasher : ggc_cache_ptr_hash<tree_decl_map>
 {
   static hashval_t hash (tree_decl_map *m) { return tree_decl_map_hash (m); }
   static bool
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/tree.c	2015-06-16 10:02:04.188341910 +0100
@@ -198,7 +198,7 @@ struct GTY((for_user)) type_hash {
 /* Initial size of the hash table (rounded to next prime).  */
 #define TYPE_HASH_INITIAL_SIZE 1000
 
-struct type_cache_hasher : ggc_cache_hasher<type_hash *>
+struct type_cache_hasher : ggc_cache_ptr_hash<type_hash>
 {
   static hashval_t hash (type_hash *t) { return t->hash; }
   static bool equal (type_hash *a, type_hash *b);
@@ -222,7 +222,7 @@ static GTY ((cache)) hash_table<type_cac
 /* Hash table and temporary node for larger integer const values.  */
 static GTY (()) tree int_cst_node;
 
-struct int_cst_hasher : ggc_cache_hasher<tree>
+struct int_cst_hasher : ggc_cache_ptr_hash<tree_node>
 {
   static hashval_t hash (tree t);
   static bool equal (tree x, tree y);
@@ -238,7 +238,7 @@ static GTY ((cache)) hash_table<int_cst_
 static GTY (()) tree cl_optimization_node;
 static GTY (()) tree cl_target_option_node;
 
-struct cl_option_hasher : ggc_cache_hasher<tree>
+struct cl_option_hasher : ggc_cache_ptr_hash<tree_node>
 {
   static hashval_t hash (tree t);
   static bool equal (tree x, tree y);
@@ -255,7 +255,7 @@ static GTY ((cache))
 static GTY ((cache))
      hash_table<tree_decl_map_cache_hasher> *value_expr_for_decl;
 
-struct tree_vec_map_cache_hasher : ggc_cache_hasher<tree_vec_map *>
+struct tree_vec_map_cache_hasher : ggc_cache_ptr_hash<tree_vec_map>
 {
   static hashval_t hash (tree_vec_map *m) { return DECL_UID (m->base.from); }
 
Index: gcc/ubsan.c
===================================================================
--- gcc/ubsan.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/ubsan.c	2015-06-16 10:02:04.192341864 +0100
@@ -85,7 +85,7 @@ struct GTY((for_user)) tree_type_map {
   tree decl;
 };
 
-struct tree_type_map_cache_hasher : ggc_cache_hasher<tree_type_map *>
+struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
 {
   static inline hashval_t
   hash (tree_type_map *t)
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/varasm.c	2015-06-16 10:02:04.192341864 +0100
@@ -5792,7 +5792,7 @@ assemble_alias (tree decl, tree target)
    to its transaction aware clone.  Note that tm_pure functions are
    considered to be their own clone.  */
 
-struct tm_clone_hasher : ggc_cache_hasher<tree_map *>
+struct tm_clone_hasher : ggc_cache_ptr_hash<tree_map>
 {
   static hashval_t hash (tree_map *m) { return tree_map_hash (m); }
   static bool equal (tree_map *a, tree_map *b) { return tree_map_eq (a, b); }
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/config/i386/i386.c	2015-06-16 10:02:04.184341957 +0100
@@ -14203,7 +14203,7 @@ legitimize_tls_address (rtx x, enum tls_
    to symbol DECL if BEIMPORT is true.  Otherwise create or return the
    unique refptr-DECL symbol corresponding to symbol DECL.  */
 
-struct dllimport_hasher : ggc_cache_hasher<tree_map *>
+struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
 {
   static inline hashval_t hash (tree_map *m) { return m->hash; }
   static inline bool
Index: gcc/config/nvptx/nvptx.c
===================================================================
--- gcc/config/nvptx/nvptx.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/config/nvptx/nvptx.c	2015-06-16 10:02:04.184341957 +0100
@@ -67,7 +67,7 @@
    decls corresponding to them.  */
 static std::stringstream func_decls;
 
-struct declared_libfunc_hasher : ggc_cache_hasher<rtx>
+struct declared_libfunc_hasher : ggc_cache_ptr_hash<rtx_def>
 {
   static hashval_t hash (rtx x) { return htab_hash_pointer (x); }
   static bool equal (rtx a, rtx b) { return a == b; }
@@ -76,7 +76,7 @@ struct declared_libfunc_hasher : ggc_cac
 static GTY((cache))
   hash_table<declared_libfunc_hasher> *declared_libfuncs_htab;
 
-  struct tree_hasher : ggc_cache_hasher<tree>
+struct tree_hasher : ggc_cache_ptr_hash<tree_node>
 {
   static hashval_t hash (tree t) { return htab_hash_pointer (t); }
   static bool equal (tree a, tree b) { return a == b; }
Index: gcc/ada/gcc-interface/decl.c
===================================================================
--- gcc/ada/gcc-interface/decl.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/ada/gcc-interface/decl.c	2015-06-16 10:02:04.172342095 +0100
@@ -135,7 +135,7 @@ typedef struct variant_desc_d {
 
 /* A hash table used to cache the result of annotate_value.  */
 
-struct value_annotation_hasher : ggc_cache_hasher<tree_int_map *>
+struct value_annotation_hasher : ggc_cache_ptr_hash<tree_int_map>
 {
   static inline hashval_t
   hash (tree_int_map *m)
Index: gcc/ada/gcc-interface/utils.c
===================================================================
--- gcc/ada/gcc-interface/utils.c	2015-06-16 10:02:04.196341817 +0100
+++ gcc/ada/gcc-interface/utils.c	2015-06-16 10:02:04.176342049 +0100
@@ -239,7 +239,7 @@ struct GTY((for_user)) pad_type_hash {
   tree type;
 };
 
-struct pad_type_hasher : ggc_cache_hasher<pad_type_hash *>
+struct pad_type_hasher : ggc_cache_ptr_hash<pad_type_hash>
 {
   static inline hashval_t hash (pad_type_hash *t) { return t->hash; }
   static bool equal (pad_type_hash *a, pad_type_hash *b);

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [10/13] Require {mark,id}_{deleted,empty} functions
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (8 preceding siblings ...)
  2015-06-16  9:05 ` [08/13] Add a ggc_cache_ptr_hash Richard Sandiford
@ 2015-06-16  9:12 ` Richard Sandiford
  2015-06-23 23:18   ` Jeff Law
  2015-06-16  9:13 ` [11/13] Generalise typed_noop_remove Richard Sandiford
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:12 UTC (permalink / raw)
  To: gcc-patches

After the previous changes, all traits classes provide an implementation
of the empty & deleted entry functions, so we can remove the code that
provided defaults.

gcc/
	* hash-table.h (has_is_deleted, is_deleted_helper): Delete.
	(has_is_empty, is_empty_helper): Delete.
	(has_mark_deleted, mark_deleted_helper): Delete.
	(has_mark_empty, mark_empty_helper): Delete.
	(hash_table::is_deleted): Call the Descriptor unconditionally.
	(hash_table::is_empty): Likewise.
	(hash_table::mark_deleted): Likewise.
	(hash_table::mark_empty): Likewise.

Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-16 10:10:16.374654332 +0100
+++ gcc/hash-table.h	2015-06-16 10:10:16.370654379 +0100
@@ -323,122 +323,6 @@ hash_table_mod2 (hashval_t hash, unsigne
   return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
 }
 
- template<typename Traits>
- struct has_is_deleted
-{
-  template<typename U, bool (*)(U &)> struct helper {};
-  template<typename U> static char test (helper<U, U::is_deleted> *);
-  template<typename U> static int test (...);
-  static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
-};
-
-template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
-struct is_deleted_helper
-{
-  static inline bool
-  call (Type &v)
-  {
-    return Traits::is_deleted (v);
-  }
-};
-
-template<typename Type, typename Traits>
-struct is_deleted_helper<Type *, Traits, false>
-{
-  static inline bool
-  call (Type *v)
-  {
-    return v == HTAB_DELETED_ENTRY;
-  }
-};
-
- template<typename Traits>
- struct has_is_empty
-{
-  template<typename U, bool (*)(U &)> struct helper {};
-  template<typename U> static char test (helper<U, U::is_empty> *);
-  template<typename U> static int test (...);
-  static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
-};
-
-template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
-struct is_empty_helper
-{
-  static inline bool
-  call (Type &v)
-  {
-    return Traits::is_empty (v);
-  }
-};
-
-template<typename Type, typename Traits>
-struct is_empty_helper<Type *, Traits, false>
-{
-  static inline bool
-  call (Type *v)
-  {
-    return v == HTAB_EMPTY_ENTRY;
-  }
-};
-
- template<typename Traits>
- struct has_mark_deleted
-{
-  template<typename U, void (*)(U &)> struct helper {};
-  template<typename U> static char test (helper<U, U::mark_deleted> *);
-  template<typename U> static int test (...);
-  static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
-};
-
-template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
-struct mark_deleted_helper
-{
-  static inline void
-  call (Type &v)
-  {
-    Traits::mark_deleted (v);
-  }
-};
-
-template<typename Type, typename Traits>
-struct mark_deleted_helper<Type *, Traits, false>
-{
-  static inline void
-  call (Type *&v)
-  {
-    v = static_cast<Type *> (HTAB_DELETED_ENTRY);
-  }
-};
-
- template<typename Traits>
- struct has_mark_empty
-{
-  template<typename U, void (*)(U &)> struct helper {};
-  template<typename U> static char test (helper<U, U::mark_empty> *);
-  template<typename U> static int test (...);
-  static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
-};
-
-template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
-struct mark_empty_helper
-{
-  static inline void
-  call (Type &v)
-  {
-    Traits::mark_empty (v);
-  }
-};
-
-template<typename Type, typename Traits>
-struct mark_empty_helper<Type *, Traits, false>
-{
-  static inline void
-  call (Type *&v)
-  {
-    v = static_cast<Type *> (HTAB_EMPTY_ENTRY);
-  }
-};
-
 class mem_usage;
 
 /* User-facing hash table type.
@@ -610,23 +494,24 @@ struct mark_empty_helper<Type *, Traits,
   value_type *find_empty_slot_for_expand (hashval_t);
   void expand ();
   static bool is_deleted (value_type &v)
-    {
-      return is_deleted_helper<value_type, Descriptor>::call (v);
-    }
+  {
+    return Descriptor::is_deleted (v);
+  }
+
   static bool is_empty (value_type &v)
-    {
-      return is_empty_helper<value_type, Descriptor>::call (v);
-    }
+  {
+    return Descriptor::is_empty (v);
+  }
 
   static void mark_deleted (value_type &v)
-    {
-      return mark_deleted_helper<value_type, Descriptor>::call (v);
-    }
+  {
+    Descriptor::mark_deleted (v);
+  }
 
   static void mark_empty (value_type &v)
-    {
-      return mark_empty_helper<value_type, Descriptor>::call (v);
-    }
+  {
+    Descriptor::mark_empty (v);
+  }
 
   /* Table itself.  */
   typename Descriptor::value_type *m_entries;

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [11/13] Generalise typed_noop_remove
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (9 preceding siblings ...)
  2015-06-16  9:12 ` [10/13] Require {mark,id}_{deleted,empty} functions Richard Sandiford
@ 2015-06-16  9:13 ` Richard Sandiford
  2015-06-23 23:20   ` Jeff Law
  2015-06-16  9:17 ` [12/13] Reuse hash_table traits for hash_set Richard Sandiford
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:13 UTC (permalink / raw)
  To: gcc-patches

The traits interface is supposed to support non-pointer element types,
so there's no real reason for typed_noop_remove to be specifically for
pointers.  It should be usable by anything that wants a no-op remove().

gcc/
	* hash-traits.h (typed_noop_remove): Don't require a pointer type.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-15 16:05:24.059210397 +0100
+++ gcc/hash-traits.h	2015-06-15 16:05:24.051210490 +0100
@@ -44,7 +44,7 @@ typed_free_remove <Type>::remove (Type *
 template <typename Type>
 struct typed_noop_remove
 {
-  static inline void remove (Type *p);
+  static inline void remove (Type &);
 };
 
 
@@ -52,7 +52,7 @@ struct typed_noop_remove
 
 template <typename Type>
 inline void
-typed_noop_remove <Type>::remove (Type *p ATTRIBUTE_UNUSED)
+typed_noop_remove <Type>::remove (Type &)
 {
 }
 
@@ -169,7 +169,7 @@ struct ggc_cache_remove : ggc_remove<T>
    is deleted.  */
 
 template <typename T>
-struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T> {};
+struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T *> {};
 
 /* Traits for pointer elements that should be freed via free() when an
    element is deleted.  */

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [12/13] Reuse hash_table traits for hash_set
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (10 preceding siblings ...)
  2015-06-16  9:13 ` [11/13] Generalise typed_noop_remove Richard Sandiford
@ 2015-06-16  9:17 ` Richard Sandiford
  2015-06-23 23:20   ` Jeff Law
  2015-06-16  9:23 ` [13/13] Update comments in hash-table.h Richard Sandiford
  2015-06-23 20:36 ` [00/13] Share hash traits between hash_table and hash_set Jeff Law
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:17 UTC (permalink / raw)
  To: gcc-patches

This is the main patch, to reuse the hash_table traits for hash_set.
The idea is to replace the untemplated default_hashset_traits with a
templated default_hash_traits, which gives the default traits for a
given type.  This allows things like hash_set<void *> to continue
to work.

For now I've left default_hash_traits without a default implementation.
It could instead be defined to inherit its argument, so that hash_set
<free_ptr_hash <foo> > would work.  I didn't do that because I don't
have a use case, but it seems like a reasonably clean approach if
needed.

gcc/
	* hash-traits.h (default_hash_traits): New structure.
	* hash-set.h (default_hashset_traits): Delete.
	(hash_set): Use default_hash_traits<Key> instead of
	default_hashset_traits.  Delete hash_entry type and use Key directly.
	* ipa-devirt.c (pair_traits): Delete.
	(default_hash_traits <type_pair>): Override.
	(odr_subtypes_equivalent_p): Remove pair_types template parameter.
	(odr_types_equivalent_p, add_type_duplicate): Likewise.

Index: gcc/hash-traits.h
===================================================================
--- gcc/hash-traits.h	2015-06-16 10:12:56.580811647 +0100
+++ gcc/hash-traits.h	2015-06-16 10:12:56.576811695 +0100
@@ -190,4 +190,9 @@ struct ggc_ptr_hash : pointer_hash <T>,
 template <typename T>
 struct ggc_cache_ptr_hash : pointer_hash <T>, ggc_cache_remove <T *> {};
 
+template <typename T> struct default_hash_traits;
+
+template <typename T>
+struct default_hash_traits <T *> : ggc_ptr_hash <T> {};
+
 #endif
Index: gcc/hash-set.h
===================================================================
--- gcc/hash-set.h	2015-06-16 10:12:56.580811647 +0100
+++ gcc/hash-set.h	2015-06-16 10:12:56.572811743 +0100
@@ -21,162 +21,9 @@ Software Foundation; either version 3, o
 #ifndef hash_set_h
 #define hash_set_h
 
-/* implement default behavior for traits when types allow it.  */
-
-struct default_hashset_traits
-{
-  /* Hashes the passed in key.  */
-
-  template<typename T>
-  static hashval_t
-  hash (T *p)
-    {
-      return uintptr_t (p) >> 3;
-    }
-
-  template<typename T> static hashval_t hash(const T &v) { return v; }
-
-  /* Return true if the two keys passed as arguments are equal.  */
-
-  template<typename T>
-  static bool
-  equal (const T &a, const T &b)
-    {
-      return a == b;
-    }
-
-  /* Called to dispose of the key before marking the entry as deleted.  */
-
-  template<typename T> static void remove (T &v) { v.~T (); }
-
-  /* Mark the passed in entry as being deleted.  */
-
-  template<typename T>
-  static void
-  mark_deleted (T *&e)
-    {
-      e = reinterpret_cast<void *> (1);
-    }
-
-  /* Mark the passed in entry as being empty.  */
-
-  template<typename T>
-  static void
-  mark_empty (T *&e)
-    {
-      e = NULL;
-    }
-
-  /* Return true if the passed in entry is marked as deleted.  */
-
-  template<typename T>
-  static bool
-  is_deleted (T *e)
-    {
-      return e == reinterpret_cast<void *> (1);
-    }
-
-  /* Return true if the passed in entry is marked as empty.  */
-
-  template<typename T> static bool is_empty (T *e) { return e == NULL; }
-
-  /* ggc walking routine, mark all objects refered to by this one.  */
-
-  template<typename T>
-  static void
-  ggc_mx (T &x)
-    {
-      extern void gt_ggc_mx (T &);
-      gt_ggc_mx (x);
-    }
-
-  /* pch walking routine, note all objects refered to by this element.  */
-
-  template<typename T>
-  static void
-  pch_nx (T &x)
-    {
-      extern void gt_pch_nx (T &);
-      gt_pch_nx (x);
-    }
-};
-
-template<typename Key, typename Traits = default_hashset_traits>
+template<typename Key, typename Traits = default_hash_traits<Key> >
 class hash_set
 {
-  struct hash_entry
-  {
-    Key m_key;
-
-    typedef hash_entry value_type;
-    typedef Key compare_type;
-
-    static hashval_t hash (const hash_entry &e)
-      {
-       	return Traits::hash (e.m_key);
-      }
-
-    static bool equal (const hash_entry &a, const Key &b)
-       	{
-	  return Traits::equal (a.m_key, b);
-       	}
-
-    static void remove (hash_entry &e) { Traits::remove (e.m_key); }
-
-    static void
-    mark_deleted (hash_entry &e)
-      {
-       	Traits::mark_deleted (e.m_key);
-      }
-
-    static bool is_deleted (const hash_entry &e)
-      {
-       	return Traits::is_deleted (e.m_key);
-      }
-
-    static void
-    mark_empty (hash_entry &e)
-      {
-	Traits::mark_empty (e.m_key);
-      }
-
-    static bool
-    is_empty (const hash_entry &e)
-      {
-	return Traits::is_empty (e.m_key);
-      }
-
-    static void ggc_mx (hash_entry &e)
-      {
-	Traits::ggc_mx (e.m_key);
-      }
-
-    static void pch_nx (hash_entry &e)
-      {
-	Traits::pch_nx (e.m_key);
-      }
-
-    static void pch_nx (hash_entry &e, gt_pointer_operator op, void *c)
-      {
-	pch_nx_helper (e.m_key, op, c);
-      }
-
-  private:
-    template<typename T>
-    static void
-      pch_nx_helper (T &x, gt_pointer_operator op, void *cookie)
-	{
-	  gt_pch_nx (&x, op, cookie);
-	}
-
-    template<typename T>
-      static void
-      pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie)
-	{
-	  op (&x, cookie);
-	}
-  };
-
 public:
   explicit hash_set (size_t n = 13, bool ggc = false CXX_MEM_STAT_INFO)
     : m_table (n, ggc, true, HASH_SET_ORIGIN PASS_MEM_STAT) {}
@@ -196,11 +43,10 @@ template<typename Key, typename Traits =
 
   bool add (const Key &k)
     {
-      hash_entry *e = m_table.find_slot_with_hash (k, Traits::hash (k),
-						   INSERT);
-      bool existed = !hash_entry::is_empty (*e);
+      Key *e = m_table.find_slot_with_hash (k, Traits::hash (k), INSERT);
+      bool existed = !Traits::is_empty (*e);
       if (!existed)
-	e->m_key = k;
+	*e = k;
 
       return existed;
     }
@@ -209,8 +55,8 @@ template<typename Key, typename Traits =
 
   bool contains (const Key &k)
     {
-      hash_entry &e = m_table.find_with_hash (k, Traits::hash (k));
-      return !Traits::is_empty (e.m_key);
+      Key &e = m_table.find_with_hash (k, Traits::hash (k));
+      return !Traits::is_empty (e);
     }
 
   /* Call the call back on each pair of key and value with the passed in
@@ -219,9 +65,9 @@ template<typename Key, typename Traits =
   template<typename Arg, bool (*f)(const Key &, Arg)>
   void traverse (Arg a) const
     {
-      for (typename hash_table<hash_entry>::iterator iter = m_table.begin ();
+      for (typename hash_table<Traits>::iterator iter = m_table.begin ();
 	   iter != m_table.end (); ++iter)
-	f ((*iter).m_key, a);
+	f (*iter, a);
     }
 
   /* Return the number of elements in the set.  */
@@ -234,7 +80,7 @@ template<typename Key, typename Traits =
   template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *);
       template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *, gt_pointer_operator, void *);
 
-  hash_table<hash_entry> m_table;
+  hash_table<Traits> m_table;
 };
 
 /* ggc marking routines.  */
Index: gcc/ipa-devirt.c
===================================================================
--- gcc/ipa-devirt.c	2015-06-16 10:12:56.580811647 +0100
+++ gcc/ipa-devirt.c	2015-06-16 10:12:56.576811695 +0100
@@ -164,8 +164,11 @@ typedef struct
   tree second;
 } type_pair;
 
-struct pair_traits : default_hashset_traits
+template <>
+struct default_hash_traits <type_pair> : typed_noop_remove <type_pair>
 {
+  typedef type_pair value_type;
+  typedef type_pair compare_type;
   static hashval_t
   hash (type_pair p)
   {
@@ -194,7 +197,7 @@ struct pair_traits : default_hashset_tra
 };
 
 static bool odr_types_equivalent_p (tree, tree, bool, bool *,
-				    hash_set<type_pair,pair_traits> *,
+				    hash_set<type_pair> *,
 				    location_t, location_t);
 
 static bool odr_violation_reported = false;
@@ -771,7 +774,7 @@ set_type_binfo (tree type, tree binfo)
 
 static bool
 odr_subtypes_equivalent_p (tree t1, tree t2,
-			   hash_set<type_pair,pair_traits> *visited,
+			   hash_set<type_pair> *visited,
 			   location_t loc1, location_t loc2)
 {
 
@@ -1337,7 +1340,7 @@ warn_types_mismatch (tree t1, tree t2, l
 
 static bool
 odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
-			hash_set<type_pair,pair_traits> *visited,
+			hash_set<type_pair> *visited,
 			location_t loc1, location_t loc2)
 {
   /* Check first for the obvious case of pointer identity.  */
@@ -1787,7 +1790,7 @@ odr_types_equivalent_p (tree t1, tree t2
 bool
 odr_types_equivalent_p (tree type1, tree type2)
 {
-  hash_set<type_pair,pair_traits> visited;
+  hash_set<type_pair> visited;
 
 #ifdef ENABLE_CHECKING
   gcc_assert (odr_or_derived_type_p (type1) && odr_or_derived_type_p (type2));
@@ -1867,7 +1870,7 @@ add_type_duplicate (odr_type val, tree t
   bool base_mismatch = false;
   unsigned int i;
   bool warned = false;
-  hash_set<type_pair,pair_traits> visited;
+  hash_set<type_pair> visited;
 
   gcc_assert (in_lto_p);
   vec_safe_push (val->types, type);

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [13/13] Update comments in hash-table.h
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (11 preceding siblings ...)
  2015-06-16  9:17 ` [12/13] Reuse hash_table traits for hash_set Richard Sandiford
@ 2015-06-16  9:23 ` Richard Sandiford
  2015-06-23 23:21   ` Jeff Law
  2015-06-23 20:36 ` [00/13] Share hash traits between hash_table and hash_set Jeff Law
  13 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-16  9:23 UTC (permalink / raw)
  To: gcc-patches

This updates the commentary in hash-table.h for the changes in this
series and fixes some cases that were already out of date.  It also has
a couple of trivial formatting fixes.

gcc/
	* hash-table.h: Update comments.

Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h	2015-06-15 16:05:53.294873079 +0100
+++ gcc/hash-table.h	2015-06-15 16:05:53.286873170 +0100
@@ -37,15 +37,16 @@ Software Foundation; either version 3, o
          - A typedef named 'value_type' to the value type (from above).
 
          - A static member function named 'hash' that takes a value_type
-         pointer and returns a hashval_t value.
+         (or 'const value_type &') and returns a hashval_t value.
 
-         - A typedef named 'compare_type' that is used to test when an value
+         - A typedef named 'compare_type' that is used to test when a value
          is found.  This type is the comparison type.  Usually, it will be the
          same as value_type.  If it is not the same type, you must generally
          explicitly compute hash values and pass them to the hash table.
 
          - A static member function named 'equal' that takes a value_type
-         pointer and a compare_type pointer, and returns a bool.
+         and a compare_type, and returns a bool.  Both arguments can be
+         const references.
 
          - A static function named 'remove' that takes an value_type pointer
          and frees the memory allocated by it.  This function is used when
@@ -68,7 +69,7 @@ Software Foundation; either version 3, o
 
       4. The template type used to describe how hash table memory
       is allocated.  This type is called the allocator type.  It is
-      parameterized on the value type.  It provides four functions.
+      parameterized on the value type.  It provides two functions:
 
          - A static member function named 'data_alloc'.  This function
          allocates the data elements in the table.
@@ -120,10 +121,16 @@ Software Foundation; either version 3, o
 
       2. Choose a hash function.  Write the static 'hash' member function.
 
-      3. Choose an equality testing function.  In most cases, its two
-      arguments will be value_type pointers.  If not, the first argument must
-      be a value_type pointer, and the second argument a compare_type pointer.
-
+      3. Decide whether the lookup function should take as input an object
+	 of type value_type or something more restricted.  Define compare_type
+	 accordingly.
+
+      4. Choose an equality testing function 'equal' that compares a value_type
+	 and a compare_type.
+
+   If your elements are pointers, it is usually easiest to start with one
+   of the generic pointer descriptors described below and override the bits
+   you need to change.
 
    AN EXAMPLE DESCRIPTOR TYPE
 
@@ -163,11 +170,19 @@ Software Foundation; either version 3, o
 
    EASY DESCRIPTORS FOR POINTERS
 
-   The class template pointer_hash provides everything you need to hash
-   pointers (as opposed to what they point to).  So, to instantiate a hash
-   table over pointers to whatever_type,
+   There are four descriptors for pointer elements, one for each of
+   the removal policies above:
+
+   * nofree_ptr_hash (based on typed_noop_remove)
+   * free_ptr_hash (based on typed_free_remove)
+   * ggc_ptr_hash (based on ggc_remove)
+   * ggc_cache_ptr_hash (based on ggc_cache_remove)
+
+   These descriptors hash and compare elements by their pointer value,
+   rather than what they point to.  So, to instantiate a hash table over
+   pointers to whatever_type, without freeing the whatever_types, use:
 
-      hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
+      hash_table <nofree_ptr_hash <whatever_type> > whatever_type_hash_table;
 
 
    HASH TABLE ITERATORS
@@ -327,20 +342,9 @@ hash_table_mod2 (hashval_t hash, unsigne
 
 /* User-facing hash table type.
 
-   The table stores elements of type Descriptor::value_type.
-
-   It hashes values with the hash member function.
-     The table currently works with relatively weak hash functions.
-     Use typed_pointer_hash <Value> when hashing pointers instead of objects.
-
-   It compares elements with the equal member function.
-     Two elements with the same hash may not be equal.
-     Use typed_pointer_equal <Value> when hashing pointers instead of objects.
-
-   It removes elements with the remove member function.
-     This feature is useful for freeing memory.
-     Derive from typed_null_remove <Value> when not freeing objects.
-     Derive from typed_free_remove <Value> when doing a simple object free.
+   The table stores elements of type Descriptor::value_type and uses
+   the static descriptor functions described at the top of the file
+   to hash, compare and remove elements.
 
    Specify the template Allocator to allocate and free memory.
      The default is xcallocator.
@@ -363,7 +367,6 @@ hash_table_mod2 (hashval_t hash, unsigne
   ~hash_table ();
 
   /* Create a hash_table in gc memory.  */
-
   static hash_table *
   create_ggc (size_t n CXX_MEM_STAT_INFO)
   {
@@ -387,7 +390,6 @@ hash_table_mod2 (hashval_t hash, unsigne
   /* This function clears a specified SLOT in a hash table.  It is
      useful when you've already done the lookup and don't want to do it
      again. */
-
   void clear_slot (value_type *);
 
   /* This function searches for a hash table entry equal to the given
@@ -395,7 +397,7 @@ hash_table_mod2 (hashval_t hash, unsigne
      be used to insert or delete an element. */
   value_type &find_with_hash (const compare_type &, hashval_t);
 
-/* Like find_slot_with_hash, but compute the hash value from the element.  */
+  /* Like find_slot_with_hash, but compute the hash value from the element.  */
   value_type &find (const value_type &value)
     {
       return find_with_hash (value, Descriptor::hash (value));
@@ -421,7 +423,8 @@ hash_table_mod2 (hashval_t hash, unsigne
      matching element in the hash table, this function does nothing. */
   void remove_elt_with_hash (const compare_type &, hashval_t);
 
-/* Like remove_elt_with_hash, but compute the hash value from the element.  */
+  /* Like remove_elt_with_hash, but compute the hash value from the
+     element.  */
   void remove_elt (const value_type &value)
     {
       remove_elt_with_hash (value, Descriptor::hash (value));
@@ -662,7 +665,7 @@ hash_table<Descriptor, Allocator>::find_
    table entries is changed.  If memory allocation fails, this function
    will abort.  */
 
-	  template<typename Descriptor, template<typename Type> class Allocator>
+template<typename Descriptor, template<typename Type> class Allocator>
 void
 hash_table<Descriptor, Allocator>::expand ()
 {

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [00/13] Share hash traits between hash_table and hash_set
  2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
                   ` (12 preceding siblings ...)
  2015-06-16  9:23 ` [13/13] Update comments in hash-table.h Richard Sandiford
@ 2015-06-23 20:36 ` Jeff Law
  13 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 20:36 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:42 AM, Richard Sandiford wrote:
> At the moment we need separate traits classes for hash_table, hash_set
> and hash_map.  I think that's a sign that we don't have the right
> abstraction.
You're probably right.

>
> The aim of this series is to unify the traits for hash_table and hash_set.
> If that's OK, I'll look at adding default hash_map traits for the common
> case in which the deleted/empty information is stored in the key rather
> than the value and where hash_table traits could be used.
>
> There were various things I needed to change along the way:
>
> - Our one generic hasher, pointer_hash, inherits from typed_noop_remove.
>    In other words, it's specifically for cases where the pointer isn't
>    freed when an entry is deleted.  That seems a bit arbitrary.  I think
>    we should separate out the hashing and the removing aspects.
Seems wise.  Certainly doesn't feel right that hashing and removing are 
tied together like this (/me scurries off to see if this was my doing...)





>
>    Also, typed_noop_remove and typed_free_remove don't provide hashing typedefs,
>    but the ggc equivalents ggc_hasher and ggc_cache_hasher do.  If we separate
>    the hashing and removing aspects, the typedefs belong to the hashing side.
Right.

>
>    Much of the awkwardness here is due to not having "proper" object
>    construction and destruction.  If we had that, the memory management
>    would be an integral part of the element type rather than being part
>    of the traits.  So I don't think adding a template parameter for the
>    element remover would necessarily be forward progress.
It's a common theme in GCC.

>
> - handle_cache_entry is too tied to the internals.  The generic
>    implementation is:
>
>      static void
>      handle_cache_entry (T &e)
>      {
>        if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
> 	e = static_cast<T> (HTAB_DELETED_ENTRY);
>      }
>
>    and a typical override looks like:
>
>      void
>      pad_type_hasher::handle_cache_entry (pad_type_hash *&t)
>      {
>        extern void gt_ggc_mx (pad_type_hash *&);
>        if (t == HTAB_EMPTY_ENTRY || t == HTAB_DELETED_ENTRY)
> 	return;
>        else if (ggc_marked_p (t->type))
> 	gt_ggc_mx (t);
>        else
> 	t = static_cast<pad_type_hash *> (HTAB_DELETED_ENTRY);
>      }
>
>    In particular, this bypasses the normal remove() function, so we never
>    update m_n_deleted.
>
>    ISTM the (single) caller should be checking for empty and deleted items
>    first and handling any deletion itself.  All we want to know from the
>    traits is which of the following applies:
>
>    - the entry should be deleted
>    - the entry should be kept and needs to be marked
>    - the entry should be kept and is already marked (an optimisation of
>      the previous case).
>
>    The patch adds a keep_cache_entry function to provide this information.
Seems like this is a result of having the memory management being part 
of the traits rather than the element.

Thanks for the detailed overview...  Onward to the patches.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [01/13] Move hash traits to their own header file
  2015-06-16  8:46 ` [01/13] Move hash traits to their own header file Richard Sandiford
@ 2015-06-23 20:53   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 20:53 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:43 AM, Richard Sandiford wrote:
> This patch just moves the traits classes to their own header file,
> hash-traits.h.
>
> gcc/
> 	* hash-table.h: Include hash-traits.h.
> 	(typed_free_remove, typed_noop_remove, pointer_hash, ggc_hasher)
> 	(ggc_cache_hasher): Move to...
> 	* hash-traits.h: ...this new file.
This is fine.

In fact, I think that we probably should just have a policy that moving 
bits like this into a new file should be considered obviously OK after 
the usual bootstrap and regression test.

jeff


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-06-16  8:46 ` [02/13] Replace handle_cache_entry with new interface Richard Sandiford
@ 2015-06-23 20:55   ` Jeff Law
  2015-06-24  8:23     ` Richard Sandiford
  2015-07-01  9:41   ` Trevor Saunders
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff Law @ 2015-06-23 20:55 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:45 AM, Richard Sandiford wrote:
> As described in the covering note, this patch replaces handle_cache_entry
> with a new function keep_cache_entry.  It also ensures that elements are
> deleted using the proper function, so that m_n_deleted is updated.
>
> I couldn't tell whether the unusual name of the function
> ("gt_cleare_cache") is deliberate or not, but I left it be.
Short-hand for clear_entry or something similar?


>
> gcc/ada/
> 	* gcc-interface/decl.c (value_annotation_hasher::handle_cache_entry):
> 	Delete.
> 	(value_annotation_hasher::keep_cache_entry): New function.
> 	* gcc-interface/utils.c (pad_type_hasher::handle_cache_entry):
> 	Delete.
> 	(pad_type_hasher::keep_cache_entry): New function.
>
> gcc/
> 	* hash-table.h (hash_table): Add gt_cleare_cache as a friend.
> 	(gt_cleare_cache): Check here for deleted and empty entries.
> 	Replace handle_cache_entry with a call to keep_cache_entry.
> 	* hash-traits.h (ggc_cache_hasher::handle_cache_entry): Delete.
> 	(ggc_cache_hasher::keep_cache_entry): New function.
> 	* trans-mem.c (tm_wrapper_hasher::handle_cache_entry): Delete.
> 	(tm_wrapper_hasher::keep_cache_entry): New function.
> 	* tree.h (tree_decl_map_cache_hasher::handle_cache_entry): Delete.
> 	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
> 	* tree.c (type_cache_hasher::handle_cache_entry): Delete.
> 	(type_cache_hasher::keep_cache_entry): New function.
> 	(tree_vec_map_cache_hasher::handle_cache_entry): Delete.
> 	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
> 	* ubsan.c (tree_type_map_cache_hasher::handle_cache_entry): Delete.
> 	(tree_type_map_cache_hasher::keep_cache_entry): New function.
> 	* varasm.c (tm_clone_hasher::handle_cache_entry): Delete.
> 	(tm_clone_hasher::keep_cache_entry): New function.
> 	* config/i386/i386.c (dllimport_hasher::handle_cache_entry): Delete.
> 	(dllimport_hasher::keep_cache_entry): New function.
So for all the keep_cache_entry functions, I guess they're trivial 
enough that a function comment probably isn't needed.  Presumably no 
good way to share the trivial implementation?

OK for the trunk.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [03/13] Make ggc_cached_hasher inherit from ggc_hasher
  2015-06-16  8:53 ` [03/13] Make ggc_cached_hasher inherit from ggc_hasher Richard Sandiford
@ 2015-06-23 20:56   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 20:56 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:52 AM, Richard Sandiford wrote:
> Most of ggc_cache_hasher is duplicated from ggc_hasher.  This patch
> gets the same functionality via inheritance.  It also brings the
> ggc_hasher functions in line with ggc_cache_hasher by making remove()
> and ggc_mx() take references rather than pointers.  This seems more
> consistent with the idea that elements don't need to be pointers and
> could be some gc-ed structure instead.
>
> gcc/
> 	* hash-traits.h (ggc_hasher::remove): Take a reference parameter.
> 	(ggc_hasher::ggc_mx): Likewise.
> 	(ggc_cache_hasher): Inherit from ggc_hasher.  Remove definitions
> 	that duplicate ggc_hasher ones.
OK.
jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [04/13] Add {mark,is}_{empty,deleted} to pointer_hash
  2015-06-16  8:55 ` [04/13] Add {mark,is}_{empty,deleted} to pointer_hash Richard Sandiford
@ 2015-06-23 21:00   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 21:00 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:53 AM, Richard Sandiford wrote:
> This patch just adds the standard pointer handling of empty and deleted
> entries.  As the series goes on, more and more traits classes will inherit
> these definitions, to the point where we can require the functions to exist.
>
> gcc/
> 	* hash-traits.h (pointer_hash::mark_deleted, pointer_hash::mark_empty)
> 	(pointer_hash::is_deleted, pointer_hash::is_empty): New functions.
OK.
jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-16  8:55 ` [05/13] Add nofree_ptr_hash Richard Sandiford
@ 2015-06-23 22:18   ` Jeff Law
  2015-06-24  8:42     ` Richard Sandiford
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff Law @ 2015-06-23 22:18 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:55 AM, Richard Sandiford wrote:
> This patch stops pointer_hash from inheriting typed_noop_remove and
> instead creates a new class nofree_ptr_hash that inherits from both.
> It then updates all uses of typed_noop_remove (which are all pointers)
> and pointer_hash so that they use this new class instead.
>
> gcc/
> 	* hash-table.h: Update comments.
> 	* hash-traits.h (pointer_hash): Don't inherit from typed_noop_remove.
> 	(nofree_ptr_hash): New class.
> 	* asan.c (asan_mem_ref_hasher): Inherit from nofree_ptr_hash rather
> 	than typed_noop_remove.  Remove redudant typedefs.
> 	* attribs.c (attribute_hasher): Likewise.
> 	* cfg.c (bb_copy_hasher): Likewise.
> 	* cselib.c (cselib_hasher): Likewise.
> 	* dse.c (invariant_group_base_hasher): Likewise.
> 	* dwarf2cfi.c (trace_info_hasher): Likewise.
> 	* dwarf2out.c (macinfo_entry_hasher): Likewise.
> 	(comdat_type_hasher, loc_list_hasher): Likewise.
> 	* gcse.c (pre_ldst_expr_hasher): Likewise.
> 	* genmatch.c (id_base): Likewise.
> 	* genrecog.c (test_pattern_hasher): Likewise.
> 	* gimple-ssa-strength-reduction.c (cand_chain_hasher): Likewise.
> 	* haifa-sched.c (delay_i1_hasher): Likewise.
> 	* hard-reg-set.h (simplifiable_subregs_hasher): Likewise.
> 	* ipa-icf.h (congruence_class_group_hash): Likewise.
> 	* ipa-profile.c (histogram_hash): Likewise.
> 	* ira-color.c (allocno_hard_regs_hasher): Likewise.
> 	* lto-streamer.h (string_slot_hasher): Likewise.
> 	* lto-streamer.c (tree_entry_hasher): Likewise.
> 	* plugin.c (event_hasher): Likewise.
> 	* postreload-gcse.c (expr_hasher): Likewise.
> 	* store-motion.c (st_expr_hasher): Likewise.
> 	* tree-sra.c (uid_decl_hasher): Likewise.
> 	* tree-ssa-coalesce.c (coalesce_pair_hasher): Likewise.
> 	(ssa_name_var_hash): Likewise.
> 	* tree-ssa-live.c (tree_int_map_hasher): Likewise.
> 	* tree-ssa-loop-im.c (mem_ref_hasher): Likewise.
> 	* tree-ssa-pre.c (pre_expr_d): Likewise.
> 	* tree-ssa-sccvn.c (vn_nary_op_hasher): Likewise.
> 	* vtable-verify.h (registration_hasher): Likewise.
> 	* vtable-verify.c (vtbl_map_hasher): Likewise.
> 	* config/arm/arm.c (libcall_hasher): Likewise.
> 	* config/i386/winnt.c (wrapped_symbol_hasher): Likewise.
> 	* config/ia64/ia64.c (bundle_state_hasher): Likewise.
> 	* config/sol2.c (comdat_entry_hasher): Likewise.
> 	* fold-const.c (fold): Use nofree_ptr_hash instead of pointer_hash.
> 	(print_fold_checksum, fold_checksum_tree): Likewise.
> 	(debug_fold_checksum, fold_build1_stat_loc): Likewise.
> 	(fold_build2_stat_loc, fold_build3_stat_loc): Likewise.
> 	(fold_build_call_array_loc): Likewise.
> 	* tree-ssa-ccp.c (gimple_htab): Likewise.
> 	* tree-browser.c (tree_upper_hasher): Inherit from nofree_ptr_hash
> 	rather than pointer_type.
>
> gcc/c/
> 	* c-decl.c (detect_field_duplicates_hash): Use nofree_ptr_hash
> 	instead of pointer_hash.
> 	(detect_field_duplicates): Likewise.
>
> gcc/cp/
> 	* class.c (fixed_type_or_null_ref_ht): Inherit from nofree_ptr_hash
> 	rather than pointer_hash.
> 	(fixed_type_or_null): Use nofree_ptr_hash instead of pointer_hash.
> 	* semantics.c (nrv_data): Likewise.
> 	* tree.c (verify_stmt_tree_r, verify_stmt_tree): Likewise.
>
> gcc/java/
> 	* jcf-io.c (charstar_hash): Inherit from nofree_ptr_hash rather
> 	than typed_noop_remove.  Remove redudant typedefs.
>
> gcc/lto/
> 	* lto.c (tree_scc_hasher): Inherit from nofree_ptr_hash rather
> 	than typed_noop_remove.  Remove redudant typedefs.
>
> gcc/objc/
> 	* objc-act.c (decl_name_hash): Inherit from nofree_ptr_hash rather
> 	than typed_noop_remove.  Remove redudant typedefs.
>
> libcc1/
> 	* plugin.cc (string_hasher): Inherit from nofree_ptr_hash rather
> 	than typed_noop_remove.  Remove redudant typedefs.
> 	(plugin_context): Use nofree_ptr_hash rather than pointer_hash.
> 	(plugin_context::mark): Likewise.
So are we allowing multiple inheritance in GCC?  It seems like that's 
what we've got for nofree_ptr_hash.  Is there a better way to achieve 
what you're trying to do, or do you think this use ought to fall under 
some kind of exception?


> Index: gcc/haifa-sched.c
> ===================================================================
> --- gcc/haifa-sched.c	2015-06-16 09:53:47.338092692 +0100
> +++ gcc/haifa-sched.c	2015-06-16 09:53:47.322092878 +0100
> @@ -614,9 +614,8 @@ struct delay_pair
>
>   /* Helpers for delay hashing.  */
>
> -struct delay_i1_hasher : typed_noop_remove <delay_pair>
> +struct delay_i1_hasher : nofree_ptr_hash <delay_pair>
>   {
> -  typedef delay_pair *value_type;
>     typedef void *compare_type;
>     static inline hashval_t hash (const delay_pair *);
>     static inline bool equal (const delay_pair *, const void *);
Did you keep compare_type intentionally?  Similarly for the changes in 
hard-reg-set.h, tree-ssa-loop-im.c, and tree-ssa-sccvn.c.  You probably 
did, but I just want to be sure.

So I'm holding off on approving this one pending further discussion of 
the use of multiple inheritance for nofree_ptr_hash.

Jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [06/13] Add free_ptr_hash
  2015-06-16  8:58 ` [06/13] Add free_ptr_hash Richard Sandiford
@ 2015-06-23 23:14   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:14 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 02:56 AM, Richard Sandiford wrote:
> Similarly to the last patch, this one adds a free_ptr_hash that inherits
> from both pointer_hash and typed_free_remove.
>
> gcc/
> 	* hash-traits.h (free_ptr_hash): New class.
> 	* dwarf2out.c (decl_table_entry_hasher): Inherit from free_ptr_hash
> 	rather than typed_free_remove.  Remove redudant typedefs.
> 	(external_ref_hasher): Likewise.
> 	* except.c (action_record_hasher, ttypes_filter_hasher): Likewise.
> 	(ehspec_hasher): Likewise.
> 	* ggc-common.c (saving_hasher): Likewise.
> 	* gimplify.c (gimplify_hasher): Likewise.
> 	* haifa-sched.c (delay_i2_hasher): Likewise.
> 	* loop-invariant.c (invariant_expr_hasher): Likewise.
> 	* loop-iv.c (biv_entry_hasher): Likewise.
> 	* loop-unroll.c (iv_split_hasher, var_expand_hasher): Likewise.
> 	* trans-mem.c (tm_mem_map_hasher, tm_memop_hasher): Likewise.
> 	* tree-cfg.c (locus_discrim_hasher): Likewise.
> 	* tree-eh.c (finally_tree_hasher): Likewise.
> 	* tree-into-ssa.c (var_info_hasher): Likewise.
> 	* tree-parloops.c (reduction_hasher, name_to_copy_hasher): Likewise.
> 	* tree-ssa-loop-ivopts.c (iv_inv_expr_hasher): Likewise.
> 	* tree-ssa-phiopt.c (ssa_names_hasher): Likewise.
> 	* tree-ssa-pre.c (expr_pred_trans_d): Likewise.
> 	* tree-ssa-sccvn.c (vn_constant_hasher): Likewise.
> 	* tree-ssa-structalias.c (equiv_class_hasher): Likewise.
> 	(shared_bitmap_hasher): Likewise.
> 	* tree-ssa-threadupdate.c (redirection_data): Likewise.
> 	* tree-vectorizer.h (peel_info_hasher): Likewise.
> 	* tree-vectorizer.c (simduid_to_vf, simd_array_to_simduid): Likewise.
> 	* config/mips/mips.c (mips_lo_sum_offset_hasher): Likewise.
>
> libcc1/
> 	* plugin.cc (decl_addr_hasher): Inherit from free_ptr_hash
> 	rather than typed_free_remove.  Remove redudant typedefs.
Same concern as last patch -- multiple inheritance.  Other than that it 
looks fine.  Will assume you've got the removal of typedefs right in 
cases where you just remove one of value_type vs compare_type.

jeff



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [07/13] Add ggc_ptr_hash
  2015-06-16  9:03 ` [07/13] Add ggc_ptr_hash Richard Sandiford
@ 2015-06-23 23:16   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:16 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:01 AM, Richard Sandiford wrote:
> This patch renames ggc_hasher to ggc_remove and removes the typedefs,
> to make it provide the same kind of interface as typed_noop_remove and
> typed_free_remove.  It then defines a new class ggc_ptr_hash that
> inherits from both pointer_hash and ggc_remove.  It changes all uses of
> ggc_hasher to use ggc_ptr_hash instead.
>
> gcc/
> 	* hash-traits.h (ggc_hasher): Rename to...
> 	(ggc_remover): ...this and remove typedefs.
> 	(ggc_cache_hasher): Update accordingly.  Add typedefs.
> 	(ggc_ptr_hash): New class.
> 	* hash-table.h: Update comment.
> 	* cfgloop.h (loop_exit_hasher): Inherit from ggc_ptr_hash rather than
> 	ggc_hasher.
> 	* cgraph.h (section_name_hasher, cgraph_edge_hasher): Likewise.
> 	(tree_descriptor_hasher): Likewise.
> 	* cgraph.c (function_version_hasher): Likewise.
> 	* dwarf2out.c (indirect_string_hasher, dwarf_file_hasher): Likewise.
> 	(decl_die_hasher, block_die_hasher, decl_loc_hasher): Likewise.
> 	(dw_loc_list_hasher, addr_hasher): Likewise.
> 	* function.h (used_type_hasher): Likewise.
> 	* function.c (temp_address_hasher): Likewise.
> 	* gimple-ssa.h (tm_restart_hasher, ssa_name_hasher): Likewise.
> 	* libfuncs.h (libfunc_hasher): Likewise.
> 	* lto-streamer.h (decl_state_hasher): Likewise.
> 	* optabs.c (libfunc_decl_hasher): Likewise.
> 	* tree-scalar-evolution.c (scev_info_hasher): Likewise.
> 	* varasm.c (section_hasher, object_block_hasher): Likewise.
> 	(const_rtx_desc_hasher): Likewise.
> 	* config/darwin.c (indirection_hasher, cfstring_hasher): Likewise.
> 	* config/rs6000/rs6000.c (toc_hasher, builtin_hasher): Likewise.
>
> gcc/c-family/
> 	* c-common.c (c_type_hasher): Inherit from ggc_ptr_hash rather than
> 	ggc_hasher.
>
> gcc/cp/
> 	* constexpr.c (constexpr_fundef_hasher): Inherit from ggc_ptr_hash
> 	rather than ggc_hasher.
> 	(constexpr_call_hasher): Likewise.
> 	* cp-tree.h (cxx_int_tree_map_hasher, named_label_hasher): Likewise.
> 	* decl.c (typename_hasher): Likewise.
> 	* mangle.c (conv_type_hasher): Likewise.
> 	* pt.c (spec_hasher): Likewise.
> 	* tree.c (cplus_array_hasher, list_hasher): Likewise.
> 	* typeck2.c (abstract_type_hasher): Likewise.
>
> gcc/fortran/
> 	* trans-decl.c (module_hasher): Likewise.
> 	* trans.h (module_decl_hasher): Likewise.
>
> gcc/java/
> 	* java-tree.h (treetreehasher): Inherit from ggc_ptr_hash
> 	rather than ggc_hasher.
> 	(ict_hasher, type_assertion_hasher): Likewise.
>
> gcc/objc/
> 	* objc-act.c (objc_string_hasher): Inherit from ggc_ptr_hash
> 	rather than ggc_hasher.
Same concern as #5 & #6, multiple inheritance.  Otherwise its fine.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [08/13] Add a ggc_cache_ptr_hash
  2015-06-16  9:05 ` [08/13] Add a ggc_cache_ptr_hash Richard Sandiford
@ 2015-06-23 23:17   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:17 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:03 AM, Richard Sandiford wrote:
> Like the previous patch, but for ggc_cache_hasher.
>
> gcc/
> 	* hash-traits.h (ggc_cache_hasher): Rename to...
> 	(ggc_cache_remove): ...this and remove typedefs.
> 	(ggc_cache_ptr_hash): New class.
> 	* hash-table.h: Update commentary.
> 	* emit-rtl.c (const_int_hasher): Inherit from ggc_cache_ptr_hash
> 	rather than ggc_cache_hasher.
> 	(const_wide_int_hasher, reg_attr_hasher): Likewise.
> 	(const_double_hasher, const_fixed_hasher): Likewise.
> 	* function.c (insn_cache_hasher): Likewise.
> 	* trans-mem.c (tm_wrapper_hasher): Likewise.
> 	* tree.h (tree_decl_map_cache_hasher): Likewise.
> 	* tree.c (type_cache_hasher, int_cst_hasher): Likewise.
> 	(cl_option_hasher, tree_vec_map_cache_hasher): Likewise.
> 	* ubsan.c (tree_type_map_cache_hasher): Likewise.
> 	* varasm.c (tm_clone_hasher): Likewise.
> 	* config/i386/i386.c (dllimport_hasher): Likewise.
> 	* config/nvptx/nvptx.c (declared_libfunc_hasher): Likewise.
> 	(tree_hasher): Likewise.
>
> gcc/ada/
> 	* gcc-interface/decl.c (value_annotation_hasher): Inherit from
> 	ggc_cache_ptr_hash rather than ggc_cache_hasher.
> 	* gcc-interface/utils.c (pad_type_hasher): Likewise.
Same as others -- concern about multiple inheritance.  Otherwise it's OK.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [09/13] Make remaining pointer hashes inherit from a generic class
  2015-06-16  9:05 ` [09/13] Make remaining pointer hashes inherit from a generic class Richard Sandiford
@ 2015-06-23 23:18   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:18 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:05 AM, Richard Sandiford wrote:
> This patch mops up the remaining pointer traits classes that didn't
> inherit from any of the standard ones and just did their own thing.
>
> gcc/
> 	* cgraph.h (asmname_hasher): Inherit from ggc_ptr_hash.  Remove
> 	redundant typedefs and members.
> 	* coverage.c (counts_entry): Inherit from pointer_hash.  Remove
> 	redundant typedefs.
> 	* dwarf2out.c (cu_hash_table_entry_hasher): Likewise.
> 	* ipa-devirt.c (odr_name_hasher): Likewise.
> 	(polymorphic_call_target_hasher): Likewise.
> 	* ira-costs.c (cost_classes_hasher): Likewise.
> 	* statistics.c (stats_counter_hasher): Likewise.
> 	* trans-mem.c (log_entry_hasher): Likewise.
> 	* tree-ssa-dom.c (expr_elt_hasher): Likewise.
> 	* tree-ssa-sccvn.c (vn_phi_hasher, vn_reference_hasher): Likewise.
> 	* tree-ssa-tail-merge.c (same_succ_def): Likewise.
> 	* var-tracking.c (variable_hasher): Likewise.
> 	* valtrack.h (dead_debug_hash_descr): Inherit from free_ptr_hash.
> 	Remove redundant typedefs and members.
OK.  Obviously dependent on prerequisites.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [10/13] Require {mark,id}_{deleted,empty} functions
  2015-06-16  9:12 ` [10/13] Require {mark,id}_{deleted,empty} functions Richard Sandiford
@ 2015-06-23 23:18   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:18 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:11 AM, Richard Sandiford wrote:
> After the previous changes, all traits classes provide an implementation
> of the empty & deleted entry functions, so we can remove the code that
> provided defaults.
>
> gcc/
> 	* hash-table.h (has_is_deleted, is_deleted_helper): Delete.
> 	(has_is_empty, is_empty_helper): Delete.
> 	(has_mark_deleted, mark_deleted_helper): Delete.
> 	(has_mark_empty, mark_empty_helper): Delete.
> 	(hash_table::is_deleted): Call the Descriptor unconditionally.
> 	(hash_table::is_empty): Likewise.
> 	(hash_table::mark_deleted): Likewise.
> 	(hash_table::mark_empty): Likewise.
OK.  Obviously dependent on prerequisites.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [11/13] Generalise typed_noop_remove
  2015-06-16  9:13 ` [11/13] Generalise typed_noop_remove Richard Sandiford
@ 2015-06-23 23:20   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:20 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:12 AM, Richard Sandiford wrote:
> The traits interface is supposed to support non-pointer element types,
> so there's no real reason for typed_noop_remove to be specifically for
> pointers.  It should be usable by anything that wants a no-op remove().
>
> gcc/
> 	* hash-traits.h (typed_noop_remove): Don't require a pointer type.
OK.
jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [12/13] Reuse hash_table traits for hash_set
  2015-06-16  9:17 ` [12/13] Reuse hash_table traits for hash_set Richard Sandiford
@ 2015-06-23 23:20   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:20 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:14 AM, Richard Sandiford wrote:
> This is the main patch, to reuse the hash_table traits for hash_set.
> The idea is to replace the untemplated default_hashset_traits with a
> templated default_hash_traits, which gives the default traits for a
> given type.  This allows things like hash_set<void *> to continue
> to work.
>
> For now I've left default_hash_traits without a default implementation.
> It could instead be defined to inherit its argument, so that hash_set
> <free_ptr_hash <foo> > would work.  I didn't do that because I don't
> have a use case, but it seems like a reasonably clean approach if
> needed.
>
> gcc/
> 	* hash-traits.h (default_hash_traits): New structure.
> 	* hash-set.h (default_hashset_traits): Delete.
> 	(hash_set): Use default_hash_traits<Key> instead of
> 	default_hashset_traits.  Delete hash_entry type and use Key directly.
> 	* ipa-devirt.c (pair_traits): Delete.
> 	(default_hash_traits <type_pair>): Override.
> 	(odr_subtypes_equivalent_p): Remove pair_types template parameter.
> 	(odr_types_equivalent_p, add_type_duplicate): Likewise.
OK.  Obviously dependent on prerequisites.

Jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [13/13] Update comments in hash-table.h
  2015-06-16  9:23 ` [13/13] Update comments in hash-table.h Richard Sandiford
@ 2015-06-23 23:21   ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-23 23:21 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/16/2015 03:17 AM, Richard Sandiford wrote:
> This updates the commentary in hash-table.h for the changes in this
> series and fixes some cases that were already out of date.  It also has
> a couple of trivial formatting fixes.
>
> gcc/
> 	* hash-table.h: Update comments.
OK.
jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-06-23 20:55   ` Jeff Law
@ 2015-06-24  8:23     ` Richard Sandiford
  2015-06-24 17:10       ` Jeff Law
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-24  8:23 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

Jeff Law <law@redhat.com> writes:
> On 06/16/2015 02:45 AM, Richard Sandiford wrote:
>> As described in the covering note, this patch replaces handle_cache_entry
>> with a new function keep_cache_entry.  It also ensures that elements are
>> deleted using the proper function, so that m_n_deleted is updated.
>>
>> I couldn't tell whether the unusual name of the function
>> ("gt_cleare_cache") is deliberate or not, but I left it be.
> Short-hand for clear_entry or something similar?

Yeah, could be.

>> gcc/ada/
>> 	* gcc-interface/decl.c (value_annotation_hasher::handle_cache_entry):
>> 	Delete.
>> 	(value_annotation_hasher::keep_cache_entry): New function.
>> 	* gcc-interface/utils.c (pad_type_hasher::handle_cache_entry):
>> 	Delete.
>> 	(pad_type_hasher::keep_cache_entry): New function.
>>
>> gcc/
>> 	* hash-table.h (hash_table): Add gt_cleare_cache as a friend.
>> 	(gt_cleare_cache): Check here for deleted and empty entries.
>> 	Replace handle_cache_entry with a call to keep_cache_entry.
>> 	* hash-traits.h (ggc_cache_hasher::handle_cache_entry): Delete.
>> 	(ggc_cache_hasher::keep_cache_entry): New function.
>> 	* trans-mem.c (tm_wrapper_hasher::handle_cache_entry): Delete.
>> 	(tm_wrapper_hasher::keep_cache_entry): New function.
>> 	* tree.h (tree_decl_map_cache_hasher::handle_cache_entry): Delete.
>> 	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
>> 	* tree.c (type_cache_hasher::handle_cache_entry): Delete.
>> 	(type_cache_hasher::keep_cache_entry): New function.
>> 	(tree_vec_map_cache_hasher::handle_cache_entry): Delete.
>> 	(tree_vec_map_cache_hasher::keep_cache_entry): New function.
>> 	* ubsan.c (tree_type_map_cache_hasher::handle_cache_entry): Delete.
>> 	(tree_type_map_cache_hasher::keep_cache_entry): New function.
>> 	* varasm.c (tm_clone_hasher::handle_cache_entry): Delete.
>> 	(tm_clone_hasher::keep_cache_entry): New function.
>> 	* config/i386/i386.c (dllimport_hasher::handle_cache_entry): Delete.
>> 	(dllimport_hasher::keep_cache_entry): New function.
> So for all the keep_cache_entry functions, I guess they're trivial 
> enough that a function comment probably isn't needed.

Yeah.  For cases like this where the function is implementing a defined
interface (described in hash-table.h), I think it's better to only have
comments for implementations that are doing something non-obvious.

> Presumably no good way to share the trivial implementation?

Probably not without sharing the other parts of the traits in some way.
That might be another possible cleanup :-)

Thanks,
Richard

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-23 22:18   ` Jeff Law
@ 2015-06-24  8:42     ` Richard Sandiford
  2015-06-25  3:30       ` Jeff Law
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-24  8:42 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

Jeff Law <law@redhat.com> writes:
> On 06/16/2015 02:55 AM, Richard Sandiford wrote:
>> This patch stops pointer_hash from inheriting typed_noop_remove and
>> instead creates a new class nofree_ptr_hash that inherits from both.
>> It then updates all uses of typed_noop_remove (which are all pointers)
>> and pointer_hash so that they use this new class instead.
>>
>> gcc/
>> 	* hash-table.h: Update comments.
>> 	* hash-traits.h (pointer_hash): Don't inherit from typed_noop_remove.
>> 	(nofree_ptr_hash): New class.
>> 	* asan.c (asan_mem_ref_hasher): Inherit from nofree_ptr_hash rather
>> 	than typed_noop_remove.  Remove redudant typedefs.
>> 	* attribs.c (attribute_hasher): Likewise.
>> 	* cfg.c (bb_copy_hasher): Likewise.
>> 	* cselib.c (cselib_hasher): Likewise.
>> 	* dse.c (invariant_group_base_hasher): Likewise.
>> 	* dwarf2cfi.c (trace_info_hasher): Likewise.
>> 	* dwarf2out.c (macinfo_entry_hasher): Likewise.
>> 	(comdat_type_hasher, loc_list_hasher): Likewise.
>> 	* gcse.c (pre_ldst_expr_hasher): Likewise.
>> 	* genmatch.c (id_base): Likewise.
>> 	* genrecog.c (test_pattern_hasher): Likewise.
>> 	* gimple-ssa-strength-reduction.c (cand_chain_hasher): Likewise.
>> 	* haifa-sched.c (delay_i1_hasher): Likewise.
>> 	* hard-reg-set.h (simplifiable_subregs_hasher): Likewise.
>> 	* ipa-icf.h (congruence_class_group_hash): Likewise.
>> 	* ipa-profile.c (histogram_hash): Likewise.
>> 	* ira-color.c (allocno_hard_regs_hasher): Likewise.
>> 	* lto-streamer.h (string_slot_hasher): Likewise.
>> 	* lto-streamer.c (tree_entry_hasher): Likewise.
>> 	* plugin.c (event_hasher): Likewise.
>> 	* postreload-gcse.c (expr_hasher): Likewise.
>> 	* store-motion.c (st_expr_hasher): Likewise.
>> 	* tree-sra.c (uid_decl_hasher): Likewise.
>> 	* tree-ssa-coalesce.c (coalesce_pair_hasher): Likewise.
>> 	(ssa_name_var_hash): Likewise.
>> 	* tree-ssa-live.c (tree_int_map_hasher): Likewise.
>> 	* tree-ssa-loop-im.c (mem_ref_hasher): Likewise.
>> 	* tree-ssa-pre.c (pre_expr_d): Likewise.
>> 	* tree-ssa-sccvn.c (vn_nary_op_hasher): Likewise.
>> 	* vtable-verify.h (registration_hasher): Likewise.
>> 	* vtable-verify.c (vtbl_map_hasher): Likewise.
>> 	* config/arm/arm.c (libcall_hasher): Likewise.
>> 	* config/i386/winnt.c (wrapped_symbol_hasher): Likewise.
>> 	* config/ia64/ia64.c (bundle_state_hasher): Likewise.
>> 	* config/sol2.c (comdat_entry_hasher): Likewise.
>> 	* fold-const.c (fold): Use nofree_ptr_hash instead of pointer_hash.
>> 	(print_fold_checksum, fold_checksum_tree): Likewise.
>> 	(debug_fold_checksum, fold_build1_stat_loc): Likewise.
>> 	(fold_build2_stat_loc, fold_build3_stat_loc): Likewise.
>> 	(fold_build_call_array_loc): Likewise.
>> 	* tree-ssa-ccp.c (gimple_htab): Likewise.
>> 	* tree-browser.c (tree_upper_hasher): Inherit from nofree_ptr_hash
>> 	rather than pointer_type.
>>
>> gcc/c/
>> 	* c-decl.c (detect_field_duplicates_hash): Use nofree_ptr_hash
>> 	instead of pointer_hash.
>> 	(detect_field_duplicates): Likewise.
>>
>> gcc/cp/
>> 	* class.c (fixed_type_or_null_ref_ht): Inherit from nofree_ptr_hash
>> 	rather than pointer_hash.
>> 	(fixed_type_or_null): Use nofree_ptr_hash instead of pointer_hash.
>> 	* semantics.c (nrv_data): Likewise.
>> 	* tree.c (verify_stmt_tree_r, verify_stmt_tree): Likewise.
>>
>> gcc/java/
>> 	* jcf-io.c (charstar_hash): Inherit from nofree_ptr_hash rather
>> 	than typed_noop_remove.  Remove redudant typedefs.
>>
>> gcc/lto/
>> 	* lto.c (tree_scc_hasher): Inherit from nofree_ptr_hash rather
>> 	than typed_noop_remove.  Remove redudant typedefs.
>>
>> gcc/objc/
>> 	* objc-act.c (decl_name_hash): Inherit from nofree_ptr_hash rather
>> 	than typed_noop_remove.  Remove redudant typedefs.
>>
>> libcc1/
>> 	* plugin.cc (string_hasher): Inherit from nofree_ptr_hash rather
>> 	than typed_noop_remove.  Remove redudant typedefs.
>> 	(plugin_context): Use nofree_ptr_hash rather than pointer_hash.
>> 	(plugin_context::mark): Likewise.
> So are we allowing multiple inheritance in GCC?  It seems like that's 
> what we've got for nofree_ptr_hash.  Is there a better way to achieve 
> what you're trying to do, or do you think this use ought to fall under 
> some kind of exception?
>
>
>> Index: gcc/haifa-sched.c
>> ===================================================================
>> --- gcc/haifa-sched.c	2015-06-16 09:53:47.338092692 +0100
>> +++ gcc/haifa-sched.c	2015-06-16 09:53:47.322092878 +0100
>> @@ -614,9 +614,8 @@ struct delay_pair
>>
>>   /* Helpers for delay hashing.  */
>>
>> -struct delay_i1_hasher : typed_noop_remove <delay_pair>
>> +struct delay_i1_hasher : nofree_ptr_hash <delay_pair>
>>   {
>> -  typedef delay_pair *value_type;
>>     typedef void *compare_type;
>>     static inline hashval_t hash (const delay_pair *);
>>     static inline bool equal (const delay_pair *, const void *);
> Did you keep compare_type intentionally?  Similarly for the changes in 
> hard-reg-set.h, tree-ssa-loop-im.c, and tree-ssa-sccvn.c.  You probably 
> did, but I just want to be sure.

Yeah.  The idea is to keep compare_type if it's different from the type
being hashed (value_type) .  It's needed by the hash_table implementation
to know what type find_with_hash & co. expect.

> So I'm holding off on approving this one pending further discussion of 
> the use of multiple inheritance for nofree_ptr_hash.

I thought that might be controversial. :-)  My two main defences are:

1) This is multiple inheritance of traits classes, which all just have
   static member functions, rather than multiple inheritance of data-
   carrying classes.  It's really just a union of two separate groups
   of functions.

2) This goes away if we move to proper C++ object management for the
   elements, with constructors and destructors.  The remove() would
   then just be the destructor.

   I think we want that, but it's a relatively big change, and I think
   doing this kind of consolidation first will help.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-06-24  8:23     ` Richard Sandiford
@ 2015-06-24 17:10       ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-24 17:10 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/24/2015 02:16 AM, Richard Sandiford wrote:
>> So for all the keep_cache_entry functions, I guess they're trivial
>> enough that a function comment probably isn't needed.
>
> Yeah.  For cases like this where the function is implementing a defined
> interface (described in hash-table.h), I think it's better to only have
> comments for implementations that are doing something non-obvious.
That works for me.

>
>> Presumably no good way to share the trivial implementation?
>
> Probably not without sharing the other parts of the traits in some way.
> That might be another possible cleanup :-)
I'll let you decide whether or not to pursue.  I'd like to hope that ICF 
would help us here.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-24  8:42     ` Richard Sandiford
@ 2015-06-25  3:30       ` Jeff Law
  2015-06-25  9:59         ` Richard Biener
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff Law @ 2015-06-25  3:30 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 06/24/2015 02:23 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> So I'm holding off on approving this one pending further discussion of
>> the use of multiple inheritance for nofree_ptr_hash.
>
> I thought that might be controversial. :-)  My two main defences are:
>
> 1) This is multiple inheritance of traits classes, which all just have
>     static member functions, rather than multiple inheritance of data-
>     carrying classes.  It's really just a union of two separate groups
>     of functions.
As I was thinking about this during review I almost convinced myself 
that multiple inheritance from traits classes ought to be acceptable.

As you state, they don't carry data and we're just getting a union of 
their functions.  One could probably even argue that traits classes by 
their nature are designed to be composed with other traits and classes.

I'm (obviously) not as well versed in this stuff as I ought to be, hence 
my conservatism.  It'd be real helpful if folks with more real world 
experience in this space could chime in on the pros/cons if this approach.

If we do go forward, ISTM updating our coding conventions to codify this 
exception to the "avoid MI" would be wise.  And my inclination is to go 
forward, but let's give other folks a chance to chime in.


Jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-25  3:30       ` Jeff Law
@ 2015-06-25  9:59         ` Richard Biener
  2015-06-25 16:33           ` Jeff Law
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Biener @ 2015-06-25  9:59 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches, richard.sandiford

On Thu, Jun 25, 2015 at 5:19 AM, Jeff Law <law@redhat.com> wrote:
> On 06/24/2015 02:23 AM, Richard Sandiford wrote:
>>
>> Jeff Law <law@redhat.com> writes:
>>>
>>> So I'm holding off on approving this one pending further discussion of
>>> the use of multiple inheritance for nofree_ptr_hash.
>>
>>
>> I thought that might be controversial. :-)  My two main defences are:
>>
>> 1) This is multiple inheritance of traits classes, which all just have
>>     static member functions, rather than multiple inheritance of data-
>>     carrying classes.  It's really just a union of two separate groups
>>     of functions.
>
> As I was thinking about this during review I almost convinced myself that
> multiple inheritance from traits classes ought to be acceptable.
>
> As you state, they don't carry data and we're just getting a union of their
> functions.  One could probably even argue that traits classes by their
> nature are designed to be composed with other traits and classes.
>
> I'm (obviously) not as well versed in this stuff as I ought to be, hence my
> conservatism.  It'd be real helpful if folks with more real world experience
> in this space could chime in on the pros/cons if this approach.
>
> If we do go forward, ISTM updating our coding conventions to codify this
> exception to the "avoid MI" would be wise.  And my inclination is to go
> forward, but let's give other folks a chance to chime in.

Yes, I think this is ok.

Richard.

>
> Jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-25  9:59         ` Richard Biener
@ 2015-06-25 16:33           ` Jeff Law
  2015-06-25 17:52             ` Richard Sandiford
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff Law @ 2015-06-25 16:33 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, richard.sandiford

On 06/25/2015 03:49 AM, Richard Biener wrote:
> On Thu, Jun 25, 2015 at 5:19 AM, Jeff Law <law@redhat.com> wrote:
>> On 06/24/2015 02:23 AM, Richard Sandiford wrote:
>>>
>>> Jeff Law <law@redhat.com> writes:
>>>>
>>>> So I'm holding off on approving this one pending further discussion of
>>>> the use of multiple inheritance for nofree_ptr_hash.
>>>
>>>
>>> I thought that might be controversial. :-)  My two main defences are:
>>>
>>> 1) This is multiple inheritance of traits classes, which all just have
>>>      static member functions, rather than multiple inheritance of data-
>>>      carrying classes.  It's really just a union of two separate groups
>>>      of functions.
>>
>> As I was thinking about this during review I almost convinced myself that
>> multiple inheritance from traits classes ought to be acceptable.
>>
>> As you state, they don't carry data and we're just getting a union of their
>> functions.  One could probably even argue that traits classes by their
>> nature are designed to be composed with other traits and classes.
>>
>> I'm (obviously) not as well versed in this stuff as I ought to be, hence my
>> conservatism.  It'd be real helpful if folks with more real world experience
>> in this space could chime in on the pros/cons if this approach.
>>
>> If we do go forward, ISTM updating our coding conventions to codify this
>> exception to the "avoid MI" would be wise.  And my inclination is to go
>> forward, but let's give other folks a chance to chime in.
>
> Yes, I think this is ok.
Works for me.  Richard S., as a follow-up can you update the coding 
conventions, which I think it maintained in the ancient CVS repo for the 
web pages (ping Gerald if you're unfamiliar with it).

Jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-25 16:33           ` Jeff Law
@ 2015-06-25 17:52             ` Richard Sandiford
  2015-06-25 18:23               ` Jeff Law
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-06-25 17:52 UTC (permalink / raw)
  To: Jeff Law; +Cc: Richard Biener, gcc-patches

Jeff Law <law@redhat.com> writes:
> On 06/25/2015 03:49 AM, Richard Biener wrote:
>> On Thu, Jun 25, 2015 at 5:19 AM, Jeff Law <law@redhat.com> wrote:
>>> On 06/24/2015 02:23 AM, Richard Sandiford wrote:
>>>>
>>>> Jeff Law <law@redhat.com> writes:
>>>>>
>>>>> So I'm holding off on approving this one pending further discussion of
>>>>> the use of multiple inheritance for nofree_ptr_hash.
>>>>
>>>>
>>>> I thought that might be controversial. :-)  My two main defences are:
>>>>
>>>> 1) This is multiple inheritance of traits classes, which all just have
>>>>      static member functions, rather than multiple inheritance of data-
>>>>      carrying classes.  It's really just a union of two separate groups
>>>>      of functions.
>>>
>>> As I was thinking about this during review I almost convinced myself that
>>> multiple inheritance from traits classes ought to be acceptable.
>>>
>>> As you state, they don't carry data and we're just getting a union of their
>>> functions.  One could probably even argue that traits classes by their
>>> nature are designed to be composed with other traits and classes.
>>>
>>> I'm (obviously) not as well versed in this stuff as I ought to be, hence my
>>> conservatism.  It'd be real helpful if folks with more real world experience
>>> in this space could chime in on the pros/cons if this approach.
>>>
>>> If we do go forward, ISTM updating our coding conventions to codify this
>>> exception to the "avoid MI" would be wise.  And my inclination is to go
>>> forward, but let's give other folks a chance to chime in.
>>
>> Yes, I think this is ok.
> Works for me.  Richard S., as a follow-up can you update the coding 
> conventions, which I think it maintained in the ancient CVS repo for the 
> web pages (ping Gerald if you're unfamiliar with it).

OK, sounds good.  How does this look?

Thanks,
Richard

Index: htdocs/codingconventions.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/codingconventions.html,v
retrieving revision 1.71
diff -u -r1.71 codingconventions.html
--- htdocs/codingconventions.html	9 Jul 2014 00:03:05 -0000	1.71
+++ htdocs/codingconventions.html	25 Jun 2015 17:31:39 -0000
@@ -888,6 +888,9 @@
 On the rare occasion that using mulitple inheritance is indeed useful,
 prepare design rationales in advance,
 and take special care to make documentation of the entire hierarchy clear.
+(In particular, multiple inheritance can be an acceptable way of combining
+"traits"-style classes that only contain static member functions.
+Its use with data-carrying classes is more problematic.)
 </p>
 
 <p>

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [05/13] Add nofree_ptr_hash
  2015-06-25 17:52             ` Richard Sandiford
@ 2015-06-25 18:23               ` Jeff Law
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Law @ 2015-06-25 18:23 UTC (permalink / raw)
  To: Richard Biener, gcc-patches, richard.sandiford

On 06/25/2015 11:33 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> On 06/25/2015 03:49 AM, Richard Biener wrote:
>>> On Thu, Jun 25, 2015 at 5:19 AM, Jeff Law <law@redhat.com> wrote:
>>>> On 06/24/2015 02:23 AM, Richard Sandiford wrote:
>>>>>
>>>>> Jeff Law <law@redhat.com> writes:
>>>>>>
>>>>>> So I'm holding off on approving this one pending further discussion of
>>>>>> the use of multiple inheritance for nofree_ptr_hash.
>>>>>
>>>>>
>>>>> I thought that might be controversial. :-)  My two main defences are:
>>>>>
>>>>> 1) This is multiple inheritance of traits classes, which all just have
>>>>>       static member functions, rather than multiple inheritance of data-
>>>>>       carrying classes.  It's really just a union of two separate groups
>>>>>       of functions.
>>>>
>>>> As I was thinking about this during review I almost convinced myself that
>>>> multiple inheritance from traits classes ought to be acceptable.
>>>>
>>>> As you state, they don't carry data and we're just getting a union of their
>>>> functions.  One could probably even argue that traits classes by their
>>>> nature are designed to be composed with other traits and classes.
>>>>
>>>> I'm (obviously) not as well versed in this stuff as I ought to be, hence my
>>>> conservatism.  It'd be real helpful if folks with more real world experience
>>>> in this space could chime in on the pros/cons if this approach.
>>>>
>>>> If we do go forward, ISTM updating our coding conventions to codify this
>>>> exception to the "avoid MI" would be wise.  And my inclination is to go
>>>> forward, but let's give other folks a chance to chime in.
>>>
>>> Yes, I think this is ok.
>> Works for me.  Richard S., as a follow-up can you update the coding
>> conventions, which I think it maintained in the ancient CVS repo for the
>> web pages (ping Gerald if you're unfamiliar with it).
>
> OK, sounds good.  How does this look?
Looks good.  Thanks.

jeff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-06-16  8:46 ` [02/13] Replace handle_cache_entry with new interface Richard Sandiford
  2015-06-23 20:55   ` Jeff Law
@ 2015-07-01  9:41   ` Trevor Saunders
  2015-07-01  9:59     ` Richard Sandiford
  1 sibling, 1 reply; 39+ messages in thread
From: Trevor Saunders @ 2015-07-01  9:41 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On Tue, Jun 16, 2015 at 09:45:56AM +0100, Richard Sandiford wrote:
> As described in the covering note, this patch replaces handle_cache_entry
> with a new function keep_cache_entry.  It also ensures that elements are
> deleted using the proper function, so that m_n_deleted is updated.

Thanks for taking this off my to do list ;-)

> I couldn't tell whether the unusual name of the function
> ("gt_cleare_cache") is deliberate or not, but I left it be.

I'm not sure what's particularly unusual about it?

> +  static int
> +  keep_cache_entry (tree_int_map *&m)

I think we could now change the interface to take const T *?  I imagine
inlining may get rid of the extra indirection anyway, but it feels
cleaner anyway.

> +	 - An optional static function named 'keep_cache_entry'.  This
> +	 function is provided only for garbage-collected elements that
> +	 are not marked by the normal gc mark pass.  It describes what
> +	 what should happen to the element at the end of the gc mark phase.
> +	 The return value should be:
> +	   - 0 if the element should be deleted
> +	   - 1 if the element should be kept and needs to be marked
> +	   - -1 if the element should be kept and is already marked.
> +	 Returning -1 rather than 1 is purely an optimization.

In theory using an enum seems better, but I'm not sure if the extra
verbosity makes it better in practice.

> +  static int
> +  keep_cache_entry (T &e)
>    {
> -    if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
> -      e = static_cast<T> (HTAB_DELETED_ENTRY);
> +    return ggc_marked_p (e) ? -1 : 0;

 hmm, this is the only place where -1 is used right?  I believe this
 case only works if the hash table is storing pointers to things in gc
 memory, and only keeps things that get marked by other paths.  I
 believe that means -1 is only a very small optimization because in the
 case we return -1 all we save is the check that that pointer itself is
 marked.  So i'm tempted to change this interface to just return a bool.
 Of course it would be nice if the compiler could inline enough to
 actually optimize out the redundant check if the pointer is makred, but
 that might take some shuffling code around.

thanks for cleaning this up, and sorry my response is delayed.

Trev

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-07-01  9:41   ` Trevor Saunders
@ 2015-07-01  9:59     ` Richard Sandiford
  2015-07-01 11:24       ` Trevor Saunders
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Sandiford @ 2015-07-01  9:59 UTC (permalink / raw)
  To: Trevor Saunders; +Cc: gcc-patches

Trevor Saunders <tbsaunde@tbsaunde.org> writes:
> On Tue, Jun 16, 2015 at 09:45:56AM +0100, Richard Sandiford wrote:
>> I couldn't tell whether the unusual name of the function
>> ("gt_cleare_cache") is deliberate or not, but I left it be.
>
> I'm not sure what's particularly unusual about it?

"cleare" rather than "clear".

>> +  static int
>> +  keep_cache_entry (tree_int_map *&m)
>
> I think we could now change the interface to take const T *?  I imagine
> inlining may get rid of the extra indirection anyway, but it feels
> cleaner anyway.

Yeah, good point.

>> +	 - An optional static function named 'keep_cache_entry'.  This
>> +	 function is provided only for garbage-collected elements that
>> +	 are not marked by the normal gc mark pass.  It describes what
>> +	 what should happen to the element at the end of the gc mark phase.
>> +	 The return value should be:
>> +	   - 0 if the element should be deleted
>> +	   - 1 if the element should be kept and needs to be marked
>> +	   - -1 if the element should be kept and is already marked.
>> +	 Returning -1 rather than 1 is purely an optimization.
>
> In theory using an enum seems better, but I'm not sure if the extra
> verbosity makes it better in practice.

Yeah, I wondered about an enum but it seemed like overkill.

>> +  static int
>> +  keep_cache_entry (T &e)
>>    {
>> - if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY &&
>> !ggc_marked_p (e))
>> -      e = static_cast<T> (HTAB_DELETED_ENTRY);
>> +    return ggc_marked_p (e) ? -1 : 0;
>
>  hmm, this is the only place where -1 is used right?  I believe this
>  case only works if the hash table is storing pointers to things in gc
>  memory, and only keeps things that get marked by other paths.  I
>  believe that means -1 is only a very small optimization because in the
>  case we return -1 all we save is the check that that pointer itself is
>  marked.

Right.  But it's an optimisation that we had before and I think we
should keep it.  The -1 case is in the generic traits rather than
"user" code.

>  So i'm tempted to change this interface to just return a bool.
>  Of course it would be nice if the compiler could inline enough to
>  actually optimize out the redundant check if the pointer is makred, but
>  that might take some shuffling code around.

In practice all calls will return from {0, 1} or {0, -1}, so assuming
sensible inlining, no caller will use all three paths.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [02/13] Replace handle_cache_entry with new interface
  2015-07-01  9:59     ` Richard Sandiford
@ 2015-07-01 11:24       ` Trevor Saunders
  0 siblings, 0 replies; 39+ messages in thread
From: Trevor Saunders @ 2015-07-01 11:24 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On Wed, Jul 01, 2015 at 10:59:15AM +0100, Richard Sandiford wrote:
> Trevor Saunders <tbsaunde@tbsaunde.org> writes:
> > On Tue, Jun 16, 2015 at 09:45:56AM +0100, Richard Sandiford wrote:
> >> I couldn't tell whether the unusual name of the function
> >> ("gt_cleare_cache") is deliberate or not, but I left it be.
> >
> > I'm not sure what's particularly unusual about it?
> 
> "cleare" rather than "clear".

oh! I didn't notice that but yeah its wierd probably just being a bad
typist.

> >> +  static int
> >> +  keep_cache_entry (tree_int_map *&m)
> >
> > I think we could now change the interface to take const T *?  I imagine
> > inlining may get rid of the extra indirection anyway, but it feels
> > cleaner anyway.
> 
> Yeah, good point.
> 
> >> +	 - An optional static function named 'keep_cache_entry'.  This
> >> +	 function is provided only for garbage-collected elements that
> >> +	 are not marked by the normal gc mark pass.  It describes what
> >> +	 what should happen to the element at the end of the gc mark phase.
> >> +	 The return value should be:
> >> +	   - 0 if the element should be deleted
> >> +	   - 1 if the element should be kept and needs to be marked
> >> +	   - -1 if the element should be kept and is already marked.
> >> +	 Returning -1 rather than 1 is purely an optimization.
> >
> > In theory using an enum seems better, but I'm not sure if the extra
> > verbosity makes it better in practice.
> 
> Yeah, I wondered about an enum but it seemed like overkill.
> 
> >> +  static int
> >> +  keep_cache_entry (T &e)
> >>    {
> >> - if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY &&
> >> !ggc_marked_p (e))
> >> -      e = static_cast<T> (HTAB_DELETED_ENTRY);
> >> +    return ggc_marked_p (e) ? -1 : 0;
> >
> >  hmm, this is the only place where -1 is used right?  I believe this
> >  case only works if the hash table is storing pointers to things in gc
> >  memory, and only keeps things that get marked by other paths.  I
> >  believe that means -1 is only a very small optimization because in the
> >  case we return -1 all we save is the check that that pointer itself is
> >  marked.
> 
> Right.  But it's an optimisation that we had before and I think we
> should keep it.  The -1 case is in the generic traits rather than
> "user" code.
> 
> >  So i'm tempted to change this interface to just return a bool.
> >  Of course it would be nice if the compiler could inline enough to
> >  actually optimize out the redundant check if the pointer is makred, but
> >  that might take some shuffling code around.
> 
> In practice all calls will return from {0, 1} or {0, -1}, so assuming
> sensible inlining, no caller will use all three paths.

yeah

Trev


> 
> Thanks,
> Richard
> 

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2015-07-01 11:24 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-16  8:44 [00/13] Share hash traits between hash_table and hash_set Richard Sandiford
2015-06-16  8:46 ` [01/13] Move hash traits to their own header file Richard Sandiford
2015-06-23 20:53   ` Jeff Law
2015-06-16  8:46 ` [02/13] Replace handle_cache_entry with new interface Richard Sandiford
2015-06-23 20:55   ` Jeff Law
2015-06-24  8:23     ` Richard Sandiford
2015-06-24 17:10       ` Jeff Law
2015-07-01  9:41   ` Trevor Saunders
2015-07-01  9:59     ` Richard Sandiford
2015-07-01 11:24       ` Trevor Saunders
2015-06-16  8:53 ` [03/13] Make ggc_cached_hasher inherit from ggc_hasher Richard Sandiford
2015-06-23 20:56   ` Jeff Law
2015-06-16  8:55 ` [05/13] Add nofree_ptr_hash Richard Sandiford
2015-06-23 22:18   ` Jeff Law
2015-06-24  8:42     ` Richard Sandiford
2015-06-25  3:30       ` Jeff Law
2015-06-25  9:59         ` Richard Biener
2015-06-25 16:33           ` Jeff Law
2015-06-25 17:52             ` Richard Sandiford
2015-06-25 18:23               ` Jeff Law
2015-06-16  8:55 ` [04/13] Add {mark,is}_{empty,deleted} to pointer_hash Richard Sandiford
2015-06-23 21:00   ` Jeff Law
2015-06-16  8:58 ` [06/13] Add free_ptr_hash Richard Sandiford
2015-06-23 23:14   ` Jeff Law
2015-06-16  9:03 ` [07/13] Add ggc_ptr_hash Richard Sandiford
2015-06-23 23:16   ` Jeff Law
2015-06-16  9:05 ` [09/13] Make remaining pointer hashes inherit from a generic class Richard Sandiford
2015-06-23 23:18   ` Jeff Law
2015-06-16  9:05 ` [08/13] Add a ggc_cache_ptr_hash Richard Sandiford
2015-06-23 23:17   ` Jeff Law
2015-06-16  9:12 ` [10/13] Require {mark,id}_{deleted,empty} functions Richard Sandiford
2015-06-23 23:18   ` Jeff Law
2015-06-16  9:13 ` [11/13] Generalise typed_noop_remove Richard Sandiford
2015-06-23 23:20   ` Jeff Law
2015-06-16  9:17 ` [12/13] Reuse hash_table traits for hash_set Richard Sandiford
2015-06-23 23:20   ` Jeff Law
2015-06-16  9:23 ` [13/13] Update comments in hash-table.h Richard Sandiford
2015-06-23 23:21   ` Jeff Law
2015-06-23 20:36 ` [00/13] Share hash traits between hash_table and hash_set Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).