From f52492fd160bef626cd0ea8b4f1d62a3030a1cb9 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 13 Jan 2020 11:17:31 -0500 Subject: [PATCH] FIXME: experiments with fixing hash_map::empty --- gcc/hash-map-traits.h | 16 ++++++++++++++++ gcc/hash-map.h | 4 ++++ gcc/hash-table.h | 10 ++++++---- gcc/hash-traits.h | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/gcc/hash-map-traits.h b/gcc/hash-map-traits.h index 4764380b364..051e1d4b899 100644 --- a/gcc/hash-map-traits.h +++ b/gcc/hash-map-traits.h @@ -39,6 +39,7 @@ struct simple_hashmap_traits template static inline bool is_empty (const T &); template static inline bool is_deleted (const T &); template static inline void mark_empty (T &); + template static inline void bulk_mark_empty (T *, size_t); template static inline void mark_deleted (T &); }; @@ -90,6 +91,21 @@ simple_hashmap_traits ::mark_empty (T &entry) H::mark_empty (entry.m_key); } +template +template +inline void +simple_hashmap_traits ::bulk_mark_empty (T *entry, size_t count) +{ +#if 0 + /* This assumes that the value type is a POD. */ + if (H::empty_is_all_zeroes_p () && std::is_pod ()) + memset (entry, 0, sizeof (T) * count); + else +#endif + for (size_t i = 0; i < count; i++) + mark_empty (entry[i]); +} + template template inline void diff --git a/gcc/hash-map.h b/gcc/hash-map.h index 7cb466767ea..472e420edba 100644 --- a/gcc/hash-map.h +++ b/gcc/hash-map.h @@ -68,6 +68,10 @@ class GTY((user)) hash_map static void mark_empty (hash_entry &e) { Traits::mark_empty (e); } static bool is_empty (const hash_entry &e) { return Traits::is_empty (e); } + static void bulk_mark_empty (hash_entry *e, size_t count) + { + Traits::bulk_mark_empty (e, count); + } static void ggc_mx (hash_entry &e) { diff --git a/gcc/hash-table.h b/gcc/hash-table.h index 539f8ba7adb..75da7f4201c 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -551,6 +551,11 @@ private: Descriptor::mark_empty (v); } + static void bulk_mark_empty (value_type *v, size_t count) + { + Descriptor::bulk_mark_empty (v, count); + } + /* Table itself. */ typename Descriptor::value_type *m_entries; @@ -868,10 +873,7 @@ hash_table::empty_slow () m_size_prime_index = nindex; } else - { - for (size_t i = 0; i < size; i++) - mark_empty (entries[i]); - } + bulk_mark_empty (entries, size); m_n_deleted = 0; m_n_elements = 0; diff --git a/gcc/hash-traits.h b/gcc/hash-traits.h index d259a41a418..fdcac613c4c 100644 --- a/gcc/hash-traits.h +++ b/gcc/hash-traits.h @@ -91,6 +91,7 @@ struct int_hash : typed_noop_remove static inline void mark_empty (Type &); static inline bool is_deleted (Type); static inline bool is_empty (Type); + static inline bool empty_is_all_zeroes_p (); }; template @@ -136,6 +137,12 @@ int_hash ::is_empty (Type x) return x == Empty; } +template +inline bool empty_is_all_zeroes_p () +{ + return Empty == 0; +} + /* 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). */ @@ -151,8 +158,10 @@ struct pointer_hash const compare_type &candidate); static inline void mark_deleted (Type *&); static inline void mark_empty (Type *&); + static inline void bulk_mark_empty (Type **, size_t); static inline bool is_deleted (Type *); static inline bool is_empty (Type *); + static inline bool empty_is_all_zeroes_p (); }; template @@ -186,6 +195,13 @@ pointer_hash ::mark_empty (Type *&e) e = NULL; } +template +inline void +pointer_hash ::bulk_mark_empty (Type **e, size_t count) +{ + memset (e, 0, sizeof (Type *) * count); +} + template inline bool pointer_hash ::is_deleted (Type *e) @@ -200,6 +216,13 @@ pointer_hash ::is_empty (Type *e) return e == NULL; } +template +inline bool +pointer_hash ::empty_is_all_zeroes_p () +{ + return true; +} + /* Hasher for "const char *" strings, using string rather than pointer equality. */ -- 2.21.0