diff mbox

[05/13] Add nofree_ptr_hash

Message ID 87twu8118n.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford June 16, 2015, 8:55 a.m. UTC
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.

Comments

Jeff Law June 23, 2015, 9:36 p.m. UTC | #1
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
Richard Sandiford June 24, 2015, 8:23 a.m. UTC | #2
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
Jeff Law June 25, 2015, 3:19 a.m. UTC | #3
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
Richard Biener June 25, 2015, 9:49 a.m. UTC | #4
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
Jeff Law June 25, 2015, 4:31 p.m. UTC | #5
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
diff mbox

Patch

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)
 }
 
 /* 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
 
 
 
-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);
 }