Support GTY((cache)) on hash_map.

gcc/
	* hash-traits.h (ggc_remove): Add ggc_maybe_mx member function.
	(ggc_cache_remove): Override it instead of ggc_mx.
	* hash-table.h (gt_ggc_mx): Call it instead of ggc_mx.
	(gt_cleare_cache): Call ggc_mx instead of gt_ggc_mx.
	* hash-map-traits.h (simple_hashmap_traits): Add maybe_mx member.
	(simple_cache_map_traits): Override maybe_mx.
	* hash-map.h (hash_entry): Add ggc_maybe_mx and keep_cache_entry.
	(hash_map): Friend gt_cleare_cache.
	(gt_cleare_cache): New.
	* tree.h (tree_cache_traits): New hash_map traits class.
	(tree_cache_map): New typedef.
gcc/cp/
	* decl.c (decomp_type_table): Use tree_cache_map.
	* init.c (nsdmi_inst): Likewise.
	* pt.c (defarg_ints): Likewise.
	* cp-objcp-common.c (cp_get_debug_type): Likewise.

From-SVN: r254731
This commit is contained in:
Jason Merrill 2017-11-14 11:02:57 -05:00 committed by Jason Merrill
parent 55518e0f5d
commit 21faa10189
12 changed files with 96 additions and 53 deletions

View File

@ -1,3 +1,18 @@
2017-11-14 Jason Merrill <jason@redhat.com>
Support GTY((cache)) on hash_map.
* hash-traits.h (ggc_remove): Add ggc_maybe_mx member function.
(ggc_cache_remove): Override it instead of ggc_mx.
* hash-table.h (gt_ggc_mx): Call it instead of ggc_mx.
(gt_cleare_cache): Call ggc_mx instead of gt_ggc_mx.
* hash-map-traits.h (simple_hashmap_traits): Add maybe_mx member.
(simple_cache_map_traits): Override maybe_mx.
* hash-map.h (hash_entry): Add ggc_maybe_mx and keep_cache_entry.
(hash_map): Friend gt_cleare_cache.
(gt_cleare_cache): New.
* tree.h (tree_cache_traits): New hash_map traits class.
(tree_cache_map): New typedef.
2017-11-14 Richard Biener <rguenther@suse.de>
* tree-cfgcleanup.c (cleanup_control_expr_graph): Remove first_p

View File

@ -1,3 +1,11 @@
2017-11-14 Jason Merrill <jason@redhat.com>
Use GTY((cache)) on some hash tables.
* decl.c (decomp_type_table): Use tree_cache_map.
* init.c (nsdmi_inst): Likewise.
* pt.c (defarg_ints): Likewise.
* cp-objcp-common.c (cp_get_debug_type): Likewise.
2017-11-13 Jason Merrill <jason@redhat.com>
Capture adjustments for P0588R1.

View File

@ -122,19 +122,7 @@ cxx_types_compatible_p (tree x, tree y)
return same_type_ignoring_top_level_qualifiers_p (x, y);
}
struct debug_type_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); }
static int
keep_cache_entry (tree_map *&e)
{
return ggc_marked_p (e->base.from);
}
};
static GTY((cache)) hash_table<debug_type_hasher> *debug_type_hash;
static GTY((cache)) tree_cache_map *debug_type_map;
/* Return a type to use in the debug info instead of TYPE, or NULL_TREE to
keep TYPE. */
@ -142,38 +130,29 @@ static GTY((cache)) hash_table<debug_type_hasher> *debug_type_hash;
tree
cp_get_debug_type (const_tree type)
{
tree dtype = NULL_TREE;
if (TYPE_PTRMEMFUNC_P (type) && !typedef_variant_p (type))
dtype = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type)));
/* We cannot simply return the debug type here because the function uses
the type canonicalization hashtable, which is GC-ed, so its behavior
depends on the actual collection points. Since we are building these
types on the fly for the debug info only, they would not be attached
to any GC root and always be swept, so we would make the contents of
the debug info depend on the collection points. */
if (dtype)
{
if (debug_type_hash == NULL)
debug_type_hash = hash_table<debug_type_hasher>::create_ggc (512);
/* We cannot simply use build_offset_type here because the function uses
the type canonicalization hashtable, which is GC-ed, so its behavior
depends on the actual collection points. Since we are building these
types on the fly for the debug info only, they would not be attached
to any GC root and always be swept, so we would make the contents of
the debug info depend on the collection points. */
struct tree_map in, *h, **slot;
in.base.from = CONST_CAST_TREE (type);
in.hash = htab_hash_pointer (type);
slot = debug_type_hash->find_slot_with_hash (&in, in.hash, INSERT);
if (*slot)
return (*slot)->to;
tree t = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type)));
h = ggc_alloc<tree_map> ();
h->base.from = CONST_CAST_TREE (type);
h->hash = htab_hash_pointer (type);
h->to = t;
*slot = h;
return t;
tree ktype = CONST_CAST_TREE (type);
if (debug_type_map == NULL)
debug_type_map = tree_cache_map::create_ggc (512);
else if (tree *slot = debug_type_map->get (ktype))
return *slot;
debug_type_map->put (ktype, dtype);
}
return NULL_TREE;
return dtype;
}
/* Return -1 if dwarf ATTR shouldn't be added for DECL, or the attribute

View File

@ -5124,7 +5124,6 @@ extern GTY(()) vec<tree, va_gc> *static_decls;
/* An array of vtable-needing types that have no key function, or have
an emitted key function. */
extern GTY(()) vec<tree, va_gc> *keyed_classes;
/* Here's where we control how name mangling takes place. */

View File

@ -7283,12 +7283,13 @@ get_tuple_decomp_init (tree decl, unsigned i)
/* It's impossible to recover the decltype of a tuple decomposition variable
based on the actual type of the variable, so store it in a hash table. */
static GTY(()) hash_map<tree,tree> *decomp_type_table;
static GTY((cache)) tree_cache_map *decomp_type_table;
static void
store_decomp_type (tree v, tree t)
{
if (!decomp_type_table)
decomp_type_table = hash_map<tree,tree>::create_ggc (13);
decomp_type_table = tree_cache_map::create_ggc (13);
decomp_type_table->put (v, t);
}

View File

@ -535,7 +535,7 @@ perform_target_ctor (tree init)
/* Return the non-static data initializer for FIELD_DECL MEMBER. */
static GTY(()) hash_map<tree, tree> *nsdmi_inst;
static GTY((cache)) tree_cache_map *nsdmi_inst;
tree
get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
@ -590,7 +590,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
if (init != error_mark_node)
{
if (!nsdmi_inst)
nsdmi_inst = hash_map<tree,tree>::create_ggc (37);
nsdmi_inst = tree_cache_map::create_ggc (37);
nsdmi_inst->put (member, init);
}

View File

@ -12014,7 +12014,7 @@ tsubst_aggr_type (tree t,
}
}
static GTY(()) hash_map<tree, tree> *defarg_inst;
static GTY((cache)) tree_cache_map *defarg_inst;
/* Substitute into the default argument ARG (a default argument for
FN), which has the indicated TYPE. */
@ -12101,7 +12101,7 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
if (arg != error_mark_node && !cp_unevaluated_operand)
{
if (!defarg_inst)
defarg_inst = hash_map<tree,tree>::create_ggc (37);
defarg_inst = tree_cache_map::create_ggc (37);
defarg_inst->put (parm, arg);
}

View File

@ -32,6 +32,7 @@ template <typename H, typename Value>
struct simple_hashmap_traits
{
typedef typename H::value_type key_type;
static const bool maybe_mx = true;
static inline hashval_t hash (const key_type &);
static inline bool equal_keys (const key_type &, const key_type &);
template <typename T> static inline void remove (T &);
@ -97,6 +98,12 @@ simple_hashmap_traits <H, Value>::mark_deleted (T &entry)
H::mark_deleted (entry.m_key);
}
template <typename H, typename Value>
struct simple_cache_map_traits: public simple_hashmap_traits<H,Value>
{
static const bool maybe_mx = false;
};
/* Implement traits for a hash_map with values of type Value for cases
in which the key cannot represent empty and deleted slots. Instead
record empty and deleted entries in Value. Derived classes must

View File

@ -62,6 +62,12 @@ class GTY((user)) hash_map
gt_ggc_mx (e.m_value);
}
static void ggc_maybe_mx (hash_entry &e)
{
if (Traits::maybe_mx)
ggc_mx (e);
}
static void pch_nx (hash_entry &e)
{
gt_pch_nx (e.m_key);
@ -74,6 +80,11 @@ class GTY((user)) hash_map
pch_nx_helper (e.m_value, op, c);
}
static int keep_cache_entry (hash_entry &e)
{
return ggc_marked_p (e.m_key);
}
private:
template<typename T>
static void
@ -237,7 +248,8 @@ private:
template<typename T, typename U, typename V> friend void gt_ggc_mx (hash_map<T, U, V> *);
template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *);
template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
template<typename T, typename U, typename V> friend void gt_cleare_cache (hash_map<T, U, V> *);
hash_table<hash_entry> m_table;
};
@ -258,6 +270,13 @@ gt_pch_nx (hash_map<K, V, H> *h)
gt_pch_nx (&h->m_table);
}
template<typename K, typename V, typename H>
static inline void
gt_cleare_cache (hash_map<K, V, H> *h)
{
gt_cleare_cache (&h->m_table);
}
template<typename K, typename V, typename H>
static inline void
gt_pch_nx (hash_map<K, V, H> *h, gt_pointer_operator op, void *cookie)

View File

@ -1044,7 +1044,9 @@ gt_ggc_mx (hash_table<E> *h)
|| table::is_deleted (h->m_entries[i]))
continue;
E::ggc_mx (h->m_entries[i]);
/* Use ggc_maxbe_mx so we don't mark right away for cache tables; we'll
mark in gt_cleare_cache if appropriate. */
E::ggc_maybe_mx (h->m_entries[i]);
}
}
@ -1094,7 +1096,6 @@ template<typename H>
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;
@ -1106,7 +1107,7 @@ gt_cleare_cache (hash_table<H> *h)
if (res == 0)
h->clear_slot (&*iter);
else if (res != -1)
gt_ggc_mx (*iter);
H::ggc_mx (*iter);
}
}

View File

@ -235,6 +235,13 @@ struct ggc_remove
gt_ggc_mx (p);
}
/* Overridden in ggc_cache_remove. */
static void
ggc_maybe_mx (T &p)
{
ggc_mx (p);
}
static void
pch_nx (T &p)
{
@ -256,7 +263,7 @@ template<typename T>
struct ggc_cache_remove : ggc_remove<T>
{
/* Entries are weakly held because this is for caches. */
static void ggc_mx (T &) {}
static void ggc_maybe_mx (T &) {}
static int
keep_cache_entry (T &e)

View File

@ -4858,6 +4858,13 @@ struct tree_decl_map_cache_hasher : ggc_cache_ptr_hash<tree_decl_map>
#define tree_vec_map_hash tree_decl_map_hash
#define tree_vec_map_marked_p tree_map_base_marked_p
/* A hash_map of two trees for use with GTY((cache)). Garbage collection for
such a map will not mark keys, and will mark values if the key is already
marked. */
struct tree_cache_traits
: simple_cache_map_traits<default_hash_traits<tree>, tree> { };
typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;
/* Initialize the abstract argument list iterator object ITER with the
arguments from CALL_EXPR node EXP. */
static inline void