+2017-01-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * hash-table.h (hash_table::too_empty_p): New function.
+ (hash_table::expand): Use it.
+ (hash_table::traverse): Likewise.
+ (hash_table::empty_slot): Use sizeof (value_type) instead of
+ sizeof (PTR) to convert bytes to elements. Shrink the table
+ if the current size is excessive for the current number of
+ elements.
+
2017-01-13 Richard Sandiford <richard.sandiford@arm.com>
* ira-costs.c (record_reg_classes): Break from the inner loop
value_type *alloc_entries (size_t n CXX_MEM_STAT_INFO) const;
value_type *find_empty_slot_for_expand (hashval_t);
+ bool too_empty_p (unsigned int);
void expand ();
static bool is_deleted (value_type &v)
{
}
}
+/* Return true if the current table is excessively big for ELTS elements. */
+
+template<typename Descriptor, template<typename Type> class Allocator>
+inline bool
+hash_table<Descriptor, Allocator>::too_empty_p (unsigned int elts)
+{
+ return elts * 8 < m_size && m_size > 32;
+}
+
/* The following function changes size of memory allocated for the
entries and repeatedly inserts the table elements. The occupancy
of the table after the call will be about 50%. Naturally the hash
too full or too empty. */
unsigned int nindex;
size_t nsize;
- if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
+ if (elts * 2 > osize || too_empty_p (elts))
{
nindex = hash_table_higher_prime_index (elts * 2);
nsize = prime_tab[nindex].prime;
hash_table<Descriptor, Allocator>::empty_slow ()
{
size_t size = m_size;
+ size_t nsize = size;
value_type *entries = m_entries;
int i;
Descriptor::remove (entries[i]);
/* Instead of clearing megabyte, downsize the table. */
- if (size > 1024*1024 / sizeof (PTR))
+ if (size > 1024*1024 / sizeof (value_type))
+ nsize = 1024 / sizeof (value_type);
+ else if (too_empty_p (m_n_elements))
+ nsize = m_n_elements * 2;
+
+ if (nsize != size)
{
- int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
+ int nindex = hash_table_higher_prime_index (nsize);
int nsize = prime_tab[nindex].prime;
if (!m_ggc)
void
hash_table<Descriptor, Allocator>::traverse (Argument argument)
{
- size_t size = m_size;
- if (elements () * 8 < size && size > 32)
+ if (too_empty_p (elements ()))
expand ();
traverse_noresize <Argument, Callback> (argument);