1 /* Traits for hashable types.
2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 /* Helpful type for removing with free. */
25 template <typename Type
>
26 struct typed_free_remove
28 static inline void remove (Type
*p
);
31 template <typename Type
>
32 struct typed_const_free_remove
34 static inline void remove (const Type
*p
);
37 /* Remove with free. */
39 template <typename Type
>
41 typed_free_remove
<Type
>::remove (Type
*p
)
46 template <typename Type
>
48 typed_const_free_remove
<Type
>::remove (const Type
*p
)
50 free (const_cast <Type
*> (p
));
53 /* Helpful type for removing with delete. */
55 template <typename Type
>
56 struct typed_delete_remove
58 static inline void remove (Type
*p
);
62 /* Remove with delete. */
64 template <typename Type
>
66 typed_delete_remove
<Type
>::remove (Type
*p
)
71 /* Helpful type for a no-op remove. */
73 template <typename Type
>
74 struct typed_noop_remove
76 static inline void remove (Type
&);
80 /* Remove doing nothing. */
82 template <typename Type
>
84 typed_noop_remove
<Type
>::remove (Type
&)
88 /* Base traits for integer type Type, providing just the hash and
89 comparison functionality. */
91 template <typename Type
>
92 struct int_hash_base
: typed_noop_remove
<Type
>
94 typedef Type value_type
;
95 typedef Type compare_type
;
97 static inline hashval_t
hash (value_type
);
98 static inline bool equal (value_type existing
, value_type candidate
);
101 template <typename Type
>
103 int_hash_base
<Type
>::hash (value_type x
)
108 template <typename Type
>
110 int_hash_base
<Type
>::equal (value_type x
, value_type y
)
115 /* Hasher for integer type Type in which Empty is a spare value that can be
116 used to mark empty slots. If Deleted != Empty then Deleted is another
117 spare value that can be used for deleted slots; if Deleted == Empty then
118 hash table entries cannot be deleted. */
120 template <typename Type
, Type Empty
, Type Deleted
= Empty
>
121 struct int_hash
: int_hash_base
<Type
>
123 typedef Type value_type
;
124 typedef Type compare_type
;
126 static inline void mark_deleted (Type
&);
127 static const bool empty_zero_p
= Empty
== 0;
128 static inline void mark_empty (Type
&);
129 static inline bool is_deleted (Type
);
130 static inline bool is_empty (Type
);
133 template <typename Type
, Type Empty
, Type Deleted
>
135 int_hash
<Type
, Empty
, Deleted
>::mark_deleted (Type
&x
)
137 gcc_assert (Empty
!= Deleted
);
141 template <typename Type
, Type Empty
, Type Deleted
>
143 int_hash
<Type
, Empty
, Deleted
>::mark_empty (Type
&x
)
148 template <typename Type
, Type Empty
, Type Deleted
>
150 int_hash
<Type
, Empty
, Deleted
>::is_deleted (Type x
)
152 return Empty
!= Deleted
&& x
== Deleted
;
155 template <typename Type
, Type Empty
, Type Deleted
>
157 int_hash
<Type
, Empty
, Deleted
>::is_empty (Type x
)
162 /* Pointer hasher based on pointer equality. Other types of pointer hash
163 can inherit this and override the hash and equal functions with some
164 other form of equality (such as string equality). */
166 template <typename Type
>
169 typedef Type
*value_type
;
170 typedef Type
*compare_type
;
172 static inline hashval_t
hash (const value_type
&);
173 static inline bool equal (const value_type
&existing
,
174 const compare_type
&candidate
);
175 static inline void mark_deleted (Type
*&);
176 static const bool empty_zero_p
= true;
177 static inline void mark_empty (Type
*&);
178 static inline bool is_deleted (Type
*);
179 static inline bool is_empty (Type
*);
182 template <typename Type
>
184 pointer_hash
<Type
>::hash (const value_type
&candidate
)
186 /* This is a really poor hash function, but it is what the current code uses,
187 so I am reusing it to avoid an additional axis in testing. */
188 return (hashval_t
) ((intptr_t)candidate
>> 3);
191 template <typename Type
>
193 pointer_hash
<Type
>::equal (const value_type
&existing
,
194 const compare_type
&candidate
)
196 return existing
== candidate
;
199 template <typename Type
>
201 pointer_hash
<Type
>::mark_deleted (Type
*&e
)
203 e
= reinterpret_cast<Type
*> (1);
206 template <typename Type
>
208 pointer_hash
<Type
>::mark_empty (Type
*&e
)
213 template <typename Type
>
215 pointer_hash
<Type
>::is_deleted (Type
*e
)
217 return e
== reinterpret_cast<Type
*> (1);
220 template <typename Type
>
222 pointer_hash
<Type
>::is_empty (Type
*e
)
227 /* Hasher for "const char *" strings, using string rather than pointer
230 struct string_hash
: pointer_hash
<const char>
232 static inline hashval_t
hash (const char *);
233 static inline bool equal (const char *, const char *);
237 string_hash::hash (const char *id
)
239 return htab_hash_string (id
);
243 string_hash::equal (const char *id1
, const char *id2
)
245 return strcmp (id1
, id2
) == 0;
248 /* Remover and marker for entries in gc memory. */
253 static void remove (T
&) {}
258 extern void gt_ggc_mx (T
&);
262 /* Overridden in ggc_cache_remove. */
272 extern void gt_pch_nx (T
&);
277 pch_nx (T
&p
, gt_pointer_operator op
, void *cookie
)
279 op (&p
, NULL
, cookie
);
283 /* Remover and marker for "cache" entries in gc memory. These entries can
284 be deleted if there are no non-cache references to the data. */
287 struct ggc_cache_remove
: ggc_remove
<T
>
289 /* Entries are weakly held because this is for caches. */
290 static void ggc_maybe_mx (T
&) {}
293 keep_cache_entry (T
&e
)
295 return ggc_marked_p (e
) ? -1 : 0;
299 /* Traits for pointer elements that should not be freed when an element
302 template <typename T
>
303 struct nofree_ptr_hash
: pointer_hash
<T
>, typed_noop_remove
<T
*> {};
305 /* Traits for pointer elements that should be freed via free() when an
306 element is deleted. */
308 template <typename T
>
309 struct free_ptr_hash
: pointer_hash
<T
>, typed_free_remove
<T
> {};
311 /* Traits for pointer elements that should be freed via delete operand when an
312 element is deleted. */
314 template <typename T
>
315 struct delete_ptr_hash
: pointer_hash
<T
>, typed_delete_remove
<T
> {};
317 /* Traits for elements that point to gc memory. The pointed-to data
318 must be kept across collections. */
320 template <typename T
>
321 struct ggc_ptr_hash
: pointer_hash
<T
>, ggc_remove
<T
*> {};
323 /* Traits for elements that point to gc memory. The elements don't
324 in themselves keep the pointed-to data alive and they can be deleted
325 if the pointed-to data is going to be collected. */
327 template <typename T
>
328 struct ggc_cache_ptr_hash
: pointer_hash
<T
>, ggc_cache_remove
<T
*> {};
330 /* Traits for string elements that should be freed when an element is
333 struct free_string_hash
: string_hash
, typed_const_free_remove
<char> {};
335 /* Traits for string elements that should not be freed when an element
338 struct nofree_string_hash
: string_hash
, typed_noop_remove
<const char *> {};
340 /* Traits for pairs of values, using the first to record empty and
343 template <typename T1
, typename T2
>
346 typedef std::pair
<typename
T1::value_type
,
347 typename
T2::value_type
> value_type
;
348 typedef std::pair
<typename
T1::compare_type
,
349 typename
T2::compare_type
> compare_type
;
351 static inline hashval_t
hash (const value_type
&);
352 static inline bool equal (const value_type
&, const compare_type
&);
353 static inline void remove (value_type
&);
354 static inline void mark_deleted (value_type
&);
355 static const bool empty_zero_p
= T1::empty_zero_p
;
356 static inline void mark_empty (value_type
&);
357 static inline bool is_deleted (const value_type
&);
358 static inline bool is_empty (const value_type
&);
361 template <typename T1
, typename T2
>
363 pair_hash
<T1
, T2
>::hash (const value_type
&x
)
365 return iterative_hash_hashval_t (T1::hash (x
.first
), T2::hash (x
.second
));
368 template <typename T1
, typename T2
>
370 pair_hash
<T1
, T2
>::equal (const value_type
&x
, const compare_type
&y
)
372 return T1::equal (x
.first
, y
.first
) && T2::equal (x
.second
, y
.second
);
375 template <typename T1
, typename T2
>
377 pair_hash
<T1
, T2
>::remove (value_type
&x
)
379 T1::remove (x
.first
);
380 T2::remove (x
.second
);
383 template <typename T1
, typename T2
>
385 pair_hash
<T1
, T2
>::mark_deleted (value_type
&x
)
387 T1::mark_deleted (x
.first
);
390 template <typename T1
, typename T2
>
392 pair_hash
<T1
, T2
>::mark_empty (value_type
&x
)
394 T1::mark_empty (x
.first
);
397 template <typename T1
, typename T2
>
399 pair_hash
<T1
, T2
>::is_deleted (const value_type
&x
)
401 return T1::is_deleted (x
.first
);
404 template <typename T1
, typename T2
>
406 pair_hash
<T1
, T2
>::is_empty (const value_type
&x
)
408 return T1::is_empty (x
.first
);
411 /* Base traits for vectors, providing just the hash and comparison
412 functionality. Type gives the corresponding traits for the element
415 template <typename Type
>
418 typedef vec
<typename
Type::value_type
> value_type
;
419 typedef vec
<typename
Type::compare_type
> compare_type
;
421 static inline hashval_t
hash (value_type
);
422 static inline bool equal (value_type
, compare_type
);
425 template <typename Type
>
427 vec_hash_base
<Type
>::hash (value_type x
)
429 inchash::hash hstate
;
430 hstate
.add_int (x
.length ());
431 for (auto &value
: x
)
432 hstate
.merge_hash (Type::hash (value
));
433 return hstate
.end ();
436 template <typename Type
>
438 vec_hash_base
<Type
>::equal (value_type x
, compare_type y
)
440 if (x
.length () != y
.length ())
442 for (unsigned int i
= 0; i
< x
.length (); ++i
)
443 if (!Type::equal (x
[i
], y
[i
]))
448 /* Traits for vectors whose contents should be freed normally. */
450 template <typename Type
>
451 struct vec_free_hash_base
: vec_hash_base
<Type
>
453 static void remove (typename vec_hash_base
<Type
>::value_type
&);
456 template <typename Type
>
458 vec_free_hash_base
<Type
>
459 ::remove (typename vec_hash_base
<Type
>::value_type
&x
)
461 for (auto &value
: x
)
466 template <typename T
> struct default_hash_traits
: T
{};
468 template <typename T
>
469 struct default_hash_traits
<T
*> : ggc_ptr_hash
<T
> {};