move many gc hashtab to hash_table

gcc/

* asan.c, cfgloop.c, cfgloop.h, cgraph.c, cgraph.h,
	config/darwin.c, config/m32c/m32c.c, config/mep/mep.c,
	config/mips/mips.c, config/rs6000/rs6000.c, dwarf2out.c,
	function.c, function.h, gimple-ssa.h, libfuncs.h, optabs.c,
	output.h, rtl.h, sese.c, symtab.c, tree-cfg.c, tree-dfa.c,
	tree-ssa.c, varasm.c: Use hash-table instead of hashtab.
	* doc/gty.texi (for_user): Document new option.
	* gengtype.c (create_user_defined_type): Don't try to get a struct for
	char.
	(walk_type): Don't error out on for_user option.
	(write_func_for_structure): Emit user marking routines if requested by
	for_user option.
	(write_local_func_for_structure): Likewise.
	(main): Mark types with for_user option as used.
	* ggc.h (gt_pch_nx): Add overload for unsigned int.
	* hash-map.h (hash_map::hash_entry::pch_nx_helper): AddOverloads.
	* hash-table.h (ggc_hasher): New struct.
	(hash_table::create_ggc): New function.
	(gt_pch_nx): New overload for hash_table.

java/

	* class.c, decl.c, except.c, expr.c, java-tree.h, lang.c: Use
	hash_table instead of hashtab.

objc/

	* objc-act.c: use hash_table instead of hashtab.

cp/

	* cp-gimplify.c, cp-tree.h, decl.c, mangle.c, name-lookup.c,
	pt.c, semantics.c, tree.c, typeck2.c: Use hash_table instead of
	hashtab.

fortran/

	* trans-decl.c, trans.c, trans.h: Use hash_table instead of hashtab.

c-family/

	* c-common.c: Use hash_table instead of hashtab.

From-SVN: r216127
This commit is contained in:
Trevor Saunders 2014-10-12 22:22:53 +00:00 committed by Trevor Saunders
parent 7b262a51ea
commit 2a22f99cb1
55 changed files with 1357 additions and 1237 deletions

View File

@ -1,3 +1,25 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* asan.c, cfgloop.c, cfgloop.h, cgraph.c, cgraph.h,
config/darwin.c, config/m32c/m32c.c, config/mep/mep.c,
config/mips/mips.c, config/rs6000/rs6000.c, dwarf2out.c,
function.c, function.h, gimple-ssa.h, libfuncs.h, optabs.c,
output.h, rtl.h, sese.c, symtab.c, tree-cfg.c, tree-dfa.c,
tree-ssa.c, varasm.c: Use hash-table instead of hashtab.
* doc/gty.texi (for_user): Document new option.
* gengtype.c (create_user_defined_type): Don't try to get a struct for
char.
(walk_type): Don't error out on for_user option.
(write_func_for_structure): Emit user marking routines if requested by
for_user option.
(write_local_func_for_structure): Likewise.
(main): Mark types with for_user option as used.
* ggc.h (gt_pch_nx): Add overload for unsigned int.
* hash-map.h (hash_map::hash_entry::pch_nx_helper): AddOverloads.
* hash-table.h (ggc_hasher): New struct.
(hash_table::create_ggc): New function.
(gt_pch_nx): New overload for hash_table.
2014-10-11 Oleg Endo <olegendo@gcc.gnu.org> 2014-10-11 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.h (TARGET_SH4A_ARCH): Remove macro. * config/sh/sh.h (TARGET_SH4A_ARCH): Remove macro.

View File

@ -2368,15 +2368,15 @@ initialize_sanitizer_builtins (void)
/* Called via htab_traverse. Count number of emitted /* Called via htab_traverse. Count number of emitted
STRING_CSTs in the constant hash table. */ STRING_CSTs in the constant hash table. */
static int int
count_string_csts (void **slot, void *data) count_string_csts (constant_descriptor_tree **slot,
unsigned HOST_WIDE_INT *data)
{ {
struct constant_descriptor_tree *desc struct constant_descriptor_tree *desc = *slot;
= (struct constant_descriptor_tree *) *slot;
if (TREE_CODE (desc->value) == STRING_CST if (TREE_CODE (desc->value) == STRING_CST
&& TREE_ASM_WRITTEN (desc->value) && TREE_ASM_WRITTEN (desc->value)
&& asan_protect_global (desc->value)) && asan_protect_global (desc->value))
++*((unsigned HOST_WIDE_INT *) data); ++*data;
return 1; return 1;
} }
@ -2389,20 +2389,18 @@ struct asan_add_string_csts_data
vec<constructor_elt, va_gc> *v; vec<constructor_elt, va_gc> *v;
}; };
/* Called via htab_traverse. Call asan_add_global /* Called via hash_table::traverse. Call asan_add_global
on emitted STRING_CSTs from the constant hash table. */ on emitted STRING_CSTs from the constant hash table. */
static int int
add_string_csts (void **slot, void *data) add_string_csts (constant_descriptor_tree **slot,
asan_add_string_csts_data *aascd)
{ {
struct constant_descriptor_tree *desc struct constant_descriptor_tree *desc = *slot;
= (struct constant_descriptor_tree *) *slot;
if (TREE_CODE (desc->value) == STRING_CST if (TREE_CODE (desc->value) == STRING_CST
&& TREE_ASM_WRITTEN (desc->value) && TREE_ASM_WRITTEN (desc->value)
&& asan_protect_global (desc->value)) && asan_protect_global (desc->value))
{ {
struct asan_add_string_csts_data *aascd
= (struct asan_add_string_csts_data *) data;
asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)), asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
aascd->type, aascd->v); aascd->type, aascd->v);
} }
@ -2440,8 +2438,9 @@ asan_finish_file (void)
if (TREE_ASM_WRITTEN (vnode->decl) if (TREE_ASM_WRITTEN (vnode->decl)
&& asan_protect_global (vnode->decl)) && asan_protect_global (vnode->decl))
++gcount; ++gcount;
htab_t const_desc_htab = constant_pool_htab (); hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
htab_traverse (const_desc_htab, count_string_csts, &gcount); const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
(&gcount);
if (gcount) if (gcount)
{ {
tree type = asan_global_struct (), var, ctor; tree type = asan_global_struct (), var, ctor;
@ -2465,7 +2464,8 @@ asan_finish_file (void)
struct asan_add_string_csts_data aascd; struct asan_add_string_csts_data aascd;
aascd.type = TREE_TYPE (type); aascd.type = TREE_TYPE (type);
aascd.v = v; aascd.v = v;
htab_traverse (const_desc_htab, add_string_csts, &aascd); const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
(&aascd);
ctor = build_constructor (type, v); ctor = build_constructor (type, v);
TREE_CONSTANT (ctor) = 1; TREE_CONSTANT (ctor) = 1;
TREE_STATIC (ctor) = 1; TREE_STATIC (ctor) = 1;

View File

@ -1,3 +1,7 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* c-common.c: Use hash_table instead of hashtab.
2014-10-06 Edward Smith-Rowland <3dw4rd@verizon.net> 2014-10-06 Edward Smith-Rowland <3dw4rd@verizon.net>
* c-family/c-cppbuiltin.c: Move __cpp_attribute_deprecated to the * c-family/c-cppbuiltin.c: Move __cpp_attribute_deprecated to the

View File

@ -4803,23 +4803,28 @@ c_apply_type_quals_to_decl (int type_quals, tree decl)
} }
} }
struct c_type_hasher : ggc_hasher<tree>
{
static hashval_t hash (tree);
static bool equal (tree, tree);
};
/* Hash function for the problem of multiple type definitions in /* Hash function for the problem of multiple type definitions in
different files. This must hash all types that will compare different files. This must hash all types that will compare
equal via comptypes to the same value. In practice it hashes equal via comptypes to the same value. In practice it hashes
on some of the simple stuff and leaves the details to comptypes. */ on some of the simple stuff and leaves the details to comptypes. */
static hashval_t hashval_t
c_type_hash (const void *p) c_type_hasher::hash (tree t)
{ {
int n_elements; int n_elements;
int shift, size; int shift, size;
const_tree const t = (const_tree) p;
tree t2; tree t2;
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
/* For pointers, hash on pointee type plus some swizzling. */ /* For pointers, hash on pointee type plus some swizzling. */
case POINTER_TYPE: case POINTER_TYPE:
return c_type_hash (TREE_TYPE (t)) ^ 0x3003003; return hash (TREE_TYPE (t)) ^ 0x3003003;
/* Hash on number of elements and total size. */ /* Hash on number of elements and total size. */
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
shift = 3; shift = 3;
@ -4851,7 +4856,13 @@ c_type_hash (const void *p)
return ((size << 24) | (n_elements << shift)); return ((size << 24) | (n_elements << shift));
} }
static GTY((param_is (union tree_node))) htab_t type_hash_table; bool
c_type_hasher::equal (tree t1, tree t2)
{
return lang_hooks.types_compatible_p (t1, t2);
}
static GTY(()) hash_table<c_type_hasher> *type_hash_table;
/* Return the typed-based alias set for T, which may be an expression /* Return the typed-based alias set for T, which may be an expression
or a type. Return -1 if we don't do anything special. */ or a type. Return -1 if we don't do anything special. */
@ -4860,7 +4871,6 @@ alias_set_type
c_common_get_alias_set (tree t) c_common_get_alias_set (tree t)
{ {
tree u; tree u;
PTR *slot;
/* For VLAs, use the alias set of the element type rather than the /* For VLAs, use the alias set of the element type rather than the
default of alias set 0 for types compared structurally. */ default of alias set 0 for types compared structurally. */
@ -4953,10 +4963,8 @@ c_common_get_alias_set (tree t)
/* Look up t in hash table. Only one of the compatible types within each /* Look up t in hash table. Only one of the compatible types within each
alias set is recorded in the table. */ alias set is recorded in the table. */
if (!type_hash_table) if (!type_hash_table)
type_hash_table = htab_create_ggc (1021, c_type_hash, type_hash_table = hash_table<c_type_hasher>::create_ggc (1021);
(htab_eq) lang_hooks.types_compatible_p, tree *slot = type_hash_table->find_slot (t, INSERT);
NULL);
slot = htab_find_slot (type_hash_table, t, INSERT);
if (*slot != NULL) if (*slot != NULL)
{ {
TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot); TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot);

View File

@ -958,31 +958,26 @@ get_loop_body_in_bfs_order (const struct loop *loop)
/* Hash function for struct loop_exit. */ /* Hash function for struct loop_exit. */
static hashval_t hashval_t
loop_exit_hash (const void *ex) loop_exit_hasher::hash (loop_exit *exit)
{ {
const struct loop_exit *const exit = (const struct loop_exit *) ex;
return htab_hash_pointer (exit->e); return htab_hash_pointer (exit->e);
} }
/* Equality function for struct loop_exit. Compares with edge. */ /* Equality function for struct loop_exit. Compares with edge. */
static int bool
loop_exit_eq (const void *ex, const void *e) loop_exit_hasher::equal (loop_exit *exit, edge e)
{ {
const struct loop_exit *const exit = (const struct loop_exit *) ex;
return exit->e == e; return exit->e == e;
} }
/* Frees the list of loop exit descriptions EX. */ /* Frees the list of loop exit descriptions EX. */
static void void
loop_exit_free (void *ex) loop_exit_hasher::remove (loop_exit *exit)
{ {
struct loop_exit *exit = (struct loop_exit *) ex, *next; loop_exit *next;
for (; exit; exit = next) for (; exit; exit = next)
{ {
next = exit->next_e; next = exit->next_e;
@ -999,8 +994,7 @@ loop_exit_free (void *ex)
static struct loop_exit * static struct loop_exit *
get_exit_descriptions (edge e) get_exit_descriptions (edge e)
{ {
return (struct loop_exit *) htab_find_with_hash (current_loops->exits, e, return current_loops->exits->find_with_hash (e, htab_hash_pointer (e));
htab_hash_pointer (e));
} }
/* Updates the lists of loop exits in that E appears. /* Updates the lists of loop exits in that E appears.
@ -1012,7 +1006,6 @@ get_exit_descriptions (edge e)
void void
rescan_loop_exit (edge e, bool new_edge, bool removed) rescan_loop_exit (edge e, bool new_edge, bool removed)
{ {
void **slot;
struct loop_exit *exits = NULL, *exit; struct loop_exit *exits = NULL, *exit;
struct loop *aloop, *cloop; struct loop *aloop, *cloop;
@ -1045,20 +1038,20 @@ rescan_loop_exit (edge e, bool new_edge, bool removed)
if (!exits && new_edge) if (!exits && new_edge)
return; return;
slot = htab_find_slot_with_hash (current_loops->exits, e, loop_exit **slot
htab_hash_pointer (e), = current_loops->exits->find_slot_with_hash (e, htab_hash_pointer (e),
exits ? INSERT : NO_INSERT); exits ? INSERT : NO_INSERT);
if (!slot) if (!slot)
return; return;
if (exits) if (exits)
{ {
if (*slot) if (*slot)
loop_exit_free (*slot); loop_exit_hasher::remove (*slot);
*slot = exits; *slot = exits;
} }
else else
htab_clear_slot (current_loops->exits, slot); current_loops->exits->clear_slot (slot);
} }
/* For each loop, record list of exit edges, and start maintaining these /* For each loop, record list of exit edges, and start maintaining these
@ -1079,9 +1072,8 @@ record_loop_exits (void)
loops_state_set (LOOPS_HAVE_RECORDED_EXITS); loops_state_set (LOOPS_HAVE_RECORDED_EXITS);
gcc_assert (current_loops->exits == NULL); gcc_assert (current_loops->exits == NULL);
current_loops->exits = htab_create_ggc (2 * number_of_loops (cfun), current_loops->exits
loop_exit_hash, loop_exit_eq, = hash_table<loop_exit_hasher>::create_ggc (2 * number_of_loops (cfun));
loop_exit_free);
FOR_EACH_BB_FN (bb, cfun) FOR_EACH_BB_FN (bb, cfun)
{ {
@ -1095,17 +1087,17 @@ record_loop_exits (void)
/* Dumps information about the exit in *SLOT to FILE. /* Dumps information about the exit in *SLOT to FILE.
Callback for htab_traverse. */ Callback for htab_traverse. */
static int int
dump_recorded_exit (void **slot, void *file) dump_recorded_exit (loop_exit **slot, FILE *file)
{ {
struct loop_exit *exit = (struct loop_exit *) *slot; struct loop_exit *exit = *slot;
unsigned n = 0; unsigned n = 0;
edge e = exit->e; edge e = exit->e;
for (; exit != NULL; exit = exit->next_e) for (; exit != NULL; exit = exit->next_e)
n++; n++;
fprintf ((FILE*) file, "Edge %d->%d exits %u loops\n", fprintf (file, "Edge %d->%d exits %u loops\n",
e->src->index, e->dest->index, n); e->src->index, e->dest->index, n);
return 1; return 1;
@ -1119,7 +1111,7 @@ dump_recorded_exits (FILE *file)
{ {
if (!current_loops->exits) if (!current_loops->exits)
return; return;
htab_traverse (current_loops->exits, dump_recorded_exit, file); current_loops->exits->traverse<FILE *, dump_recorded_exit> (file);
} }
/* Releases lists of loop exits. */ /* Releases lists of loop exits. */
@ -1128,7 +1120,7 @@ void
release_recorded_exits (void) release_recorded_exits (void)
{ {
gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS)); gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS));
htab_delete (current_loops->exits); current_loops->exits->empty ();
current_loops->exits = NULL; current_loops->exits = NULL;
loops_state_clear (LOOPS_HAVE_RECORDED_EXITS); loops_state_clear (LOOPS_HAVE_RECORDED_EXITS);
} }
@ -1623,7 +1615,7 @@ verify_loop_structure (void)
} }
} }
if (n_exits != htab_elements (current_loops->exits)) if (n_exits != current_loops->exits->elements ())
{ {
error ("too many loop exits recorded"); error ("too many loop exits recorded");
err = 1; err = 1;

View File

@ -76,7 +76,7 @@ struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
/* Description of the loop exit. */ /* Description of the loop exit. */
struct GTY (()) loop_exit { struct GTY ((for_user)) loop_exit {
/* The exit edge. */ /* The exit edge. */
edge e; edge e;
@ -88,6 +88,15 @@ struct GTY (()) loop_exit {
struct loop_exit *next_e; struct loop_exit *next_e;
}; };
struct loop_exit_hasher : ggc_hasher<loop_exit *>
{
typedef edge compare_type;
static hashval_t hash (loop_exit *);
static bool equal (loop_exit *, edge);
static void remove (loop_exit *);
};
typedef struct loop *loop_p; typedef struct loop *loop_p;
/* An integer estimation of the number of iterations. Estimate_state /* An integer estimation of the number of iterations. Estimate_state
@ -229,7 +238,7 @@ struct GTY (()) loops {
/* Maps edges to the list of their descriptions as loop exits. Edges /* Maps edges to the list of their descriptions as loop exits. Edges
whose sources or destinations have loop_father == NULL (which may whose sources or destinations have loop_father == NULL (which may
happen during the cfg manipulations) should not appear in EXITS. */ happen during the cfg manipulations) should not appear in EXITS. */
htab_t GTY((param_is (struct loop_exit))) exits; hash_table<loop_exit_hasher> *GTY(()) exits;
/* Pointer to root of loop hierarchy tree. */ /* Pointer to root of loop hierarchy tree. */
struct loop *tree_root; struct loop *tree_root;

View File

@ -103,30 +103,34 @@ struct cgraph_2node_hook_list {
struct cgraph_2node_hook_list *next; struct cgraph_2node_hook_list *next;
}; };
/* Hash descriptor for cgraph_function_version_info. */
struct function_version_hasher : ggc_hasher<cgraph_function_version_info *>
{
static hashval_t hash (cgraph_function_version_info *);
static bool equal (cgraph_function_version_info *,
cgraph_function_version_info *);
};
/* Map a cgraph_node to cgraph_function_version_info using this htab. /* Map a cgraph_node to cgraph_function_version_info using this htab.
The cgraph_function_version_info has a THIS_NODE field that is the The cgraph_function_version_info has a THIS_NODE field that is the
corresponding cgraph_node.. */ corresponding cgraph_node.. */
static GTY((param_is (cgraph_function_version_info))) htab_t static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
cgraph_fnver_htab = NULL;
/* Hash function for cgraph_fnver_htab. */ /* Hash function for cgraph_fnver_htab. */
static hashval_t hashval_t
cgraph_fnver_htab_hash (const void *ptr) function_version_hasher::hash (cgraph_function_version_info *ptr)
{ {
int uid = ((const cgraph_function_version_info *)ptr)->this_node->uid; int uid = ptr->this_node->uid;
return (hashval_t)(uid); return (hashval_t)(uid);
} }
/* eq function for cgraph_fnver_htab. */ /* eq function for cgraph_fnver_htab. */
static int bool
cgraph_fnver_htab_eq (const void *p1, const void *p2) function_version_hasher::equal (cgraph_function_version_info *n1,
cgraph_function_version_info *n2)
{ {
const cgraph_function_version_info *n1
= (const cgraph_function_version_info *)p1;
const cgraph_function_version_info *n2
= (const cgraph_function_version_info *)p2;
return n1->this_node->uid == n2->this_node->uid; return n1->this_node->uid == n2->this_node->uid;
} }
@ -138,17 +142,13 @@ static GTY(()) struct cgraph_function_version_info *
cgraph_function_version_info * cgraph_function_version_info *
cgraph_node::function_version (void) cgraph_node::function_version (void)
{ {
cgraph_function_version_info *ret;
cgraph_function_version_info key; cgraph_function_version_info key;
key.this_node = this; key.this_node = this;
if (cgraph_fnver_htab == NULL) if (cgraph_fnver_htab == NULL)
return NULL; return NULL;
ret = (cgraph_function_version_info *) return cgraph_fnver_htab->find (&key);
htab_find (cgraph_fnver_htab, &key);
return ret;
} }
/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
@ -156,19 +156,15 @@ cgraph_node::function_version (void)
cgraph_function_version_info * cgraph_function_version_info *
cgraph_node::insert_new_function_version (void) cgraph_node::insert_new_function_version (void)
{ {
void **slot;
version_info_node = NULL; version_info_node = NULL;
version_info_node = ggc_cleared_alloc<cgraph_function_version_info> (); version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
version_info_node->this_node = this; version_info_node->this_node = this;
if (cgraph_fnver_htab == NULL) if (cgraph_fnver_htab == NULL)
cgraph_fnver_htab = htab_create_ggc (2, cgraph_fnver_htab_hash, cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
cgraph_fnver_htab_eq, NULL);
slot = htab_find_slot (cgraph_fnver_htab, version_info_node, INSERT); *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
gcc_assert (slot != NULL); = version_info_node;
*slot = version_info_node;
return version_info_node; return version_info_node;
} }
@ -195,7 +191,7 @@ cgraph_node::delete_function_version (tree decl)
decl_v->next->prev = decl_v->prev; decl_v->next->prev = decl_v->prev;
if (cgraph_fnver_htab != NULL) if (cgraph_fnver_htab != NULL)
htab_remove_elt (cgraph_fnver_htab, decl_v); cgraph_fnver_htab->remove_elt (decl_v);
decl_node->remove (); decl_node->remove ();
} }
@ -596,18 +592,18 @@ cgraph_node::get_for_asmname (tree asmname)
/* Returns a hash value for X (which really is a cgraph_edge). */ /* Returns a hash value for X (which really is a cgraph_edge). */
static hashval_t hashval_t
edge_hash (const void *x) cgraph_edge_hasher::hash (cgraph_edge *e)
{ {
return htab_hash_pointer (((const cgraph_edge *) x)->call_stmt); return htab_hash_pointer (e->call_stmt);
} }
/* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y. */ /* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y. */
static int inline bool
edge_eq (const void *x, const void *y) cgraph_edge_hasher::equal (cgraph_edge *x, gimple y)
{ {
return ((const cgraph_edge *) x)->call_stmt == y; return x->call_stmt == y;
} }
/* Add call graph edge E to call site hash of its caller. */ /* Add call graph edge E to call site hash of its caller. */
@ -615,12 +611,10 @@ edge_eq (const void *x, const void *y)
static inline void static inline void
cgraph_update_edge_in_call_site_hash (cgraph_edge *e) cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
{ {
void **slot; gimple call = e->call_stmt;
slot = htab_find_slot_with_hash (e->caller->call_site_hash, *e->caller->call_site_hash->find_slot_with_hash (call,
e->call_stmt, htab_hash_pointer (call),
htab_hash_pointer (e->call_stmt), INSERT) = e;
INSERT);
*slot = e;
} }
/* Add call graph edge E to call site hash of its caller. */ /* Add call graph edge E to call site hash of its caller. */
@ -628,15 +622,13 @@ cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
static inline void static inline void
cgraph_add_edge_to_call_site_hash (cgraph_edge *e) cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
{ {
void **slot;
/* There are two speculative edges for every statement (one direct, /* There are two speculative edges for every statement (one direct,
one indirect); always hash the direct one. */ one indirect); always hash the direct one. */
if (e->speculative && e->indirect_unknown_callee) if (e->speculative && e->indirect_unknown_callee)
return; return;
slot = htab_find_slot_with_hash (e->caller->call_site_hash, cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
e->call_stmt, (e->call_stmt,
htab_hash_pointer (e->call_stmt), htab_hash_pointer (e->call_stmt), INSERT);
INSERT);
if (*slot) if (*slot)
{ {
gcc_assert (((cgraph_edge *)*slot)->speculative); gcc_assert (((cgraph_edge *)*slot)->speculative);
@ -658,9 +650,8 @@ cgraph_node::get_edge (gimple call_stmt)
int n = 0; int n = 0;
if (call_site_hash) if (call_site_hash)
return (cgraph_edge *) return call_site_hash->find_with_hash (call_stmt,
htab_find_with_hash (call_site_hash, call_stmt, htab_hash_pointer (call_stmt));
htab_hash_pointer (call_stmt));
/* This loop may turn out to be performance problem. In such case adding /* This loop may turn out to be performance problem. In such case adding
hashtables into call nodes with very many edges is probably best hashtables into call nodes with very many edges is probably best
@ -684,7 +675,7 @@ cgraph_node::get_edge (gimple call_stmt)
if (n > 100) if (n > 100)
{ {
call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL); call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
for (e2 = callees; e2; e2 = e2->next_callee) for (e2 = callees; e2; e2 = e2->next_callee)
cgraph_add_edge_to_call_site_hash (e2); cgraph_add_edge_to_call_site_hash (e2);
for (e2 = indirect_calls; e2; e2 = e2->next_callee) for (e2 = indirect_calls; e2; e2 = e2->next_callee)
@ -722,9 +713,8 @@ cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative)
if (caller->call_site_hash if (caller->call_site_hash
&& (!speculative || !indirect_unknown_callee)) && (!speculative || !indirect_unknown_callee))
{ {
htab_remove_elt_with_hash (caller->call_site_hash, caller->call_site_hash->remove_elt_with_hash
call_stmt, (call_stmt, htab_hash_pointer (call_stmt));
htab_hash_pointer (call_stmt));
} }
cgraph_edge *e = this; cgraph_edge *e = this;
@ -942,9 +932,8 @@ cgraph_edge::remove_caller (void)
caller->callees = next_callee; caller->callees = next_callee;
} }
if (caller->call_site_hash) if (caller->call_site_hash)
htab_remove_elt_with_hash (caller->call_site_hash, caller->call_site_hash->remove_elt_with_hash (call_stmt,
call_stmt, htab_hash_pointer (call_stmt));
htab_hash_pointer (call_stmt));
} }
/* Put the edge onto the free list. */ /* Put the edge onto the free list. */
@ -1564,7 +1553,7 @@ cgraph_node::remove_callees (void)
callees = NULL; callees = NULL;
if (call_site_hash) if (call_site_hash)
{ {
htab_delete (call_site_hash); call_site_hash->empty ();
call_site_hash = NULL; call_site_hash = NULL;
} }
} }
@ -1743,7 +1732,7 @@ cgraph_node::remove (void)
decl = NULL; decl = NULL;
if (call_site_hash) if (call_site_hash)
{ {
htab_delete (call_site_hash); call_site_hash->empty ();
call_site_hash = NULL; call_site_hash = NULL;
} }

View File

@ -42,7 +42,7 @@ enum symtab_type
/* Section names are stored as reference counted strings in GGC safe hashtable /* Section names are stored as reference counted strings in GGC safe hashtable
(to make them survive through PCH). */ (to make them survive through PCH). */
struct GTY(()) section_hash_entry_d struct GTY((for_user)) section_hash_entry_d
{ {
int ref_count; int ref_count;
char *name; /* As long as this datastructure stays in GGC, we can not put char *name; /* As long as this datastructure stays in GGC, we can not put
@ -52,6 +52,14 @@ struct GTY(()) section_hash_entry_d
typedef struct section_hash_entry_d section_hash_entry; typedef struct section_hash_entry_d section_hash_entry;
struct section_name_hasher : ggc_hasher<section_hash_entry *>
{
typedef const char *compare_type;
static hashval_t hash (section_hash_entry *);
static bool equal (section_hash_entry *, const char *);
};
enum availability enum availability
{ {
/* Not yet set by cgraph_function_body_availability. */ /* Not yet set by cgraph_function_body_availability. */
@ -704,7 +712,7 @@ struct GTY(()) cgraph_simd_clone {
}; };
/* Function Multiversioning info. */ /* Function Multiversioning info. */
struct GTY(()) cgraph_function_version_info { struct GTY((for_user)) cgraph_function_version_info {
/* The cgraph_node for which the function version info is stored. */ /* The cgraph_node for which the function version info is stored. */
cgraph_node *this_node; cgraph_node *this_node;
/* Chains all the semantically identical function versions. The /* Chains all the semantically identical function versions. The
@ -743,6 +751,14 @@ enum cgraph_inline_failed_type_t
struct cgraph_edge; struct cgraph_edge;
struct cgraph_edge_hasher : ggc_hasher<cgraph_edge *>
{
typedef gimple compare_type;
static hashval_t hash (cgraph_edge *);
static bool equal (cgraph_edge *, gimple);
};
/* The cgraph data structure. /* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */ Each function decl has assigned cgraph_node listing callees and callers. */
@ -1175,7 +1191,7 @@ public:
cgraph_node *clone_of; cgraph_node *clone_of;
/* For functions with many calls sites it holds map from call expression /* For functions with many calls sites it holds map from call expression
to the edge to speed up cgraph_edge function. */ to the edge to speed up cgraph_edge function. */
htab_t GTY((param_is (cgraph_edge))) call_site_hash; hash_table<cgraph_edge_hasher> *GTY(()) call_site_hash;
/* Declaration node used to be clone of. */ /* Declaration node used to be clone of. */
tree former_clone_of; tree former_clone_of;
@ -1401,7 +1417,8 @@ struct GTY(()) cgraph_indirect_call_info
unsigned vptr_changed : 1; unsigned vptr_changed : 1;
}; };
struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge { struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
for_user)) cgraph_edge {
friend class cgraph_node; friend class cgraph_node;
/* Remove the edge in the cgraph. */ /* Remove the edge in the cgraph. */
@ -1733,6 +1750,20 @@ enum symtab_state
FINISHED FINISHED
}; };
struct asmname_hasher
{
typedef symtab_node *value_type;
typedef const_tree compare_type;
typedef int store_values_directly;
static hashval_t hash (symtab_node *n);
static bool equal (symtab_node *n, const_tree t);
static void ggc_mx (symtab_node *n);
static void pch_nx (symtab_node *&);
static void pch_nx (symtab_node *&, gt_pointer_operator, void *);
static void remove (symtab_node *) {}
};
class GTY((tag ("SYMTAB"))) symbol_table class GTY((tag ("SYMTAB"))) symbol_table
{ {
public: public:
@ -1969,10 +2000,10 @@ public:
bool cpp_implicit_aliases_done; bool cpp_implicit_aliases_done;
/* Hash table used to hold sectoons. */ /* Hash table used to hold sectoons. */
htab_t GTY((param_is (section_hash_entry))) section_hash; hash_table<section_name_hasher> *GTY(()) section_hash;
/* Hash table used to convert assembler names into nodes. */ /* Hash table used to convert assembler names into nodes. */
htab_t GTY((param_is (symtab_node))) assembler_name_hash; hash_table<asmname_hasher> *assembler_name_hash;
/* Hash table used to hold init priorities. */ /* Hash table used to hold init priorities. */
hash_map<symtab_node *, symbol_priority_map> *init_priority_hash; hash_map<symtab_node *, symbol_priority_map> *init_priority_hash;
@ -2005,11 +2036,7 @@ private:
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */ /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
static bool decl_assembler_name_equal (tree decl, const_tree asmname); static bool decl_assembler_name_equal (tree decl, const_tree asmname);
/* Returns a hash code for P. */ friend struct asmname_hasher;
static hashval_t hash_node_by_assembler_name (const void *p);
/* Returns nonzero if P1 and P2 are equal. */
static int eq_assembler_name (const void *p1, const void *p2);
/* List of hooks triggered when an edge is removed. */ /* List of hooks triggered when an edge is removed. */
cgraph_edge_hook_list * GTY((skip)) m_first_edge_removal_hook; cgraph_edge_hook_list * GTY((skip)) m_first_edge_removal_hook;
@ -2031,6 +2058,41 @@ extern GTY(()) symbol_table *symtab;
extern vec<cgraph_node *> cgraph_new_nodes; extern vec<cgraph_node *> cgraph_new_nodes;
inline hashval_t
asmname_hasher::hash (symtab_node *n)
{
return symbol_table::decl_assembler_name_hash
(DECL_ASSEMBLER_NAME (n->decl));
}
inline bool
asmname_hasher::equal (symtab_node *n, const_tree t)
{
return symbol_table::decl_assembler_name_equal (n->decl, t);
}
extern void gt_ggc_mx (symtab_node *&);
inline void
asmname_hasher::ggc_mx (symtab_node *n)
{
gt_ggc_mx (n);
}
extern void gt_pch_nx (symtab_node *&);
inline void
asmname_hasher::pch_nx (symtab_node *&n)
{
gt_pch_nx (n);
}
inline void
asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie)
{
op (&n, cookie);
}
/* In cgraph.c */ /* In cgraph.c */
void release_function_body (tree); void release_function_body (tree);
cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void); cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
@ -2485,7 +2547,7 @@ tree add_new_static_var (tree type);
Each constant in memory thus far output is recorded Each constant in memory thus far output is recorded
in `const_desc_table'. */ in `const_desc_table'. */
struct GTY(()) constant_descriptor_tree { struct GTY((for_user)) constant_descriptor_tree {
/* A MEM for the constant. */ /* A MEM for the constant. */
rtx rtl; rtx rtl;
@ -2544,8 +2606,14 @@ varpool_node::all_refs_explicit_p ()
&& !force_output); && !force_output);
} }
struct tree_descriptor_hasher : ggc_hasher<constant_descriptor_tree *>
{
static hashval_t hash (constant_descriptor_tree *);
static bool equal (constant_descriptor_tree *, constant_descriptor_tree *);
};
/* Constant pool accessor function. */ /* Constant pool accessor function. */
htab_t constant_pool_htab (void); hash_table<tree_descriptor_hasher> *constant_pool_htab (void);
/* Return node that alias is aliasing. */ /* Return node that alias is aliasing. */

View File

@ -450,7 +450,7 @@ machopic_should_output_picbase_label (void)
/* The suffix attached to stub symbols. */ /* The suffix attached to stub symbols. */
#define STUB_SUFFIX "$stub" #define STUB_SUFFIX "$stub"
typedef struct GTY (()) machopic_indirection typedef struct GTY ((for_user)) machopic_indirection
{ {
/* The SYMBOL_REF for the entity referenced. */ /* The SYMBOL_REF for the entity referenced. */
rtx symbol; rtx symbol;
@ -463,29 +463,33 @@ typedef struct GTY (()) machopic_indirection
bool used; bool used;
} machopic_indirection; } machopic_indirection;
struct indirection_hasher : ggc_hasher<machopic_indirection *>
{
typedef const char *compare_type;
static hashval_t hash (machopic_indirection *);
static bool equal (machopic_indirection *, const char *);
};
/* A table mapping stub names and non-lazy pointer names to /* A table mapping stub names and non-lazy pointer names to
SYMBOL_REFs for the stubbed-to and pointed-to entities. */ SYMBOL_REFs for the stubbed-to and pointed-to entities. */
static GTY ((param_is (struct machopic_indirection))) htab_t static GTY (()) hash_table<indirection_hasher> *machopic_indirections;
machopic_indirections;
/* Return a hash value for a SLOT in the indirections hash table. */ /* Return a hash value for a SLOT in the indirections hash table. */
static hashval_t hashval_t
machopic_indirection_hash (const void *slot) indirection_hasher::hash (machopic_indirection *p)
{ {
const machopic_indirection *p = (const machopic_indirection *) slot;
return htab_hash_string (p->ptr_name); return htab_hash_string (p->ptr_name);
} }
/* Returns true if the KEY is the same as that associated with /* Returns true if the KEY is the same as that associated with
SLOT. */ SLOT. */
static int bool
machopic_indirection_eq (const void *slot, const void *key) indirection_hasher::equal (machopic_indirection *s, const char *k)
{ {
return strcmp (((const machopic_indirection *) slot)->ptr_name, return strcmp (s->ptr_name, k) == 0;
(const char *) key) == 0;
} }
/* Return the name of the non-lazy pointer (if STUB_P is false) or /* Return the name of the non-lazy pointer (if STUB_P is false) or
@ -498,7 +502,6 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
const char *name = XSTR (sym_ref, 0); const char *name = XSTR (sym_ref, 0);
size_t namelen = strlen (name); size_t namelen = strlen (name);
machopic_indirection *p; machopic_indirection *p;
void ** slot;
bool needs_quotes; bool needs_quotes;
const char *suffix; const char *suffix;
const char *prefix = user_label_prefix; const char *prefix = user_label_prefix;
@ -548,16 +551,15 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote); sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
if (!machopic_indirections) if (!machopic_indirections)
machopic_indirections = htab_create_ggc (37, machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);
machopic_indirection_hash,
machopic_indirection_eq,
/*htab_del=*/NULL);
slot = htab_find_slot_with_hash (machopic_indirections, buffer, machopic_indirection **slot
htab_hash_string (buffer), INSERT); = machopic_indirections->find_slot_with_hash (buffer,
htab_hash_string (buffer),
INSERT);
if (*slot) if (*slot)
{ {
p = (machopic_indirection *) *slot; p = *slot;
} }
else else
{ {
@ -589,11 +591,8 @@ machopic_mcount_stub_name (void)
void void
machopic_validate_stub_or_non_lazy_ptr (const char *name) machopic_validate_stub_or_non_lazy_ptr (const char *name)
{ {
machopic_indirection *p; machopic_indirection *p
= machopic_indirections->find_with_hash (name, htab_hash_string (name));
p = ((machopic_indirection *)
(htab_find_with_hash (machopic_indirections, name,
htab_hash_string (name))));
if (p && ! p->used) if (p && ! p->used)
{ {
const char *real_name; const char *real_name;
@ -1062,11 +1061,10 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
DATA is the FILE* for assembly output. Called from DATA is the FILE* for assembly output. Called from
htab_traverse. */ htab_traverse. */
static int int
machopic_output_indirection (void **slot, void *data) machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
{ {
machopic_indirection *p = *((machopic_indirection **) slot); machopic_indirection *p = *slot;
FILE *asm_out_file = (FILE *) data;
rtx symbol; rtx symbol;
const char *sym_name; const char *sym_name;
const char *ptr_name; const char *ptr_name;
@ -1180,9 +1178,8 @@ void
machopic_finish (FILE *asm_out_file) machopic_finish (FILE *asm_out_file)
{ {
if (machopic_indirections) if (machopic_indirections)
htab_traverse_noresize (machopic_indirections, machopic_indirections
machopic_output_indirection, ->traverse_noresize<FILE *, machopic_output_indirection> (asm_out_file);
asm_out_file);
} }
int int
@ -3254,17 +3251,20 @@ static enum built_in_function darwin_builtin_cfstring;
/* Store all constructed constant CFStrings in a hash table so that /* Store all constructed constant CFStrings in a hash table so that
they get uniqued properly. */ they get uniqued properly. */
typedef struct GTY (()) cfstring_descriptor { typedef struct GTY ((for_user)) cfstring_descriptor {
/* The string literal. */ /* The string literal. */
tree literal; tree literal;
/* The resulting constant CFString. */ /* The resulting constant CFString. */
tree constructor; tree constructor;
} cfstring_descriptor; } cfstring_descriptor;
static GTY ((param_is (struct cfstring_descriptor))) htab_t cfstring_htab; struct cfstring_hasher : ggc_hasher<cfstring_descriptor *>
{
static hashval_t hash (cfstring_descriptor *);
static bool equal (cfstring_descriptor *, cfstring_descriptor *);
};
static hashval_t cfstring_hash (const void *); static GTY (()) hash_table<cfstring_hasher> *cfstring_htab;
static int cfstring_eq (const void *, const void *);
static tree static tree
add_builtin_field_decl (tree type, const char *name, tree **chain) add_builtin_field_decl (tree type, const char *name, tree **chain)
@ -3347,7 +3347,7 @@ darwin_init_cfstring_builtins (unsigned builtin_cfstring)
rest_of_decl_compilation (cfstring_class_reference, 0, 0); rest_of_decl_compilation (cfstring_class_reference, 0, 0);
/* Initialize the hash table used to hold the constant CFString objects. */ /* Initialize the hash table used to hold the constant CFString objects. */
cfstring_htab = htab_create_ggc (31, cfstring_hash, cfstring_eq, NULL); cfstring_htab = hash_table<cfstring_hasher>::create_ggc (31);
return cfstring_type_node; return cfstring_type_node;
} }
@ -3421,10 +3421,10 @@ darwin_libc_has_function (enum function_class fn_class)
return true; return true;
} }
static hashval_t hashval_t
cfstring_hash (const void *ptr) cfstring_hasher::hash (cfstring_descriptor *ptr)
{ {
tree str = ((const struct cfstring_descriptor *)ptr)->literal; tree str = ptr->literal;
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str); const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
int i, len = TREE_STRING_LENGTH (str); int i, len = TREE_STRING_LENGTH (str);
hashval_t h = len; hashval_t h = len;
@ -3435,11 +3435,11 @@ cfstring_hash (const void *ptr)
return h; return h;
} }
static int bool
cfstring_eq (const void *ptr1, const void *ptr2) cfstring_hasher::equal (cfstring_descriptor *ptr1, cfstring_descriptor *ptr2)
{ {
tree str1 = ((const struct cfstring_descriptor *)ptr1)->literal; tree str1 = ptr1->literal;
tree str2 = ((const struct cfstring_descriptor *)ptr2)->literal; tree str2 = ptr2->literal;
int len1 = TREE_STRING_LENGTH (str1); int len1 = TREE_STRING_LENGTH (str1);
return (len1 == TREE_STRING_LENGTH (str2) return (len1 == TREE_STRING_LENGTH (str2)
@ -3451,7 +3451,6 @@ tree
darwin_build_constant_cfstring (tree str) darwin_build_constant_cfstring (tree str)
{ {
struct cfstring_descriptor *desc, key; struct cfstring_descriptor *desc, key;
void **loc;
tree addr; tree addr;
if (!str) if (!str)
@ -3473,8 +3472,8 @@ darwin_build_constant_cfstring (tree str)
/* Perhaps we already constructed a constant CFString just like this one? */ /* Perhaps we already constructed a constant CFString just like this one? */
key.literal = str; key.literal = str;
loc = htab_find_slot (cfstring_htab, &key, INSERT); cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
desc = (struct cfstring_descriptor *) *loc; desc = *loc;
if (!desc) if (!desc)
{ {
@ -3550,7 +3549,6 @@ bool
darwin_cfstring_p (tree str) darwin_cfstring_p (tree str)
{ {
struct cfstring_descriptor key; struct cfstring_descriptor key;
void **loc;
if (!str) if (!str)
return false; return false;
@ -3564,7 +3562,7 @@ darwin_cfstring_p (tree str)
return false; return false;
key.literal = str; key.literal = str;
loc = htab_find_slot (cfstring_htab, &key, NO_INSERT); cfstring_descriptor **loc = cfstring_htab->find_slot (&key, NO_INSERT);
if (loc) if (loc)
return true; return true;
@ -3576,10 +3574,9 @@ void
darwin_enter_string_into_cfstring_table (tree str) darwin_enter_string_into_cfstring_table (tree str)
{ {
struct cfstring_descriptor key; struct cfstring_descriptor key;
void **loc;
key.literal = str; key.literal = str;
loc = htab_find_slot (cfstring_htab, &key, INSERT); cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
if (!*loc) if (!*loc)
{ {

View File

@ -3035,66 +3035,41 @@ m32c_insert_attributes (tree node ATTRIBUTE_UNUSED,
} }
struct GTY(()) pragma_entry { struct pragma_traits : default_hashmap_traits
const char *varname; {
unsigned address; static hashval_t hash (const char *str) { return htab_hash_string (str); }
static bool
equal_keys (const char *a, const char *b)
{
return !strcmp (a, b);
}
}; };
typedef struct pragma_entry pragma_entry;
/* Hash table of pragma info. */ /* Hash table of pragma info. */
static GTY((param_is (pragma_entry))) htab_t pragma_htab; static GTY(()) hash_map<const char *, unsigned, pragma_traits> *pragma_htab;
static int
pragma_entry_eq (const void *p1, const void *p2)
{
const pragma_entry *old = (const pragma_entry *) p1;
const char *new_name = (const char *) p2;
return strcmp (old->varname, new_name) == 0;
}
static hashval_t
pragma_entry_hash (const void *p)
{
const pragma_entry *old = (const pragma_entry *) p;
return htab_hash_string (old->varname);
}
void void
m32c_note_pragma_address (const char *varname, unsigned address) m32c_note_pragma_address (const char *varname, unsigned address)
{ {
pragma_entry **slot;
if (!pragma_htab) if (!pragma_htab)
pragma_htab = htab_create_ggc (31, pragma_entry_hash, pragma_htab
pragma_entry_eq, NULL); = hash_map<const char *, unsigned, pragma_traits>::create_ggc (31);
slot = (pragma_entry **) const char *name = ggc_strdup (varname);
htab_find_slot_with_hash (pragma_htab, varname, unsigned int *slot = &pragma_htab->get_or_insert (name);
htab_hash_string (varname), INSERT); *slot = address;
if (!*slot)
{
*slot = ggc_alloc<pragma_entry> ();
(*slot)->varname = ggc_strdup (varname);
}
(*slot)->address = address;
} }
static bool static bool
m32c_get_pragma_address (const char *varname, unsigned *address) m32c_get_pragma_address (const char *varname, unsigned *address)
{ {
pragma_entry **slot;
if (!pragma_htab) if (!pragma_htab)
return false; return false;
slot = (pragma_entry **) unsigned int *slot = pragma_htab->get (varname);
htab_find_slot_with_hash (pragma_htab, varname, if (slot)
htab_hash_string (varname), NO_INSERT);
if (slot && *slot)
{ {
*address = (*slot)->address; *address = *slot;
return true; return true;
} }
return false; return false;

View File

@ -4061,69 +4061,53 @@ mep_can_inline_p (tree caller, tree callee)
struct GTY(()) pragma_entry { struct GTY(()) pragma_entry {
int used; int used;
int flag; int flag;
const char *funcname;
}; };
typedef struct pragma_entry pragma_entry;
struct pragma_traits : default_hashmap_traits
{
static hashval_t hash (const char *s) { return htab_hash_string (s); }
static bool
equal_keys (const char *a, const char *b)
{
return strcmp (a, b) == 0;
}
};
/* Hash table of farcall-tagged sections. */ /* Hash table of farcall-tagged sections. */
static GTY((param_is (pragma_entry))) htab_t pragma_htab; static GTY(()) hash_map<const char *, pragma_entry, pragma_traits> *
pragma_htab;
static int
pragma_entry_eq (const void *p1, const void *p2)
{
const pragma_entry *old = (const pragma_entry *) p1;
const char *new_name = (const char *) p2;
return strcmp (old->funcname, new_name) == 0;
}
static hashval_t
pragma_entry_hash (const void *p)
{
const pragma_entry *old = (const pragma_entry *) p;
return htab_hash_string (old->funcname);
}
static void static void
mep_note_pragma_flag (const char *funcname, int flag) mep_note_pragma_flag (const char *funcname, int flag)
{ {
pragma_entry **slot;
if (!pragma_htab) if (!pragma_htab)
pragma_htab = htab_create_ggc (31, pragma_entry_hash, pragma_htab
pragma_entry_eq, NULL); = hash_map<const char *, pragma_entry, pragma_traits>::create_ggc (31);
slot = (pragma_entry **) bool existed;
htab_find_slot_with_hash (pragma_htab, funcname, const char *name = ggc_strdup (funcname);
htab_hash_string (funcname), INSERT); pragma_entry *slot = &pragma_htab->get_or_insert (name, &existed);
if (!existed)
if (!*slot)
{ {
*slot = ggc_alloc<pragma_entry> (); slot->flag = 0;
(*slot)->flag = 0; slot->used = 0;
(*slot)->used = 0;
(*slot)->funcname = ggc_strdup (funcname);
} }
(*slot)->flag |= flag; slot->flag |= flag;
} }
static bool static bool
mep_lookup_pragma_flag (const char *funcname, int flag) mep_lookup_pragma_flag (const char *funcname, int flag)
{ {
pragma_entry **slot;
if (!pragma_htab) if (!pragma_htab)
return false; return false;
if (funcname[0] == '@' && funcname[2] == '.') if (funcname[0] == '@' && funcname[2] == '.')
funcname += 3; funcname += 3;
slot = (pragma_entry **) pragma_entry *slot = pragma_htab->get (funcname);
htab_find_slot_with_hash (pragma_htab, funcname, if (slot && (slot->flag & flag))
htab_hash_string (funcname), NO_INSERT);
if (slot && *slot && ((*slot)->flag & flag))
{ {
(*slot)->used |= flag; slot->used |= flag;
return true; return true;
} }
return false; return false;
@ -4153,14 +4137,13 @@ mep_note_pragma_disinterrupt (const char *funcname)
mep_note_pragma_flag (funcname, FUNC_DISINTERRUPT); mep_note_pragma_flag (funcname, FUNC_DISINTERRUPT);
} }
static int bool
note_unused_pragma_disinterrupt (void **slot, void *data ATTRIBUTE_UNUSED) note_unused_pragma_disinterrupt (const char *const &s, const pragma_entry &e,
void *)
{ {
const pragma_entry *d = (const pragma_entry *)(*slot); if ((e.flag & FUNC_DISINTERRUPT)
&& !(e.used & FUNC_DISINTERRUPT))
if ((d->flag & FUNC_DISINTERRUPT) warning (0, "\"#pragma disinterrupt %s\" not used", s);
&& !(d->used & FUNC_DISINTERRUPT))
warning (0, "\"#pragma disinterrupt %s\" not used", d->funcname);
return 1; return 1;
} }
@ -4168,7 +4151,7 @@ void
mep_file_cleanups (void) mep_file_cleanups (void)
{ {
if (pragma_htab) if (pragma_htab)
htab_traverse (pragma_htab, note_unused_pragma_disinterrupt, NULL); pragma_htab->traverse<void *, note_unused_pragma_disinterrupt> (NULL);
} }
/* These three functions provide a bridge between the pramgas that /* These three functions provide a bridge between the pramgas that

View File

@ -1202,28 +1202,20 @@ static int mips_register_move_cost (enum machine_mode, reg_class_t,
reg_class_t); reg_class_t);
static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree); static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree);
struct mips16_flip_traits : default_hashmap_traits
{
static hashval_t hash (const char *s) { return htab_hash_string (s); }
static bool
equal_keys (const char *a, const char *b)
{
return !strcmp (a, b);
}
};
/* This hash table keeps track of implicit "mips16" and "nomips16" attributes /* This hash table keeps track of implicit "mips16" and "nomips16" attributes
for -mflip_mips16. It maps decl names onto a boolean mode setting. */ for -mflip_mips16. It maps decl names onto a boolean mode setting. */
struct GTY (()) mflip_mips16_entry { static GTY (()) hash_map<const char *, bool, mips16_flip_traits> *
const char *name; mflip_mips16_htab;
bool mips16_p;
};
static GTY ((param_is (struct mflip_mips16_entry))) htab_t mflip_mips16_htab;
/* Hash table callbacks for mflip_mips16_htab. */
static hashval_t
mflip_mips16_htab_hash (const void *entry)
{
return htab_hash_string (((const struct mflip_mips16_entry *) entry)->name);
}
static int
mflip_mips16_htab_eq (const void *entry, const void *name)
{
return strcmp (((const struct mflip_mips16_entry *) entry)->name,
(const char *) name) == 0;
}
/* True if -mflip-mips16 should next add an attribute for the default MIPS16 /* True if -mflip-mips16 should next add an attribute for the default MIPS16
mode, false if it should next add an attribute for the opposite mode. */ mode, false if it should next add an attribute for the opposite mode. */
@ -1236,10 +1228,7 @@ static GTY(()) bool mips16_flipper;
static bool static bool
mflip_mips16_use_mips16_p (tree decl) mflip_mips16_use_mips16_p (tree decl)
{ {
struct mflip_mips16_entry *entry;
const char *name; const char *name;
hashval_t hash;
void **slot;
bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0; bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0;
/* Use the opposite of the command-line setting for anonymous decls. */ /* Use the opposite of the command-line setting for anonymous decls. */
@ -1247,22 +1236,19 @@ mflip_mips16_use_mips16_p (tree decl)
return !base_is_mips16; return !base_is_mips16;
if (!mflip_mips16_htab) if (!mflip_mips16_htab)
mflip_mips16_htab = htab_create_ggc (37, mflip_mips16_htab_hash, mflip_mips16_htab
mflip_mips16_htab_eq, NULL); = hash_map<const char *, bool, mips16_flip_traits>::create_ggc (37);
name = IDENTIFIER_POINTER (DECL_NAME (decl)); name = IDENTIFIER_POINTER (DECL_NAME (decl));
hash = htab_hash_string (name);
slot = htab_find_slot_with_hash (mflip_mips16_htab, name, hash, INSERT); bool existed;
entry = (struct mflip_mips16_entry *) *slot; bool *slot = &mflip_mips16_htab->get_or_insert (name, &existed);
if (!entry) if (!existed)
{ {
mips16_flipper = !mips16_flipper; mips16_flipper = !mips16_flipper;
entry = ggc_alloc<mflip_mips16_entry> (); *slot = mips16_flipper ? !base_is_mips16 : base_is_mips16;
entry->name = name;
entry->mips16_p = mips16_flipper ? !base_is_mips16 : base_is_mips16;
*slot = entry;
} }
return entry->mips16_p; return *slot;
} }
/* Predicates to test for presence of "near" and "far"/"long_call" /* Predicates to test for presence of "near" and "far"/"long_call"
@ -6391,34 +6377,29 @@ mips_load_call_address (enum mips_call_type type, rtx dest, rtx addr)
} }
} }
struct local_alias_traits : default_hashmap_traits
{
static hashval_t hash (rtx);
static bool equal_keys (rtx, rtx);
};
/* Each locally-defined hard-float MIPS16 function has a local symbol /* Each locally-defined hard-float MIPS16 function has a local symbol
associated with it. This hash table maps the function symbol (FUNC) associated with it. This hash table maps the function symbol (FUNC)
to the local symbol (LOCAL). */ to the local symbol (LOCAL). */
struct GTY(()) mips16_local_alias { static GTY (()) hash_map<rtx, rtx, local_alias_traits> *mips16_local_aliases;
rtx func;
rtx local;
};
static GTY ((param_is (struct mips16_local_alias))) htab_t mips16_local_aliases;
/* Hash table callbacks for mips16_local_aliases. */ /* Hash table callbacks for mips16_local_aliases. */
static hashval_t hashval_t
mips16_local_aliases_hash (const void *entry) local_alias_traits::hash (rtx func)
{ {
const struct mips16_local_alias *alias; return htab_hash_string (XSTR (func, 0));
alias = (const struct mips16_local_alias *) entry;
return htab_hash_string (XSTR (alias->func, 0));
} }
static int bool
mips16_local_aliases_eq (const void *entry1, const void *entry2) local_alias_traits::equal_keys (rtx func1, rtx func2)
{ {
const struct mips16_local_alias *alias1, *alias2; return rtx_equal_p (func1, func2);
alias1 = (const struct mips16_local_alias *) entry1;
alias2 = (const struct mips16_local_alias *) entry2;
return rtx_equal_p (alias1->func, alias2->func);
} }
/* FUNC is the symbol for a locally-defined hard-float MIPS16 function. /* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
@ -6427,21 +6408,17 @@ mips16_local_aliases_eq (const void *entry1, const void *entry2)
static rtx static rtx
mips16_local_alias (rtx func) mips16_local_alias (rtx func)
{ {
struct mips16_local_alias *alias, tmp_alias;
void **slot;
/* Create the hash table if this is the first call. */ /* Create the hash table if this is the first call. */
if (mips16_local_aliases == NULL) if (mips16_local_aliases == NULL)
mips16_local_aliases = htab_create_ggc (37, mips16_local_aliases_hash, mips16_local_aliases
mips16_local_aliases_eq, NULL); = hash_map<rtx, rtx, local_alias_traits>::create_ggc (37);
/* Look up the function symbol, creating a new entry if need be. */ /* Look up the function symbol, creating a new entry if need be. */
tmp_alias.func = func; bool existed;
slot = htab_find_slot (mips16_local_aliases, &tmp_alias, INSERT); rtx *slot = &mips16_local_aliases->get_or_insert (func, &existed);
gcc_assert (slot != NULL); gcc_assert (slot != NULL);
alias = (struct mips16_local_alias *) *slot; if (!existed)
if (alias == NULL)
{ {
const char *func_name, *local_name; const char *func_name, *local_name;
rtx local; rtx local;
@ -6455,12 +6432,9 @@ mips16_local_alias (rtx func)
SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL; SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL;
/* Create a new structure to represent the mapping. */ /* Create a new structure to represent the mapping. */
alias = ggc_alloc<struct mips16_local_alias> (); *slot = local;
alias->func = func;
alias->local = local;
*slot = alias;
} }
return alias->local; return *slot;
} }
/* A chained list of functions for which mips16_build_call_stub has already /* A chained list of functions for which mips16_build_call_stub has already

View File

@ -1174,7 +1174,7 @@ rtl_opt_pass *make_pass_analyze_swaps (gcc::context*);
/* Hash table stuff for keeping track of TOC entries. */ /* Hash table stuff for keeping track of TOC entries. */
struct GTY(()) toc_hash_struct struct GTY((for_user)) toc_hash_struct
{ {
/* `key' will satisfy CONSTANT_P; in fact, it will satisfy /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */ ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
@ -1183,18 +1183,30 @@ struct GTY(()) toc_hash_struct
int labelno; int labelno;
}; };
static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table; struct toc_hasher : ggc_hasher<toc_hash_struct *>
{
static hashval_t hash (toc_hash_struct *);
static bool equal (toc_hash_struct *, toc_hash_struct *);
};
static GTY (()) hash_table<toc_hasher> *toc_hash_table;
/* Hash table to keep track of the argument types for builtin functions. */ /* Hash table to keep track of the argument types for builtin functions. */
struct GTY(()) builtin_hash_struct struct GTY((for_user)) builtin_hash_struct
{ {
tree type; tree type;
enum machine_mode mode[4]; /* return value + 3 arguments. */ enum machine_mode mode[4]; /* return value + 3 arguments. */
unsigned char uns_p[4]; /* and whether the types are unsigned. */ unsigned char uns_p[4]; /* and whether the types are unsigned. */
}; };
static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table; struct builtin_hasher : ggc_hasher<builtin_hash_struct *>
{
static hashval_t hash (builtin_hash_struct *);
static bool equal (builtin_hash_struct *, builtin_hash_struct *);
};
static GTY (()) hash_table<builtin_hasher> *builtin_hash_table;
/* Default register names. */ /* Default register names. */
@ -15113,13 +15125,11 @@ htm_init_builtins (void)
/* Hash function for builtin functions with up to 3 arguments and a return /* Hash function for builtin functions with up to 3 arguments and a return
type. */ type. */
static unsigned hashval_t
builtin_hash_function (const void *hash_entry) builtin_hasher::hash (builtin_hash_struct *bh)
{ {
unsigned ret = 0; unsigned ret = 0;
int i; int i;
const struct builtin_hash_struct *bh =
(const struct builtin_hash_struct *) hash_entry;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
@ -15131,12 +15141,9 @@ builtin_hash_function (const void *hash_entry)
} }
/* Compare builtin hash entries H1 and H2 for equivalence. */ /* Compare builtin hash entries H1 and H2 for equivalence. */
static int bool
builtin_hash_eq (const void *h1, const void *h2) builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
{ {
const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
return ((p1->mode[0] == p2->mode[0]) return ((p1->mode[0] == p2->mode[0])
&& (p1->mode[1] == p2->mode[1]) && (p1->mode[1] == p2->mode[1])
&& (p1->mode[2] == p2->mode[2]) && (p1->mode[2] == p2->mode[2])
@ -15157,7 +15164,6 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
{ {
struct builtin_hash_struct h; struct builtin_hash_struct h;
struct builtin_hash_struct *h2; struct builtin_hash_struct *h2;
void **found;
int num_args = 3; int num_args = 3;
int i; int i;
tree ret_type = NULL_TREE; tree ret_type = NULL_TREE;
@ -15165,8 +15171,7 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
/* Create builtin_hash_table. */ /* Create builtin_hash_table. */
if (builtin_hash_table == NULL) if (builtin_hash_table == NULL)
builtin_hash_table = htab_create_ggc (1500, builtin_hash_function, builtin_hash_table = hash_table<builtin_hasher>::create_ggc (1500);
builtin_hash_eq, NULL);
h.type = NULL_TREE; h.type = NULL_TREE;
h.mode[0] = mode_ret; h.mode[0] = mode_ret;
@ -15322,18 +15327,18 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
GET_MODE_NAME (m)); GET_MODE_NAME (m));
} }
found = htab_find_slot (builtin_hash_table, &h, INSERT); builtin_hash_struct **found = builtin_hash_table->find_slot (&h, INSERT);
if (*found == NULL) if (*found == NULL)
{ {
h2 = ggc_alloc<builtin_hash_struct> (); h2 = ggc_alloc<builtin_hash_struct> ();
*h2 = h; *h2 = h;
*found = (void *)h2; *found = h2;
h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1], h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
arg_type[2], NULL_TREE); arg_type[2], NULL_TREE);
} }
return ((struct builtin_hash_struct *)(*found))->type; return (*found)->type;
} }
static void static void
@ -25561,24 +25566,21 @@ rs6000_hash_constant (rtx k)
return result; return result;
} }
static unsigned hashval_t
toc_hash_function (const void *hash_entry) toc_hasher::hash (toc_hash_struct *thc)
{ {
const struct toc_hash_struct *thc =
(const struct toc_hash_struct *) hash_entry;
return rs6000_hash_constant (thc->key) ^ thc->key_mode; return rs6000_hash_constant (thc->key) ^ thc->key_mode;
} }
/* Compare H1 and H2 for equivalence. */ /* Compare H1 and H2 for equivalence. */
static int bool
toc_hash_eq (const void *h1, const void *h2) toc_hasher::equal (toc_hash_struct *h1, toc_hash_struct *h2)
{ {
rtx r1 = ((const struct toc_hash_struct *) h1)->key; rtx r1 = h1->key;
rtx r2 = ((const struct toc_hash_struct *) h2)->key; rtx r2 = h2->key;
if (((const struct toc_hash_struct *) h1)->key_mode if (h1->key_mode != h2->key_mode)
!= ((const struct toc_hash_struct *) h2)->key_mode)
return 0; return 0;
return rtx_equal_p (r1, r2); return rtx_equal_p (r1, r2);
@ -25665,20 +25667,18 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
if (TARGET_TOC && GET_CODE (x) != LABEL_REF) if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
{ {
struct toc_hash_struct *h; struct toc_hash_struct *h;
void * * found;
/* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
time because GGC is not initialized at that point. */ time because GGC is not initialized at that point. */
if (toc_hash_table == NULL) if (toc_hash_table == NULL)
toc_hash_table = htab_create_ggc (1021, toc_hash_function, toc_hash_table = hash_table<toc_hasher>::create_ggc (1021);
toc_hash_eq, NULL);
h = ggc_alloc<toc_hash_struct> (); h = ggc_alloc<toc_hash_struct> ();
h->key = x; h->key = x;
h->key_mode = mode; h->key_mode = mode;
h->labelno = labelno; h->labelno = labelno;
found = htab_find_slot (toc_hash_table, h, INSERT); toc_hash_struct **found = toc_hash_table->find_slot (h, INSERT);
if (*found == NULL) if (*found == NULL)
*found = h; *found = h;
else /* This is indeed a duplicate. else /* This is indeed a duplicate.
@ -25688,8 +25688,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
fprintf (file, "%d,", labelno); fprintf (file, "%d,", labelno);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) fprintf (file, "%d\n", ((*found)->labelno));
found)->labelno));
#ifdef HAVE_AS_TLS #ifdef HAVE_AS_TLS
if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF
@ -25700,8 +25699,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM"); ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
fprintf (file, "%d,", labelno); fprintf (file, "%d,", labelno);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM"); ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) fprintf (file, "%d\n", ((*found)->labelno));
found)->labelno));
} }
#endif #endif
return; return;

View File

@ -1,3 +1,9 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* cp-gimplify.c, cp-tree.h, decl.c, mangle.c, name-lookup.c,
pt.c, semantics.c, tree.c, typeck2.c: Use hash_table instead of
hashtab.
2014-10-10 Jason Merrill <jason@redhat.com> 2014-10-10 Jason Merrill <jason@redhat.com>
PR c++/62115 PR c++/62115

View File

@ -758,20 +758,18 @@ is_invisiref_parm (const_tree t)
/* Return true if the uid in both int tree maps are equal. */ /* Return true if the uid in both int tree maps are equal. */
int bool
cxx_int_tree_map_eq (const void *va, const void *vb) cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
{ {
const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
return (a->uid == b->uid); return (a->uid == b->uid);
} }
/* Hash a UID in a cxx_int_tree_map. */ /* Hash a UID in a cxx_int_tree_map. */
unsigned int unsigned int
cxx_int_tree_map_hash (const void *item) cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
{ {
return ((const struct cxx_int_tree_map *)item)->uid; return item->uid;
} }
/* A stable comparison routine for use with splay trees and DECLs. */ /* A stable comparison routine for use with splay trees and DECLs. */
@ -911,9 +909,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
{ {
struct cxx_int_tree_map *h, in; struct cxx_int_tree_map *h, in;
in.uid = DECL_UID (stmt); in.uid = DECL_UID (stmt);
h = (struct cxx_int_tree_map *) h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
htab_find_with_hash (cp_function_chain->extern_decl_map,
&in, in.uid);
if (h) if (h)
{ {
*stmt_p = h->to; *stmt_p = h->to;

View File

@ -1133,13 +1133,24 @@ struct GTY(()) saved_scope {
extern GTY(()) struct saved_scope *scope_chain; extern GTY(()) struct saved_scope *scope_chain;
struct GTY(()) cxx_int_tree_map { struct GTY((for_user)) cxx_int_tree_map {
unsigned int uid; unsigned int uid;
tree to; tree to;
}; };
extern unsigned int cxx_int_tree_map_hash (const void *); struct cxx_int_tree_map_hasher : ggc_hasher<cxx_int_tree_map *>
extern int cxx_int_tree_map_eq (const void *, const void *); {
static hashval_t hash (cxx_int_tree_map *);
static bool equal (cxx_int_tree_map *, cxx_int_tree_map *);
};
struct named_label_entry;
struct named_label_hasher : ggc_hasher<named_label_entry *>
{
static hashval_t hash (named_label_entry *);
static bool equal (named_label_entry *, named_label_entry *);
};
/* Global state pertinent to the current function. */ /* Global state pertinent to the current function. */
@ -1165,13 +1176,13 @@ struct GTY(()) language_function {
/* True if this function can throw an exception. */ /* True if this function can throw an exception. */
BOOL_BITFIELD can_throw : 1; BOOL_BITFIELD can_throw : 1;
htab_t GTY((param_is(struct named_label_entry))) x_named_labels; hash_table<named_label_hasher> *x_named_labels;
cp_binding_level *bindings; cp_binding_level *bindings;
vec<tree, va_gc> *x_local_names; vec<tree, va_gc> *x_local_names;
/* Tracking possibly infinite loops. This is a vec<tree> only because /* Tracking possibly infinite loops. This is a vec<tree> only because
vec<bool> doesn't work with gtype. */ vec<bool> doesn't work with gtype. */
vec<tree, va_gc> *infinite_loops; vec<tree, va_gc> *infinite_loops;
htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map; hash_table<cxx_int_tree_map_hasher> *extern_decl_map;
}; };
/* The current C++-specific per-function global variables. */ /* The current C++-specific per-function global variables. */

View File

@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "tree-hasher.h"
#include "stringpool.h" #include "stringpool.h"
#include "stor-layout.h" #include "stor-layout.h"
#include "varasm.h" #include "varasm.h"
@ -88,8 +89,6 @@ static int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int, static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
int); int);
static void check_for_uninitialized_const_var (tree); static void check_for_uninitialized_const_var (tree);
static hashval_t typename_hash (const void *);
static int typename_compare (const void *, const void *);
static tree local_variable_p_walkfn (tree *, int *, void *); static tree local_variable_p_walkfn (tree *, int *, void *);
static tree record_builtin_java_type (const char *, int); static tree record_builtin_java_type (const char *, int);
static const char *tag_name (enum tag_types); static const char *tag_name (enum tag_types);
@ -210,7 +209,7 @@ struct GTY((chain_next ("%h.next"))) named_label_use_entry {
we can clear out their names' definitions at the end of the we can clear out their names' definitions at the end of the
function, and so we can check the validity of jumps to these labels. */ function, and so we can check the validity of jumps to these labels. */
struct GTY(()) named_label_entry { struct GTY((for_user)) named_label_entry {
/* The decl itself. */ /* The decl itself. */
tree label_decl; tree label_decl;
@ -394,11 +393,10 @@ pop_label (tree label, tree old_value)
go out of scope. BLOCK is the top-level block for the go out of scope. BLOCK is the top-level block for the
function. */ function. */
static int int
pop_labels_1 (void **slot, void *data) pop_labels_1 (named_label_entry **slot, tree block)
{ {
struct named_label_entry *ent = (struct named_label_entry *) *slot; struct named_label_entry *ent = *slot;
tree block = (tree) data;
pop_label (ent->label_decl, NULL_TREE); pop_label (ent->label_decl, NULL_TREE);
@ -407,7 +405,7 @@ pop_labels_1 (void **slot, void *data)
DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block); DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
BLOCK_VARS (block) = ent->label_decl; BLOCK_VARS (block) = ent->label_decl;
htab_clear_slot (named_labels, slot); named_labels->clear_slot (slot);
return 1; return 1;
} }
@ -417,7 +415,7 @@ pop_labels (tree block)
{ {
if (named_labels) if (named_labels)
{ {
htab_traverse (named_labels, pop_labels_1, block); named_labels->traverse<tree, pop_labels_1> (block);
named_labels = NULL; named_labels = NULL;
} }
} }
@ -428,13 +426,12 @@ static void
pop_local_label (tree label, tree old_value) pop_local_label (tree label, tree old_value)
{ {
struct named_label_entry dummy; struct named_label_entry dummy;
void **slot;
pop_label (label, old_value); pop_label (label, old_value);
dummy.label_decl = label; dummy.label_decl = label;
slot = htab_find_slot (named_labels, &dummy, NO_INSERT); named_label_entry **slot = named_labels->find_slot (&dummy, NO_INSERT);
htab_clear_slot (named_labels, slot); named_labels->clear_slot (slot);
} }
/* The following two routines are used to interface to Objective-C++. /* The following two routines are used to interface to Objective-C++.
@ -474,11 +471,10 @@ objc_mark_locals_volatile (void *enclosing_blk)
/* Update data for defined and undefined labels when leaving a scope. */ /* Update data for defined and undefined labels when leaving a scope. */
static int int
poplevel_named_label_1 (void **slot, void *data) poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
{ {
struct named_label_entry *ent = (struct named_label_entry *) *slot; named_label_entry *ent = *slot;
cp_binding_level *bl = (cp_binding_level *) data;
cp_binding_level *obl = bl->level_chain; cp_binding_level *obl = bl->level_chain;
if (ent->binding_level == bl) if (ent->binding_level == bl)
@ -585,8 +581,8 @@ poplevel (int keep, int reverse, int functionbody)
/* Any uses of undefined labels, and any defined labels, now operate /* Any uses of undefined labels, and any defined labels, now operate
under constraints of next binding contour. */ under constraints of next binding contour. */
if (cfun && !functionbody && named_labels) if (cfun && !functionbody && named_labels)
htab_traverse (named_labels, poplevel_named_label_1, named_labels->traverse<cp_binding_level *, poplevel_named_label_1>
current_binding_level); (current_binding_level);
/* Get the decls in the order they were written. /* Get the decls in the order they were written.
Usually current_binding_level->names is in reverse order. Usually current_binding_level->names is in reverse order.
@ -2717,19 +2713,16 @@ redeclaration_error_message (tree newdecl, tree olddecl)
/* Hash and equality functions for the named_label table. */ /* Hash and equality functions for the named_label table. */
static hashval_t hashval_t
named_label_entry_hash (const void *data) named_label_hasher::hash (named_label_entry *ent)
{ {
const struct named_label_entry *ent = (const struct named_label_entry *) data;
return DECL_UID (ent->label_decl); return DECL_UID (ent->label_decl);
} }
static int bool
named_label_entry_eq (const void *a, const void *b) named_label_hasher::equal (named_label_entry *a, named_label_entry *b)
{ {
const struct named_label_entry *ent_a = (const struct named_label_entry *) a; return a->label_decl == b->label_decl;
const struct named_label_entry *ent_b = (const struct named_label_entry *) b;
return ent_a->label_decl == ent_b->label_decl;
} }
/* Create a new label, named ID. */ /* Create a new label, named ID. */
@ -2738,7 +2731,6 @@ static tree
make_label_decl (tree id, int local_p) make_label_decl (tree id, int local_p)
{ {
struct named_label_entry *ent; struct named_label_entry *ent;
void **slot;
tree decl; tree decl;
decl = build_decl (input_location, LABEL_DECL, id, void_type_node); decl = build_decl (input_location, LABEL_DECL, id, void_type_node);
@ -2756,8 +2748,7 @@ make_label_decl (tree id, int local_p)
/* Create the label htab for the function on demand. */ /* Create the label htab for the function on demand. */
if (!named_labels) if (!named_labels)
named_labels = htab_create_ggc (13, named_label_entry_hash, named_labels = hash_table<named_label_hasher>::create_ggc (13);
named_label_entry_eq, NULL);
/* Record this label on the list of labels used in this function. /* Record this label on the list of labels used in this function.
We do this before calling make_label_decl so that we get the We do this before calling make_label_decl so that we get the
@ -2765,7 +2756,7 @@ make_label_decl (tree id, int local_p)
ent = ggc_cleared_alloc<named_label_entry> (); ent = ggc_cleared_alloc<named_label_entry> ();
ent->label_decl = decl; ent->label_decl = decl;
slot = htab_find_slot (named_labels, ent, INSERT); named_label_entry **slot = named_labels->find_slot (ent, INSERT);
gcc_assert (*slot == NULL); gcc_assert (*slot == NULL);
*slot = ent; *slot = ent;
@ -2979,7 +2970,7 @@ check_goto (tree decl)
return; return;
dummy.label_decl = decl; dummy.label_decl = decl;
ent = (struct named_label_entry *) htab_find (named_labels, &dummy); ent = named_labels->find (&dummy);
gcc_assert (ent != NULL); gcc_assert (ent != NULL);
/* If the label hasn't been defined yet, defer checking. */ /* If the label hasn't been defined yet, defer checking. */
@ -3089,7 +3080,7 @@ define_label_1 (location_t location, tree name)
decl = lookup_label (name); decl = lookup_label (name);
dummy.label_decl = decl; dummy.label_decl = decl;
ent = (struct named_label_entry *) htab_find (named_labels, &dummy); ent = named_labels->find (&dummy);
gcc_assert (ent != NULL); gcc_assert (ent != NULL);
/* After labels, make any new cleanups in the function go into their /* After labels, make any new cleanups in the function go into their
@ -3264,50 +3255,50 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
return r; return r;
} }
/* Hash a TYPENAME_TYPE. K is really of type `tree'. */ struct typename_info {
static hashval_t
typename_hash (const void* k)
{
hashval_t hash;
const_tree const t = (const_tree) k;
hash = (htab_hash_pointer (TYPE_CONTEXT (t))
^ htab_hash_pointer (TYPE_IDENTIFIER (t)));
return hash;
}
typedef struct typename_info {
tree scope; tree scope;
tree name; tree name;
tree template_id; tree template_id;
bool enum_p; bool enum_p;
bool class_p; bool class_p;
} typename_info; };
/* Compare two TYPENAME_TYPEs. K1 is really of type `tree', K2 is struct typename_hasher : ggc_hasher<tree>
really of type `typename_info*' */
static int
typename_compare (const void * k1, const void * k2)
{ {
const_tree const t1 = (const_tree) k1; typedef typename_info *compare_type;
const typename_info *const t2 = (const typename_info *) k2;
return (TYPE_IDENTIFIER (t1) == t2->name /* Hash a TYPENAME_TYPE. */
&& TYPE_CONTEXT (t1) == t2->scope
&& TYPENAME_TYPE_FULLNAME (t1) == t2->template_id static hashval_t
&& TYPENAME_IS_ENUM_P (t1) == t2->enum_p hash (tree t)
&& TYPENAME_IS_CLASS_P (t1) == t2->class_p); {
} hashval_t hash;
hash = (htab_hash_pointer (TYPE_CONTEXT (t))
^ htab_hash_pointer (TYPE_IDENTIFIER (t)));
return hash;
}
/* Compare two TYPENAME_TYPEs. */
static bool
equal (tree t1, const typename_info *t2)
{
return (TYPE_IDENTIFIER (t1) == t2->name
&& TYPE_CONTEXT (t1) == t2->scope
&& TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
&& TYPENAME_IS_ENUM_P (t1) == t2->enum_p
&& TYPENAME_IS_CLASS_P (t1) == t2->class_p);
}
};
/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is /* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
the type of `T', NAME is the IDENTIFIER_NODE for `t'. the type of `T', NAME is the IDENTIFIER_NODE for `t'.
Returns the new TYPENAME_TYPE. */ Returns the new TYPENAME_TYPE. */
static GTY ((param_is (union tree_node))) htab_t typename_htab; static GTY (()) hash_table<typename_hasher> *typename_htab;
static tree static tree
build_typename_type (tree context, tree name, tree fullname, build_typename_type (tree context, tree name, tree fullname,
@ -3316,12 +3307,11 @@ build_typename_type (tree context, tree name, tree fullname,
tree t; tree t;
tree d; tree d;
typename_info ti; typename_info ti;
void **e; tree *e;
hashval_t hash; hashval_t hash;
if (typename_htab == NULL) if (typename_htab == NULL)
typename_htab = htab_create_ggc (61, &typename_hash, typename_htab = hash_table<typename_hasher>::create_ggc (61);
&typename_compare, NULL);
ti.scope = FROB_CONTEXT (context); ti.scope = FROB_CONTEXT (context);
ti.name = name; ti.name = name;
@ -3334,9 +3324,9 @@ build_typename_type (tree context, tree name, tree fullname,
^ htab_hash_pointer (ti.name)); ^ htab_hash_pointer (ti.name));
/* See if we already have this type. */ /* See if we already have this type. */
e = htab_find_slot_with_hash (typename_htab, &ti, hash, INSERT); e = typename_htab->find_slot_with_hash (&ti, hash, INSERT);
if (*e) if (*e)
t = (tree) *e; t = *e;
else else
{ {
/* Build the TYPENAME_TYPE. */ /* Build the TYPENAME_TYPE. */

View File

@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "tree-hasher.h"
#include "stor-layout.h" #include "stor-layout.h"
#include "stringpool.h" #include "stringpool.h"
#include "tm_p.h" #include "tm_p.h"
@ -3690,26 +3691,32 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
return result; return result;
} }
struct conv_type_hasher : ggc_hasher<tree>
{
static hashval_t hash (tree);
static bool equal (tree, tree);
};
/* This hash table maps TYPEs to the IDENTIFIER for a conversion /* This hash table maps TYPEs to the IDENTIFIER for a conversion
operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the
TYPE. */ TYPE. */
static GTY ((param_is (union tree_node))) htab_t conv_type_names; static GTY (()) hash_table<conv_type_hasher> *conv_type_names;
/* Hash a node (VAL1) in the table. */ /* Hash a node (VAL1) in the table. */
static hashval_t hashval_t
hash_type (const void *val) conv_type_hasher::hash (tree val)
{ {
return (hashval_t) TYPE_UID (TREE_TYPE ((const_tree) val)); return (hashval_t) TYPE_UID (TREE_TYPE (val));
} }
/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */ /* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
static int bool
compare_type (const void *val1, const void *val2) conv_type_hasher::equal (tree val1, tree val2)
{ {
return TREE_TYPE ((const_tree) val1) == (const_tree) val2; return TREE_TYPE (val1) == val2;
} }
/* Return an identifier for the mangled unqualified name for a /* Return an identifier for the mangled unqualified name for a
@ -3719,25 +3726,25 @@ compare_type (const void *val1, const void *val2)
tree tree
mangle_conv_op_name_for_type (const tree type) mangle_conv_op_name_for_type (const tree type)
{ {
void **slot; tree *slot;
tree identifier; tree identifier;
if (type == error_mark_node) if (type == error_mark_node)
return error_mark_node; return error_mark_node;
if (conv_type_names == NULL) if (conv_type_names == NULL)
conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL); conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
slot = htab_find_slot_with_hash (conv_type_names, type, slot = conv_type_names->find_slot_with_hash (type,
(hashval_t) TYPE_UID (type), INSERT); (hashval_t) TYPE_UID (type),
identifier = (tree)*slot; INSERT);
identifier = *slot;
if (!identifier) if (!identifier)
{ {
char buffer[64]; char buffer[64];
/* Create a unique name corresponding to TYPE. */ /* Create a unique name corresponding to TYPE. */
sprintf (buffer, "operator %lu", sprintf (buffer, "operator %lu", conv_type_names->elements ());
(unsigned long) htab_elements (conv_type_names));
identifier = get_identifier (buffer); identifier = get_identifier (buffer);
*slot = identifier; *slot = identifier;

View File

@ -766,22 +766,19 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
middle end. */ middle end. */
{ {
struct cxx_int_tree_map *h; struct cxx_int_tree_map *h;
void **loc;
TREE_PUBLIC (x) = TREE_PUBLIC (t); TREE_PUBLIC (x) = TREE_PUBLIC (t);
if (cp_function_chain->extern_decl_map == NULL) if (cp_function_chain->extern_decl_map == NULL)
cp_function_chain->extern_decl_map cp_function_chain->extern_decl_map
= htab_create_ggc (20, cxx_int_tree_map_hash, = hash_table<cxx_int_tree_map_hasher>::create_ggc (20);
cxx_int_tree_map_eq, NULL);
h = ggc_alloc<cxx_int_tree_map> (); h = ggc_alloc<cxx_int_tree_map> ();
h->uid = DECL_UID (x); h->uid = DECL_UID (x);
h->to = t; h->to = t;
loc = htab_find_slot_with_hash cxx_int_tree_map **loc = cp_function_chain->extern_decl_map
(cp_function_chain->extern_decl_map, h, ->find_slot (h, INSERT);
h->uid, INSERT); *loc = h;
*(struct cxx_int_tree_map **) loc = h;
} }
} }
else if (TREE_CODE (t) == PARM_DECL) else if (TREE_CODE (t) == PARM_DECL)

View File

@ -80,18 +80,22 @@ static tree cur_stmt_expr;
/* True if we've recursed into fn_type_unification too many times. */ /* True if we've recursed into fn_type_unification too many times. */
static bool excessive_deduction_depth; static bool excessive_deduction_depth;
typedef struct GTY(()) spec_entry struct GTY((for_user)) spec_entry
{ {
tree tmpl; tree tmpl;
tree args; tree args;
tree spec; tree spec;
} spec_entry; };
static GTY ((param_is (spec_entry))) struct spec_hasher : ggc_hasher<spec_entry *>
htab_t decl_specializations; {
static hashval_t hash (spec_entry *);
static bool equal (spec_entry *, spec_entry *);
};
static GTY ((param_is (spec_entry))) static GTY (()) hash_table<spec_hasher> *decl_specializations;
htab_t type_specializations;
static GTY (()) hash_table<spec_hasher> *type_specializations;
/* Contains canonical template parameter types. The vector is indexed by /* Contains canonical template parameter types. The vector is indexed by
the TEMPLATE_TYPE_IDX of the template parameter. Each element is a the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
@ -153,7 +157,6 @@ static bool inline_needs_template_parms (tree, bool);
static void push_inline_template_parms_recursive (tree, int); static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree); static tree retrieve_local_specialization (tree);
static void register_local_specialization (tree, tree); static void register_local_specialization (tree, tree);
static hashval_t hash_specialization (const void *p);
static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t); static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
static int mark_template_parm (tree, void *); static int mark_template_parm (tree, void *);
static int template_parm_this_level_p (tree, void *); static int template_parm_this_level_p (tree, void *);
@ -931,18 +934,18 @@ maybe_process_partial_specialization (tree type)
new member specialization template. */ new member specialization template. */
spec_entry elt; spec_entry elt;
spec_entry *entry; spec_entry *entry;
void **slot;
elt.tmpl = most_general_template (tmpl); elt.tmpl = most_general_template (tmpl);
elt.args = CLASSTYPE_TI_ARGS (inst); elt.args = CLASSTYPE_TI_ARGS (inst);
elt.spec = inst; elt.spec = inst;
htab_remove_elt (type_specializations, &elt); type_specializations->remove_elt (&elt);
elt.tmpl = tmpl; elt.tmpl = tmpl;
elt.args = INNERMOST_TEMPLATE_ARGS (elt.args); elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
slot = htab_find_slot (type_specializations, &elt, INSERT); spec_entry **slot
= type_specializations->find_slot (&elt, INSERT);
entry = ggc_alloc<spec_entry> (); entry = ggc_alloc<spec_entry> ();
*entry = elt; *entry = elt;
*slot = entry; *slot = entry;
@ -1085,7 +1088,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
{ {
spec_entry *found; spec_entry *found;
spec_entry elt; spec_entry elt;
htab_t specializations; hash_table<spec_hasher> *specializations;
elt.tmpl = tmpl; elt.tmpl = tmpl;
elt.args = args; elt.args = args;
@ -1097,8 +1100,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
specializations = decl_specializations; specializations = decl_specializations;
if (hash == 0) if (hash == 0)
hash = hash_specialization (&elt); hash = spec_hasher::hash (&elt);
found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash); found = specializations->find_with_hash (&elt, hash);
if (found) if (found)
return found->spec; return found->spec;
} }
@ -1343,7 +1346,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
hashval_t hash) hashval_t hash)
{ {
tree fn; tree fn;
void **slot = NULL; spec_entry **slot = NULL;
spec_entry elt; spec_entry elt;
gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)) gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec))
@ -1376,10 +1379,10 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
elt.spec = spec; elt.spec = spec;
if (hash == 0) if (hash == 0)
hash = hash_specialization (&elt); hash = spec_hasher::hash (&elt);
slot = slot =
htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT); decl_specializations->find_slot_with_hash (&elt, hash, INSERT);
if (*slot) if (*slot)
fn = ((spec_entry *) *slot)->spec; fn = ((spec_entry *) *slot)->spec;
else else
@ -1500,11 +1503,9 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
int comparing_specializations; int comparing_specializations;
static int bool
eq_specializations (const void *p1, const void *p2) spec_hasher::equal (spec_entry *e1, spec_entry *e2)
{ {
const spec_entry *e1 = (const spec_entry *)p1;
const spec_entry *e2 = (const spec_entry *)p2;
int equal; int equal;
++comparing_specializations; ++comparing_specializations;
@ -1527,10 +1528,9 @@ hash_tmpl_and_args (tree tmpl, tree args)
/* Returns a hash for a spec_entry node based on the TMPL and ARGS members, /* Returns a hash for a spec_entry node based on the TMPL and ARGS members,
ignoring SPEC. */ ignoring SPEC. */
static hashval_t hashval_t
hash_specialization (const void *p) spec_hasher::hash (spec_entry *e)
{ {
const spec_entry *e = (const spec_entry *)p;
return hash_tmpl_and_args (e->tmpl, e->args); return hash_tmpl_and_args (e->tmpl, e->args);
} }
@ -1710,7 +1710,7 @@ reregister_specialization (tree spec, tree tinfo, tree new_spec)
elt.args = TI_ARGS (tinfo); elt.args = TI_ARGS (tinfo);
elt.spec = NULL_TREE; elt.spec = NULL_TREE;
entry = (spec_entry *) htab_find (decl_specializations, &elt); entry = decl_specializations->find (&elt);
if (entry != NULL) if (entry != NULL)
{ {
gcc_assert (entry->spec == spec || entry->spec == new_spec); gcc_assert (entry->spec == spec || entry->spec == new_spec);
@ -7418,7 +7418,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
{ {
tree templ = NULL_TREE, parmlist; tree templ = NULL_TREE, parmlist;
tree t; tree t;
void **slot; spec_entry **slot;
spec_entry *entry; spec_entry *entry;
spec_entry elt; spec_entry elt;
hashval_t hash; hashval_t hash;
@ -7684,9 +7684,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
/* If we already have this specialization, return it. */ /* If we already have this specialization, return it. */
elt.tmpl = gen_tmpl; elt.tmpl = gen_tmpl;
elt.args = arglist; elt.args = arglist;
hash = hash_specialization (&elt); hash = spec_hasher::hash (&elt);
entry = (spec_entry *) htab_find_with_hash (type_specializations, entry = type_specializations->find_with_hash (&elt, hash);
&elt, hash);
if (entry) if (entry)
return entry->spec; return entry->spec;
@ -7930,8 +7929,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
elt.spec = t; elt.spec = t;
slot = htab_find_slot_with_hash (type_specializations, slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
&elt, hash, INSERT);
entry = ggc_alloc<spec_entry> (); entry = ggc_alloc<spec_entry> ();
*entry = elt; *entry = elt;
*slot = entry; *slot = entry;
@ -8652,7 +8650,7 @@ tsubst_friend_function (tree decl, tree args)
elt.args = DECL_TI_ARGS (spec); elt.args = DECL_TI_ARGS (spec);
elt.spec = NULL_TREE; elt.spec = NULL_TREE;
htab_remove_elt (decl_specializations, &elt); decl_specializations->remove_elt (&elt);
DECL_TI_ARGS (spec) DECL_TI_ARGS (spec)
= add_outermost_template_args (new_args, = add_outermost_template_args (new_args,
@ -22316,14 +22314,8 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
void void
init_template_processing (void) init_template_processing (void)
{ {
decl_specializations = htab_create_ggc (37, decl_specializations = hash_table<spec_hasher>::create_ggc (37);
hash_specialization, type_specializations = hash_table<spec_hasher>::create_ggc (37);
eq_specializations,
ggc_free);
type_specializations = htab_create_ggc (37,
hash_specialization,
eq_specializations,
ggc_free);
} }
/* Print stats about the template hash tables for -fstats. */ /* Print stats about the template hash tables for -fstats. */
@ -22332,13 +22324,13 @@ void
print_template_statistics (void) print_template_statistics (void)
{ {
fprintf (stderr, "decl_specializations: size %ld, %ld elements, " fprintf (stderr, "decl_specializations: size %ld, %ld elements, "
"%f collisions\n", (long) htab_size (decl_specializations), "%f collisions\n", decl_specializations->size (),
(long) htab_elements (decl_specializations), decl_specializations->elements (),
htab_collisions (decl_specializations)); decl_specializations->collisions ());
fprintf (stderr, "type_specializations: size %ld, %ld elements, " fprintf (stderr, "type_specializations: size %ld, %ld elements, "
"%f collisions\n", (long) htab_size (type_specializations), "%f collisions\n", type_specializations->size (),
(long) htab_elements (type_specializations), type_specializations->elements (),
htab_collisions (type_specializations)); type_specializations->collisions ());
} }
#include "gt-cp-pt.h" #include "gt-cp-pt.h"

View File

@ -7579,35 +7579,38 @@ ensure_literal_type_for_constexpr_object (tree decl)
/* Representation of entries in the constexpr function definition table. */ /* Representation of entries in the constexpr function definition table. */
typedef struct GTY(()) constexpr_fundef { struct GTY((for_user)) constexpr_fundef {
tree decl; tree decl;
tree body; tree body;
} constexpr_fundef; };
struct constexpr_fundef_hasher : ggc_hasher<constexpr_fundef *>
{
static hashval_t hash (constexpr_fundef *);
static bool equal (constexpr_fundef *, constexpr_fundef *);
};
/* This table holds all constexpr function definitions seen in /* This table holds all constexpr function definitions seen in
the current translation unit. */ the current translation unit. */
static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table; static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
/* Utility function used for managing the constexpr function table. /* Utility function used for managing the constexpr function table.
Return true if the entries pointed to by P and Q are for the Return true if the entries pointed to by P and Q are for the
same constexpr function. */ same constexpr function. */
static inline int inline bool
constexpr_fundef_equal (const void *p, const void *q) constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
{ {
const constexpr_fundef *lhs = (const constexpr_fundef *) p;
const constexpr_fundef *rhs = (const constexpr_fundef *) q;
return lhs->decl == rhs->decl; return lhs->decl == rhs->decl;
} }
/* Utility function used for managing the constexpr function table. /* Utility function used for managing the constexpr function table.
Return a hash value for the entry pointed to by Q. */ Return a hash value for the entry pointed to by Q. */
static inline hashval_t inline hashval_t
constexpr_fundef_hash (const void *p) constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
{ {
const constexpr_fundef *fundef = (const constexpr_fundef *) p;
return DECL_UID (fundef->decl); return DECL_UID (fundef->decl);
} }
@ -7621,7 +7624,7 @@ retrieve_constexpr_fundef (tree fun)
return NULL; return NULL;
fundef.decl = fun; fundef.decl = fun;
return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef); return constexpr_fundef_table->find (&fundef);
} }
/* Check whether the parameter and return types of FUN are valid for a /* Check whether the parameter and return types of FUN are valid for a
@ -8236,14 +8239,12 @@ register_constexpr_fundef (tree fun, tree body)
/* Create the constexpr function table if necessary. */ /* Create the constexpr function table if necessary. */
if (constexpr_fundef_table == NULL) if (constexpr_fundef_table == NULL)
constexpr_fundef_table = htab_create_ggc (101, constexpr_fundef_table
constexpr_fundef_hash, = hash_table<constexpr_fundef_hasher>::create_ggc (101);
constexpr_fundef_equal,
ggc_free);
entry.decl = fun; entry.decl = fun;
entry.body = body; entry.body = body;
slot = (constexpr_fundef **) slot = constexpr_fundef_table->find_slot (&entry, INSERT);
htab_find_slot (constexpr_fundef_table, &entry, INSERT);
gcc_assert (*slot == NULL); gcc_assert (*slot == NULL);
*slot = ggc_alloc<constexpr_fundef> (); *slot = ggc_alloc<constexpr_fundef> ();
@ -8296,7 +8297,7 @@ explain_invalid_constexpr_fn (tree fun)
along with the bindings of parameters to their arguments, for along with the bindings of parameters to their arguments, for
the purpose of compile time evaluation. */ the purpose of compile time evaluation. */
typedef struct GTY(()) constexpr_call { struct GTY((for_user)) constexpr_call {
/* Description of the constexpr function definition. */ /* Description of the constexpr function definition. */
constexpr_fundef *fundef; constexpr_fundef *fundef;
/* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE /* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
@ -8314,39 +8315,42 @@ typedef struct GTY(()) constexpr_call {
/* The hash of this call; we remember it here to avoid having to /* The hash of this call; we remember it here to avoid having to
recalculate it when expanding the hash table. */ recalculate it when expanding the hash table. */
hashval_t hash; hashval_t hash;
} constexpr_call; };
struct constexpr_call_hasher : ggc_hasher<constexpr_call *>
{
static hashval_t hash (constexpr_call *);
static bool equal (constexpr_call *, constexpr_call *);
};
/* A table of all constexpr calls that have been evaluated by the /* A table of all constexpr calls that have been evaluated by the
compiler in this translation unit. */ compiler in this translation unit. */
static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table; static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
static tree cxx_eval_constant_expression (const constexpr_call *, tree, static tree cxx_eval_constant_expression (const constexpr_call *, tree,
bool, bool, bool *, bool *); bool, bool, bool *, bool *);
/* Compute a hash value for a constexpr call representation. */ /* Compute a hash value for a constexpr call representation. */
static hashval_t inline hashval_t
constexpr_call_hash (const void *p) constexpr_call_hasher::hash (constexpr_call *info)
{ {
const constexpr_call *info = (const constexpr_call *) p;
return info->hash; return info->hash;
} }
/* Return 1 if the objects pointed to by P and Q represent calls /* Return true if the objects pointed to by P and Q represent calls
to the same constexpr function with the same arguments. to the same constexpr function with the same arguments.
Otherwise, return 0. */ Otherwise, return false. */
static int bool
constexpr_call_equal (const void *p, const void *q) constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
{ {
const constexpr_call *lhs = (const constexpr_call *) p;
const constexpr_call *rhs = (const constexpr_call *) q;
tree lhs_bindings; tree lhs_bindings;
tree rhs_bindings; tree rhs_bindings;
if (lhs == rhs) if (lhs == rhs)
return 1; return 1;
if (!constexpr_fundef_equal (lhs->fundef, rhs->fundef)) if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
return 0; return 0;
lhs_bindings = lhs->bindings; lhs_bindings = lhs->bindings;
rhs_bindings = rhs->bindings; rhs_bindings = rhs->bindings;
@ -8369,10 +8373,7 @@ static void
maybe_initialize_constexpr_call_table (void) maybe_initialize_constexpr_call_table (void)
{ {
if (constexpr_call_table == NULL) if (constexpr_call_table == NULL)
constexpr_call_table = htab_create_ggc (101, constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
constexpr_call_hash,
constexpr_call_equal,
ggc_free);
} }
/* Return true if T designates the implied `this' parameter. */ /* Return true if T designates the implied `this' parameter. */
@ -8681,12 +8682,11 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t,
new_call.hash new_call.hash
= iterative_hash_template_arg (new_call.bindings, = iterative_hash_template_arg (new_call.bindings,
constexpr_fundef_hash (new_call.fundef)); constexpr_fundef_hasher::hash (new_call.fundef));
/* If we have seen this call before, we are done. */ /* If we have seen this call before, we are done. */
maybe_initialize_constexpr_call_table (); maybe_initialize_constexpr_call_table ();
slot = (constexpr_call **) slot = constexpr_call_table->find_slot (&new_call, INSERT);
htab_find_slot (constexpr_call_table, &new_call, INSERT);
entry = *slot; entry = *slot;
if (entry == NULL) if (entry == NULL)
{ {

View File

@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "tree-hasher.h"
#include "stor-layout.h" #include "stor-layout.h"
#include "print-tree.h" #include "print-tree.h"
#include "tree-iterator.h" #include "tree-iterator.h"
@ -40,9 +41,7 @@ along with GCC; see the file COPYING3. If not see
static tree bot_manip (tree *, int *, void *); static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *); static tree bot_replace (tree *, int *, void *);
static int list_hash_eq (const void *, const void *);
static hashval_t list_hash_pieces (tree, tree, tree); static hashval_t list_hash_pieces (tree, tree, tree);
static hashval_t list_hash (const void *);
static tree build_target_expr (tree, tree, tsubst_flags_t); static tree build_target_expr (tree, tree, tsubst_flags_t);
static tree count_trees_r (tree *, int *, void *); static tree count_trees_r (tree *, int *, void *);
static tree verify_stmt_tree_r (tree *, int *, void *); static tree verify_stmt_tree_r (tree *, int *, void *);
@ -722,13 +721,26 @@ rvalue (tree expr)
} }
struct cplus_array_info
{
tree type;
tree domain;
};
struct cplus_array_hasher : ggc_hasher<tree>
{
typedef cplus_array_info *compare_type;
static hashval_t hash (tree t);
static bool equal (tree, cplus_array_info *);
};
/* Hash an ARRAY_TYPE. K is really of type `tree'. */ /* Hash an ARRAY_TYPE. K is really of type `tree'. */
static hashval_t hashval_t
cplus_array_hash (const void* k) cplus_array_hasher::hash (tree t)
{ {
hashval_t hash; hashval_t hash;
const_tree const t = (const_tree) k;
hash = TYPE_UID (TREE_TYPE (t)); hash = TYPE_UID (TREE_TYPE (t));
if (TYPE_DOMAIN (t)) if (TYPE_DOMAIN (t))
@ -736,26 +748,18 @@ cplus_array_hash (const void* k)
return hash; return hash;
} }
typedef struct cplus_array_info {
tree type;
tree domain;
} cplus_array_info;
/* Compare two ARRAY_TYPEs. K1 is really of type `tree', K2 is really /* Compare two ARRAY_TYPEs. K1 is really of type `tree', K2 is really
of type `cplus_array_info*'. */ of type `cplus_array_info*'. */
static int bool
cplus_array_compare (const void * k1, const void * k2) cplus_array_hasher::equal (tree t1, cplus_array_info *t2)
{ {
const_tree const t1 = (const_tree) k1;
const cplus_array_info *const t2 = (const cplus_array_info*) k2;
return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain); return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain);
} }
/* Hash table containing dependent array types, which are unsuitable for /* Hash table containing dependent array types, which are unsuitable for
the language-independent type hash table. */ the language-independent type hash table. */
static GTY ((param_is (union tree_node))) htab_t cplus_array_htab; static GTY (()) hash_table<cplus_array_hasher> *cplus_array_htab;
/* Build an ARRAY_TYPE without laying it out. */ /* Build an ARRAY_TYPE without laying it out. */
@ -813,13 +817,11 @@ build_cplus_array_type (tree elt_type, tree index_type)
{ {
/* Since type_hash_canon calls layout_type, we need to use our own /* Since type_hash_canon calls layout_type, we need to use our own
hash table. */ hash table. */
void **e;
cplus_array_info cai; cplus_array_info cai;
hashval_t hash; hashval_t hash;
if (cplus_array_htab == NULL) if (cplus_array_htab == NULL)
cplus_array_htab = htab_create_ggc (61, &cplus_array_hash, cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
&cplus_array_compare, NULL);
hash = TYPE_UID (elt_type); hash = TYPE_UID (elt_type);
if (index_type) if (index_type)
@ -827,7 +829,7 @@ build_cplus_array_type (tree elt_type, tree index_type)
cai.type = elt_type; cai.type = elt_type;
cai.domain = index_type; cai.domain = index_type;
e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT); tree *e = cplus_array_htab->find_slot_with_hash (&cai, hash, INSERT);
if (*e) if (*e)
/* We have found the type: we're done. */ /* We have found the type: we're done. */
return (tree) *e; return (tree) *e;
@ -1641,14 +1643,6 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
/* Hashing of lists so that we don't make duplicates. /* Hashing of lists so that we don't make duplicates.
The entry point is `list_hash_canon'. */ The entry point is `list_hash_canon'. */
/* Now here is the hash table. When recording a list, it is added
to the slot whose index is the hash code mod the table size.
Note that the hash table is used for several kinds of lists.
While all these live in the same table, they are completely independent,
and the hash code is computed differently for each of these. */
static GTY ((param_is (union tree_node))) htab_t list_hash_table;
struct list_proxy struct list_proxy
{ {
tree purpose; tree purpose;
@ -1656,15 +1650,28 @@ struct list_proxy
tree chain; tree chain;
}; };
struct list_hasher : ggc_hasher<tree>
{
typedef list_proxy *compare_type;
static hashval_t hash (tree);
static bool equal (tree, list_proxy *);
};
/* Now here is the hash table. When recording a list, it is added
to the slot whose index is the hash code mod the table size.
Note that the hash table is used for several kinds of lists.
While all these live in the same table, they are completely independent,
and the hash code is computed differently for each of these. */
static GTY (()) hash_table<list_hasher> *list_hash_table;
/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy /* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy
for a node we are thinking about adding). */ for a node we are thinking about adding). */
static int bool
list_hash_eq (const void* entry, const void* data) list_hasher::equal (tree t, list_proxy *proxy)
{ {
const_tree const t = (const_tree) entry;
const struct list_proxy *const proxy = (const struct list_proxy *) data;
return (TREE_VALUE (t) == proxy->value return (TREE_VALUE (t) == proxy->value
&& TREE_PURPOSE (t) == proxy->purpose && TREE_PURPOSE (t) == proxy->purpose
&& TREE_CHAIN (t) == proxy->chain); && TREE_CHAIN (t) == proxy->chain);
@ -1695,10 +1702,9 @@ list_hash_pieces (tree purpose, tree value, tree chain)
/* Hash an already existing TREE_LIST. */ /* Hash an already existing TREE_LIST. */
static hashval_t hashval_t
list_hash (const void* p) list_hasher::hash (tree t)
{ {
const_tree const t = (const_tree) p;
return list_hash_pieces (TREE_PURPOSE (t), return list_hash_pieces (TREE_PURPOSE (t),
TREE_VALUE (t), TREE_VALUE (t),
TREE_CHAIN (t)); TREE_CHAIN (t));
@ -1712,7 +1718,7 @@ tree
hash_tree_cons (tree purpose, tree value, tree chain) hash_tree_cons (tree purpose, tree value, tree chain)
{ {
int hashcode = 0; int hashcode = 0;
void **slot; tree *slot;
struct list_proxy proxy; struct list_proxy proxy;
/* Hash the list node. */ /* Hash the list node. */
@ -1723,8 +1729,7 @@ hash_tree_cons (tree purpose, tree value, tree chain)
proxy.value = value; proxy.value = value;
proxy.chain = chain; proxy.chain = chain;
/* See if it is already in the table. */ /* See if it is already in the table. */
slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode, slot = list_hash_table->find_slot_with_hash (&proxy, hashcode, INSERT);
INSERT);
/* If not, create a new node. */ /* If not, create a new node. */
if (!*slot) if (!*slot)
*slot = tree_cons (purpose, value, chain); *slot = tree_cons (purpose, value, chain);
@ -3670,7 +3675,7 @@ cp_save_expr (tree expr)
void void
init_tree (void) init_tree (void)
{ {
list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL); list_hash_table = hash_table<list_hasher>::create_ggc (61);
} }
/* Returns the kind of special function that DECL (a FUNCTION_DECL) /* Returns the kind of special function that DECL (a FUNCTION_DECL)

View File

@ -135,7 +135,7 @@ cxx_readonly_error (tree arg, enum lvalue_use errstring)
/* Structure that holds information about declarations whose type was /* Structure that holds information about declarations whose type was
incomplete and we could not check whether it was abstract or not. */ incomplete and we could not check whether it was abstract or not. */
struct GTY((chain_next ("%h.next"))) pending_abstract_type { struct GTY((chain_next ("%h.next"), for_user)) pending_abstract_type {
/* Declaration which we are checking for abstractness. It is either /* Declaration which we are checking for abstractness. It is either
a DECL node, or an IDENTIFIER_NODE if we do not have a full a DECL node, or an IDENTIFIER_NODE if we do not have a full
declaration available. */ declaration available. */
@ -155,15 +155,19 @@ struct GTY((chain_next ("%h.next"))) pending_abstract_type {
struct pending_abstract_type* next; struct pending_abstract_type* next;
}; };
struct abstract_type_hasher : ggc_hasher<pending_abstract_type *>
{
typedef tree compare_type;
static hashval_t hash (pending_abstract_type *);
static bool equal (pending_abstract_type *, tree);
};
/* Compute the hash value of the node VAL. This function is used by the /* Compute the hash value of the node VAL. This function is used by the
hash table abstract_pending_vars. */ hash table abstract_pending_vars. */
static hashval_t hashval_t
pat_calc_hash (const void* val) abstract_type_hasher::hash (pending_abstract_type *pat)
{ {
const struct pending_abstract_type *pat =
(const struct pending_abstract_type *) val;
return (hashval_t) TYPE_UID (pat->type); return (hashval_t) TYPE_UID (pat->type);
} }
@ -171,21 +175,16 @@ pat_calc_hash (const void* val)
/* Compare node VAL1 with the type VAL2. This function is used by the /* Compare node VAL1 with the type VAL2. This function is used by the
hash table abstract_pending_vars. */ hash table abstract_pending_vars. */
static int bool
pat_compare (const void* val1, const void* val2) abstract_type_hasher::equal (pending_abstract_type *pat1, tree type2)
{ {
const struct pending_abstract_type *const pat1 =
(const struct pending_abstract_type *) val1;
const_tree const type2 = (const_tree)val2;
return (pat1->type == type2); return (pat1->type == type2);
} }
/* Hash table that maintains pending_abstract_type nodes, for which we still /* Hash table that maintains pending_abstract_type nodes, for which we still
need to check for type abstractness. The key of the table is the type need to check for type abstractness. The key of the table is the type
of the declaration. */ of the declaration. */
static GTY ((param_is (struct pending_abstract_type))) static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
htab_t abstract_pending_vars = NULL;
static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t); static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
@ -197,7 +196,6 @@ static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubs
void void
complete_type_check_abstract (tree type) complete_type_check_abstract (tree type)
{ {
void **slot;
struct pending_abstract_type *pat; struct pending_abstract_type *pat;
location_t cur_loc = input_location; location_t cur_loc = input_location;
@ -207,11 +205,12 @@ complete_type_check_abstract (tree type)
return; return;
/* Retrieve the list of pending declarations for this type. */ /* Retrieve the list of pending declarations for this type. */
slot = htab_find_slot_with_hash (abstract_pending_vars, type, pending_abstract_type **slot
(hashval_t)TYPE_UID (type), NO_INSERT); = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
NO_INSERT);
if (!slot) if (!slot)
return; return;
pat = (struct pending_abstract_type*)*slot; pat = *slot;
gcc_assert (pat); gcc_assert (pat);
/* If the type is not abstract, do not do anything. */ /* If the type is not abstract, do not do anything. */
@ -244,7 +243,7 @@ complete_type_check_abstract (tree type)
} }
} }
htab_clear_slot (abstract_pending_vars, slot); abstract_pending_vars->clear_slot (slot);
input_location = cur_loc; input_location = cur_loc;
} }
@ -282,17 +281,17 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
name. */ name. */
if (!COMPLETE_TYPE_P (type) && (complain & tf_error)) if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
{ {
void **slot;
struct pending_abstract_type *pat; struct pending_abstract_type *pat;
gcc_assert (!decl || DECL_P (decl) || identifier_p (decl)); gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
if (!abstract_pending_vars) if (!abstract_pending_vars)
abstract_pending_vars = htab_create_ggc (31, &pat_calc_hash, abstract_pending_vars
&pat_compare, NULL); = hash_table<abstract_type_hasher>::create_ggc (31);
slot = htab_find_slot_with_hash (abstract_pending_vars, type, pending_abstract_type **slot
(hashval_t)TYPE_UID (type), INSERT); = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
INSERT);
pat = ggc_alloc<pending_abstract_type> (); pat = ggc_alloc<pending_abstract_type> ();
pat->type = type; pat->type = type;
@ -302,7 +301,7 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
? DECL_SOURCE_LOCATION (decl) ? DECL_SOURCE_LOCATION (decl)
: input_location); : input_location);
pat->next = (struct pending_abstract_type *) *slot; pat->next = *slot;
*slot = pat; *slot = pat;
return 0; return 0;

View File

@ -197,6 +197,12 @@ If @code{skip} is applied to a field, the type machinery will ignore it.
This is somewhat dangerous; the only safe use is in a union when one This is somewhat dangerous; the only safe use is in a union when one
field really isn't ever used. field really isn't ever used.
@findex for_user
Use this to mark types that need to be marked by user gc routines, but are not
refered to in a template argument. So if you have some user gc type T1 and a
non user gc type T2 you can give T2 the for_user option so that the marking
functions for T1 can call non mangled functions to mark T2.
@findex desc @findex desc
@findex tag @findex tag
@findex default @findex default

View File

@ -205,7 +205,7 @@ static GTY(()) section *debug_frame_section;
static GTY(()) vec<dw_fde_ref, va_gc> *fde_vec; static GTY(()) vec<dw_fde_ref, va_gc> *fde_vec;
struct GTY(()) indirect_string_node { struct GTY((for_user)) indirect_string_node {
const char *str; const char *str;
unsigned int refcount; unsigned int refcount;
enum dwarf_form form; enum dwarf_form form;
@ -213,7 +213,15 @@ struct GTY(()) indirect_string_node {
unsigned int index; unsigned int index;
}; };
static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash; struct indirect_string_hasher : ggc_hasher<indirect_string_node *>
{
typedef const char *compare_type;
static hashval_t hash (indirect_string_node *);
static bool equal (indirect_string_node *, const char *);
};
static GTY (()) hash_table<indirect_string_hasher> *debug_str_hash;
/* With split_debug_info, both the comp_dir and dwo_name go in the /* With split_debug_info, both the comp_dir and dwo_name go in the
main object file, rather than the dwo, similar to the force_direct main object file, rather than the dwo, similar to the force_direct
@ -234,8 +242,7 @@ static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
main object file. This limits the complexity to just the places main object file. This limits the complexity to just the places
that need it. */ that need it. */
static GTY ((param_is (struct indirect_string_node))) static GTY (()) hash_table<indirect_string_hasher> *skeleton_debug_str_hash;
htab_t skeleton_debug_str_hash;
static GTY(()) int dw2_string_counter; static GTY(()) int dw2_string_counter;
@ -1235,7 +1242,7 @@ dwarf2out_switch_text_section (void)
for emitting location expressions. */ for emitting location expressions. */
/* Data about a single source file. */ /* Data about a single source file. */
struct GTY(()) dwarf_file_data { struct GTY((for_user)) dwarf_file_data {
const char * filename; const char * filename;
int emitted_number; int emitted_number;
}; };
@ -1258,7 +1265,7 @@ enum ate_kind {
ate_kind_label ate_kind_label
}; };
typedef struct GTY(()) addr_table_entry_struct { typedef struct GTY((for_user)) addr_table_entry_struct {
enum ate_kind kind; enum ate_kind kind;
unsigned int refcount; unsigned int refcount;
unsigned int index; unsigned int index;
@ -2417,7 +2424,6 @@ build_cfa_aligned_loc (dw_cfa_location *cfa,
/* And now, the support for symbolic debugging information. */ /* And now, the support for symbolic debugging information. */
/* .debug_str support. */ /* .debug_str support. */
static int output_indirect_string (void **, void *);
static void dwarf2out_init (const char *); static void dwarf2out_init (const char *);
static void dwarf2out_finish (const char *); static void dwarf2out_finish (const char *);
@ -2589,7 +2595,7 @@ dw_attr_node;
The children of each node form a circular list linked by The children of each node form a circular list linked by
die_sib. die_child points to the node *before* the "first" child node. */ die_sib. die_child points to the node *before* the "first" child node. */
typedef struct GTY((chain_circular ("%h.die_sib"))) die_struct { typedef struct GTY((chain_circular ("%h.die_sib"), for_user)) die_struct {
union die_symbol_or_type_node union die_symbol_or_type_node
{ {
const char * GTY ((tag ("0"))) die_symbol; const char * GTY ((tag ("0"))) die_symbol;
@ -2775,16 +2781,37 @@ static GTY(()) limbo_die_node *limbo_die_list;
DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */ DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */
static GTY(()) limbo_die_node *deferred_asm_name; static GTY(()) limbo_die_node *deferred_asm_name;
/* Filenames referenced by this compilation unit. */ struct dwarf_file_hasher : ggc_hasher<dwarf_file_data *>
static GTY((param_is (struct dwarf_file_data))) htab_t file_table; {
typedef const char *compare_type;
static hashval_t hash (dwarf_file_data *);
static bool equal (dwarf_file_data *, const char *);
};
/* Filenames referenced by this compilation unit. */
static GTY(()) hash_table<dwarf_file_hasher> *file_table;
struct decl_die_hasher : ggc_hasher<die_node *>
{
typedef tree compare_type;
static hashval_t hash (die_node *);
static bool equal (die_node *, tree);
};
/* A hash table of references to DIE's that describe declarations. /* A hash table of references to DIE's that describe declarations.
The key is a DECL_UID() which is a unique number identifying each decl. */ The key is a DECL_UID() which is a unique number identifying each decl. */
static GTY ((param_is (struct die_struct))) htab_t decl_die_table; static GTY (()) hash_table<decl_die_hasher> *decl_die_table;
struct block_die_hasher : ggc_hasher<die_struct *>
{
static hashval_t hash (die_struct *);
static bool equal (die_struct *, die_struct *);
};
/* A hash table of references to DIE's that describe COMMON blocks. /* A hash table of references to DIE's that describe COMMON blocks.
The key is DECL_UID() ^ die_parent. */ The key is DECL_UID() ^ die_parent. */
static GTY ((param_is (struct die_struct))) htab_t common_block_die_table; static GTY (()) hash_table<block_die_hasher> *common_block_die_table;
typedef struct GTY(()) die_arg_entry_struct { typedef struct GTY(()) die_arg_entry_struct {
dw_die_ref die; dw_die_ref die;
@ -2808,7 +2835,7 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node {
}; };
/* Variable location list. */ /* Variable location list. */
struct GTY (()) var_loc_list_def { struct GTY ((for_user)) var_loc_list_def {
struct var_loc_node * GTY (()) first; struct var_loc_node * GTY (()) first;
/* Pointer to the last but one or last element of the /* Pointer to the last but one or last element of the
@ -2840,8 +2867,16 @@ struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
}; };
struct decl_loc_hasher : ggc_hasher<var_loc_list *>
{
typedef const_tree compare_type;
static hashval_t hash (var_loc_list *);
static bool equal (var_loc_list *, const_tree);
};
/* Table of decl location linked lists. */ /* Table of decl location linked lists. */
static GTY ((param_is (var_loc_list))) htab_t decl_loc_table; static GTY (()) hash_table<decl_loc_hasher> *decl_loc_table;
/* Head and tail of call_arg_loc chain. */ /* Head and tail of call_arg_loc chain. */
static GTY (()) struct call_arg_loc_node *call_arg_locations; static GTY (()) struct call_arg_loc_node *call_arg_locations;
@ -2857,7 +2892,7 @@ static int tail_call_site_count = -1;
static vec<dw_die_ref> block_map; static vec<dw_die_ref> block_map;
/* A cached location list. */ /* A cached location list. */
struct GTY (()) cached_dw_loc_list_def { struct GTY ((for_user)) cached_dw_loc_list_def {
/* The DECL_UID of the decl that this entry describes. */ /* The DECL_UID of the decl that this entry describes. */
unsigned int decl_id; unsigned int decl_id;
@ -2866,8 +2901,17 @@ struct GTY (()) cached_dw_loc_list_def {
}; };
typedef struct cached_dw_loc_list_def cached_dw_loc_list; typedef struct cached_dw_loc_list_def cached_dw_loc_list;
struct dw_loc_list_hasher : ggc_hasher<cached_dw_loc_list *>
{
typedef const_tree compare_type;
static hashval_t hash (cached_dw_loc_list *);
static bool equal (cached_dw_loc_list *, const_tree);
};
/* Table of cached location lists. */ /* Table of cached location lists. */
static GTY ((param_is (cached_dw_loc_list))) htab_t cached_dw_loc_list_table; static GTY (()) hash_table<dw_loc_list_hasher> *cached_dw_loc_list_table;
/* A pointer to the base of a list of references to DIE's that /* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of are uniquely identified by their tag, presence/absence of
@ -3002,8 +3046,6 @@ static void add_AT_double (dw_die_ref, enum dwarf_attribute,
static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int, static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
unsigned int, unsigned char *); unsigned int, unsigned char *);
static void add_AT_data8 (dw_die_ref, enum dwarf_attribute, unsigned char *); static void add_AT_data8 (dw_die_ref, enum dwarf_attribute, unsigned char *);
static hashval_t debug_str_do_hash (const void *);
static int debug_str_eq (const void *, const void *);
static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
static inline const char *AT_string (dw_attr_ref); static inline const char *AT_string (dw_attr_ref);
static enum dwarf_form AT_string_form (dw_attr_ref); static enum dwarf_form AT_string_form (dw_attr_ref);
@ -3048,13 +3090,7 @@ static dw_die_ref lookup_type_die (tree);
static dw_die_ref strip_naming_typedef (tree, dw_die_ref); static dw_die_ref strip_naming_typedef (tree, dw_die_ref);
static dw_die_ref lookup_type_die_strip_naming_typedef (tree); static dw_die_ref lookup_type_die_strip_naming_typedef (tree);
static void equate_type_number_to_die (tree, dw_die_ref); static void equate_type_number_to_die (tree, dw_die_ref);
static hashval_t decl_die_table_hash (const void *);
static int decl_die_table_eq (const void *, const void *);
static dw_die_ref lookup_decl_die (tree); static dw_die_ref lookup_decl_die (tree);
static hashval_t common_block_die_table_hash (const void *);
static int common_block_die_table_eq (const void *, const void *);
static hashval_t decl_loc_table_hash (const void *);
static int decl_loc_table_eq (const void *, const void *);
static var_loc_list *lookup_decl_loc (const_tree); static var_loc_list *lookup_decl_loc (const_tree);
static void equate_decl_number_to_die (tree, dw_die_ref); static void equate_decl_number_to_die (tree, dw_die_ref);
static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *); static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *);
@ -3908,29 +3944,28 @@ add_AT_low_high_pc (dw_die_ref die, const char *lbl_low, const char *lbl_high,
/* Hash and equality functions for debug_str_hash. */ /* Hash and equality functions for debug_str_hash. */
static hashval_t hashval_t
debug_str_do_hash (const void *x) indirect_string_hasher::hash (indirect_string_node *x)
{ {
return htab_hash_string (((const struct indirect_string_node *)x)->str); return htab_hash_string (x->str);
} }
static int bool
debug_str_eq (const void *x1, const void *x2) indirect_string_hasher::equal (indirect_string_node *x1, const char *x2)
{ {
return strcmp ((((const struct indirect_string_node *)x1)->str), return strcmp (x1->str, x2) == 0;
(const char *)x2) == 0;
} }
/* Add STR to the given string hash table. */ /* Add STR to the given string hash table. */
static struct indirect_string_node * static struct indirect_string_node *
find_AT_string_in_table (const char *str, htab_t table) find_AT_string_in_table (const char *str,
hash_table<indirect_string_hasher> *table)
{ {
struct indirect_string_node *node; struct indirect_string_node *node;
void **slot;
slot = htab_find_slot_with_hash (table, str, indirect_string_node **slot
htab_hash_string (str), INSERT); = table->find_slot_with_hash (str, htab_hash_string (str), INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
node = ggc_cleared_alloc<indirect_string_node> (); node = ggc_cleared_alloc<indirect_string_node> ();
@ -3938,7 +3973,7 @@ find_AT_string_in_table (const char *str, htab_t table)
*slot = node; *slot = node;
} }
else else
node = (struct indirect_string_node *) *slot; node = *slot;
node->refcount++; node->refcount++;
return node; return node;
@ -3950,8 +3985,7 @@ static struct indirect_string_node *
find_AT_string (const char *str) find_AT_string (const char *str)
{ {
if (! debug_str_hash) if (! debug_str_hash)
debug_str_hash = htab_create_ggc (10, debug_str_do_hash, debug_str_hash = hash_table<indirect_string_hasher>::create_ggc (10);
debug_str_eq, NULL);
return find_AT_string_in_table (str, debug_str_hash); return find_AT_string_in_table (str, debug_str_hash);
} }
@ -4180,16 +4214,21 @@ AT_loc_list_ptr (dw_attr_ref a)
return &a->dw_attr_val.v.val_loc_list; return &a->dw_attr_val.v.val_loc_list;
} }
struct addr_hasher : ggc_hasher<addr_table_entry *>
{
static hashval_t hash (addr_table_entry *);
static bool equal (addr_table_entry *, addr_table_entry *);
};
/* Table of entries into the .debug_addr section. */ /* Table of entries into the .debug_addr section. */
static GTY ((param_is (addr_table_entry))) htab_t addr_index_table; static GTY (()) hash_table<addr_hasher> *addr_index_table;
/* Hash an address_table_entry. */ /* Hash an address_table_entry. */
static hashval_t hashval_t
addr_table_entry_do_hash (const void *x) addr_hasher::hash (addr_table_entry *a)
{ {
const addr_table_entry *a = (const addr_table_entry *) x;
inchash::hash hstate; inchash::hash hstate;
switch (a->kind) switch (a->kind)
{ {
@ -4210,12 +4249,9 @@ addr_table_entry_do_hash (const void *x)
/* Determine equality for two address_table_entries. */ /* Determine equality for two address_table_entries. */
static int bool
addr_table_entry_eq (const void *x1, const void *x2) addr_hasher::equal (addr_table_entry *a1, addr_table_entry *a2)
{ {
const addr_table_entry *a1 = (const addr_table_entry *) x1;
const addr_table_entry *a2 = (const addr_table_entry *) x2;
if (a1->kind != a2->kind) if (a1->kind != a2->kind)
return 0; return 0;
switch (a1->kind) switch (a1->kind)
@ -4258,14 +4294,12 @@ add_addr_table_entry (void *addr, enum ate_kind kind)
{ {
addr_table_entry *node; addr_table_entry *node;
addr_table_entry finder; addr_table_entry finder;
void **slot;
gcc_assert (dwarf_split_debug_info); gcc_assert (dwarf_split_debug_info);
if (! addr_index_table) if (! addr_index_table)
addr_index_table = htab_create_ggc (10, addr_table_entry_do_hash, addr_index_table = hash_table<addr_hasher>::create_ggc (10);
addr_table_entry_eq, NULL);
init_addr_table_entry (&finder, kind, addr); init_addr_table_entry (&finder, kind, addr);
slot = htab_find_slot (addr_index_table, &finder, INSERT); addr_table_entry **slot = addr_index_table->find_slot (&finder, INSERT);
if (*slot == HTAB_EMPTY_ENTRY) if (*slot == HTAB_EMPTY_ENTRY)
{ {
@ -4274,7 +4308,7 @@ add_addr_table_entry (void *addr, enum ate_kind kind)
*slot = node; *slot = node;
} }
else else
node = (addr_table_entry *) *slot; node = *slot;
node->refcount++; node->refcount++;
return node; return node;
@ -4314,11 +4348,10 @@ remove_loc_list_addr_table_entries (dw_loc_descr_ref descr)
because the indexing code relies on htab_traverse to traverse nodes because the indexing code relies on htab_traverse to traverse nodes
in the same order for each run. */ in the same order for each run. */
static int int
index_addr_table_entry (void **h, void *v) index_addr_table_entry (addr_table_entry **h, unsigned int *index)
{ {
addr_table_entry *node = (addr_table_entry *) *h; addr_table_entry *node = *h;
unsigned int *index = (unsigned int *) v;
/* Don't index unreferenced nodes. */ /* Don't index unreferenced nodes. */
if (node->refcount == 0) if (node->refcount == 0)
@ -4913,18 +4946,18 @@ equate_type_number_to_die (tree type, dw_die_ref type_die)
/* Returns a hash value for X (which really is a die_struct). */ /* Returns a hash value for X (which really is a die_struct). */
static hashval_t inline hashval_t
decl_die_table_hash (const void *x) decl_die_hasher::hash (die_node *x)
{ {
return (hashval_t) ((const_dw_die_ref) x)->decl_id; return (hashval_t) x->decl_id;
} }
/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */ /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
static int inline bool
decl_die_table_eq (const void *x, const void *y) decl_die_hasher::equal (die_node *x, tree y)
{ {
return (((const_dw_die_ref) x)->decl_id == DECL_UID ((const_tree) y)); return (x->decl_id == DECL_UID (y));
} }
/* Return the DIE associated with a given declaration. */ /* Return the DIE associated with a given declaration. */
@ -4932,24 +4965,24 @@ decl_die_table_eq (const void *x, const void *y)
static inline dw_die_ref static inline dw_die_ref
lookup_decl_die (tree decl) lookup_decl_die (tree decl)
{ {
return (dw_die_ref) htab_find_with_hash (decl_die_table, decl, DECL_UID (decl)); return decl_die_table->find_with_hash (decl, DECL_UID (decl));
} }
/* Returns a hash value for X (which really is a var_loc_list). */ /* Returns a hash value for X (which really is a var_loc_list). */
static hashval_t inline hashval_t
decl_loc_table_hash (const void *x) decl_loc_hasher::hash (var_loc_list *x)
{ {
return (hashval_t) ((const var_loc_list *) x)->decl_id; return (hashval_t) x->decl_id;
} }
/* Return nonzero if decl_id of var_loc_list X is the same as /* Return nonzero if decl_id of var_loc_list X is the same as
UID of decl *Y. */ UID of decl *Y. */
static int inline bool
decl_loc_table_eq (const void *x, const void *y) decl_loc_hasher::equal (var_loc_list *x, const_tree y)
{ {
return (((const var_loc_list *) x)->decl_id == DECL_UID ((const_tree) y)); return (x->decl_id == DECL_UID (y));
} }
/* Return the var_loc list associated with a given declaration. */ /* Return the var_loc list associated with a given declaration. */
@ -4959,26 +4992,24 @@ lookup_decl_loc (const_tree decl)
{ {
if (!decl_loc_table) if (!decl_loc_table)
return NULL; return NULL;
return (var_loc_list *) return decl_loc_table->find_with_hash (decl, DECL_UID (decl));
htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
} }
/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */ /* Returns a hash value for X (which really is a cached_dw_loc_list_list). */
static hashval_t inline hashval_t
cached_dw_loc_list_table_hash (const void *x) dw_loc_list_hasher::hash (cached_dw_loc_list *x)
{ {
return (hashval_t) ((const cached_dw_loc_list *) x)->decl_id; return (hashval_t) x->decl_id;
} }
/* Return nonzero if decl_id of cached_dw_loc_list X is the same as /* Return nonzero if decl_id of cached_dw_loc_list X is the same as
UID of decl *Y. */ UID of decl *Y. */
static int inline bool
cached_dw_loc_list_table_eq (const void *x, const void *y) dw_loc_list_hasher::equal (cached_dw_loc_list *x, const_tree y)
{ {
return (((const cached_dw_loc_list *) x)->decl_id return (x->decl_id == DECL_UID (y));
== DECL_UID ((const_tree) y));
} }
/* Equate a DIE to a particular declaration. */ /* Equate a DIE to a particular declaration. */
@ -4987,10 +5018,8 @@ static void
equate_decl_number_to_die (tree decl, dw_die_ref decl_die) equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
{ {
unsigned int decl_id = DECL_UID (decl); unsigned int decl_id = DECL_UID (decl);
void **slot;
slot = htab_find_slot_with_hash (decl_die_table, decl, decl_id, INSERT); *decl_die_table->find_slot_with_hash (decl, decl_id, INSERT) = decl_die;
*slot = decl_die;
decl_die->decl_id = decl_id; decl_die->decl_id = decl_id;
} }
@ -5138,7 +5167,6 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
{ {
unsigned int decl_id; unsigned int decl_id;
var_loc_list *temp; var_loc_list *temp;
void **slot;
struct var_loc_node *loc = NULL; struct var_loc_node *loc = NULL;
HOST_WIDE_INT bitsize = -1, bitpos = -1; HOST_WIDE_INT bitsize = -1, bitpos = -1;
@ -5166,7 +5194,8 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
} }
decl_id = DECL_UID (decl); decl_id = DECL_UID (decl);
slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT); var_loc_list **slot
= decl_loc_table->find_slot_with_hash (decl, decl_id, INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
temp = ggc_cleared_alloc<var_loc_list> (); temp = ggc_cleared_alloc<var_loc_list> ();
@ -5174,7 +5203,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
*slot = temp; *slot = temp;
} }
else else
temp = (var_loc_list *) *slot; temp = *slot;
/* For PARM_DECLs try to keep around the original incoming value, /* For PARM_DECLs try to keep around the original incoming value,
even if that means we'll emit a zero-range .debug_loc entry. */ even if that means we'll emit a zero-range .debug_loc entry. */
@ -9037,8 +9066,8 @@ add_skeleton_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind,
struct indirect_string_node *node; struct indirect_string_node *node;
if (! skeleton_debug_str_hash) if (! skeleton_debug_str_hash)
skeleton_debug_str_hash = htab_create_ggc (10, debug_str_do_hash, skeleton_debug_str_hash
debug_str_eq, NULL); = hash_table<indirect_string_hasher>::create_ggc (10);
node = find_AT_string_in_table (str, skeleton_debug_str_hash); node = find_AT_string_in_table (str, skeleton_debug_str_hash);
find_string_form (node); find_string_form (node);
@ -9739,11 +9768,10 @@ struct file_name_acquire_data
/* Traversal function for the hash table. */ /* Traversal function for the hash table. */
static int int
file_name_acquire (void ** slot, void *data) file_name_acquire (dwarf_file_data **slot, file_name_acquire_data *fnad)
{ {
struct file_name_acquire_data *fnad = (struct file_name_acquire_data *) data; struct dwarf_file_data *d = *slot;
struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
struct file_info *fi; struct file_info *fi;
const char *f; const char *f;
@ -9818,7 +9846,7 @@ output_file_names (void)
fnad.files = files; fnad.files = files;
fnad.used_files = 0; fnad.used_files = 0;
fnad.max_files = numfiles; fnad.max_files = numfiles;
htab_traverse (file_table, file_name_acquire, &fnad); file_table->traverse<file_name_acquire_data *, file_name_acquire> (&fnad);
gcc_assert (fnad.used_files == fnad.max_files); gcc_assert (fnad.used_files == fnad.max_files);
qsort (files, numfiles, sizeof (files[0]), file_info_cmp); qsort (files, numfiles, sizeof (files[0]), file_info_cmp);
@ -15812,7 +15840,6 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
dw_loc_list_ref list; dw_loc_list_ref list;
var_loc_list *loc_list; var_loc_list *loc_list;
cached_dw_loc_list *cache; cached_dw_loc_list *cache;
void **slot;
if (TREE_CODE (decl) == ERROR_MARK) if (TREE_CODE (decl) == ERROR_MARK)
return false; return false;
@ -15856,8 +15883,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
cache_p = false; cache_p = false;
if (cache_p) if (cache_p)
{ {
cache = (cached_dw_loc_list *) cache = cached_dw_loc_list_table->find_with_hash (decl, DECL_UID (decl));
htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl));
if (cache) if (cache)
list = cache->loc_list; list = cache->loc_list;
} }
@ -15868,8 +15894,10 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */ BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */
if (cache_p && list && list->dw_loc_next) if (cache_p && list && list->dw_loc_next)
{ {
slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl, cached_dw_loc_list **slot
DECL_UID (decl), INSERT); = cached_dw_loc_list_table->find_slot_with_hash (decl,
DECL_UID (decl),
INSERT);
cache = ggc_cleared_alloc<cached_dw_loc_list> (); cache = ggc_cleared_alloc<cached_dw_loc_list> ();
cache->decl_id = DECL_UID (decl); cache->decl_id = DECL_UID (decl);
cache->loc_list = list; cache->loc_list = list;
@ -17991,8 +18019,8 @@ dwarf2out_abstract_function (tree decl)
tree save_fn; tree save_fn;
tree context; tree context;
int was_abstract; int was_abstract;
htab_t old_decl_loc_table; hash_table<decl_loc_hasher> *old_decl_loc_table;
htab_t old_cached_dw_loc_list_table; hash_table<dw_loc_list_hasher> *old_cached_dw_loc_list_table;
int old_call_site_count, old_tail_call_site_count; int old_call_site_count, old_tail_call_site_count;
struct call_arg_loc_node *old_call_arg_locations; struct call_arg_loc_node *old_call_arg_locations;
@ -18070,9 +18098,9 @@ premark_used_types_helper (tree const &type, void *)
marked as unused by prune_unused_types. The DIE of the type is marked marked as unused by prune_unused_types. The DIE of the type is marked
only if the global variable using the type will actually be emitted. */ only if the global variable using the type will actually be emitted. */
static int int
premark_types_used_by_global_vars_helper (void **slot, premark_types_used_by_global_vars_helper (types_used_by_vars_entry **slot,
void *data ATTRIBUTE_UNUSED) void *)
{ {
struct types_used_by_vars_entry *entry; struct types_used_by_vars_entry *entry;
dw_die_ref die; dw_die_ref die;
@ -18112,8 +18140,8 @@ static void
premark_types_used_by_global_vars (void) premark_types_used_by_global_vars (void)
{ {
if (types_used_by_vars_hash) if (types_used_by_vars_hash)
htab_traverse (types_used_by_vars_hash, types_used_by_vars_hash
premark_types_used_by_global_vars_helper, NULL); ->traverse<void *, premark_types_used_by_global_vars_helper> (NULL);
} }
/* Generate a DW_TAG_GNU_call_site DIE in function DECL under SUBR_DIE /* Generate a DW_TAG_GNU_call_site DIE in function DECL under SUBR_DIE
@ -18782,22 +18810,19 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
/* Returns a hash value for X (which really is a die_struct). */ /* Returns a hash value for X (which really is a die_struct). */
static hashval_t hashval_t
common_block_die_table_hash (const void *x) block_die_hasher::hash (die_struct *d)
{ {
const_dw_die_ref d = (const_dw_die_ref) x;
return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent); return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent);
} }
/* Return nonzero if decl_id and die_parent of die_struct X is the same /* Return nonzero if decl_id and die_parent of die_struct X is the same
as decl_id and die_parent of die_struct Y. */ as decl_id and die_parent of die_struct Y. */
static int bool
common_block_die_table_eq (const void *x, const void *y) block_die_hasher::equal (die_struct *x, die_struct *y)
{ {
const_dw_die_ref d = (const_dw_die_ref) x; return x->decl_id == y->decl_id && x->die_parent == y->die_parent;
const_dw_die_ref e = (const_dw_die_ref) y;
return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
} }
/* Generate a DIE to represent a declared data object. /* Generate a DIE to represent a declared data object.
@ -18862,19 +18887,17 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
} }
if (common_block_die_table == NULL) if (common_block_die_table == NULL)
common_block_die_table common_block_die_table = hash_table<block_die_hasher>::create_ggc (10);
= htab_create_ggc (10, common_block_die_table_hash,
common_block_die_table_eq, NULL);
com_die_arg.decl_id = DECL_UID (com_decl); com_die_arg.decl_id = DECL_UID (com_decl);
com_die_arg.die_parent = context_die; com_die_arg.die_parent = context_die;
com_die = (dw_die_ref) htab_find (common_block_die_table, &com_die_arg); com_die = common_block_die_table->find (&com_die_arg);
loc = loc_list_from_tree (com_decl, 2); loc = loc_list_from_tree (com_decl, 2);
if (com_die == NULL) if (com_die == NULL)
{ {
const char *cnam const char *cnam
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl)); = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
void **slot; die_node **slot;
com_die = new_die (DW_TAG_common_block, context_die, decl); com_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (com_die, com_decl); add_name_and_src_coords_attributes (com_die, com_decl);
@ -18890,8 +18913,8 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
if (want_pubnames ()) if (want_pubnames ())
add_pubname_string (cnam, com_die); /* ??? needed? */ add_pubname_string (cnam, com_die); /* ??? needed? */
com_die->decl_id = DECL_UID (com_decl); com_die->decl_id = DECL_UID (com_decl);
slot = htab_find_slot (common_block_die_table, com_die, INSERT); slot = common_block_die_table->find_slot (com_die, INSERT);
*slot = (void *) com_die; *slot = com_die;
} }
else if (get_AT (com_die, DW_AT_location) == NULL && loc) else if (get_AT (com_die, DW_AT_location) == NULL && loc)
{ {
@ -21066,8 +21089,8 @@ dwarf2out_function_decl (tree decl)
call_site_count = -1; call_site_count = -1;
tail_call_site_count = -1; tail_call_site_count = -1;
block_map.release (); block_map.release ();
htab_empty (decl_loc_table); decl_loc_table->empty ();
htab_empty (cached_dw_loc_list_table); cached_dw_loc_list_table->empty ();
} }
/* Output a marker (i.e. a label) for the beginning of the generated code for /* Output a marker (i.e. a label) for the beginning of the generated code for
@ -21121,19 +21144,15 @@ dwarf2out_ignore_block (const_tree block)
/* Hash table routines for file_hash. */ /* Hash table routines for file_hash. */
static int bool
file_table_eq (const void *p1_p, const void *p2_p) dwarf_file_hasher::equal (dwarf_file_data *p1, const char *p2)
{ {
const struct dwarf_file_data *const p1 =
(const struct dwarf_file_data *) p1_p;
const char *const p2 = (const char *) p2_p;
return filename_cmp (p1->filename, p2) == 0; return filename_cmp (p1->filename, p2) == 0;
} }
static hashval_t hashval_t
file_table_hash (const void *p_p) dwarf_file_hasher::hash (dwarf_file_data *p)
{ {
const struct dwarf_file_data *const p = (const struct dwarf_file_data *) p_p;
return htab_hash_string (p->filename); return htab_hash_string (p->filename);
} }
@ -21151,7 +21170,6 @@ file_table_hash (const void *p_p)
static struct dwarf_file_data * static struct dwarf_file_data *
lookup_filename (const char *file_name) lookup_filename (const char *file_name)
{ {
void ** slot;
struct dwarf_file_data * created; struct dwarf_file_data * created;
/* Check to see if the file name that was searched on the previous /* Check to see if the file name that was searched on the previous
@ -21162,10 +21180,11 @@ lookup_filename (const char *file_name)
return file_table_last_lookup; return file_table_last_lookup;
/* Didn't match the previous lookup, search the table. */ /* Didn't match the previous lookup, search the table. */
slot = htab_find_slot_with_hash (file_table, file_name, dwarf_file_data **slot
htab_hash_string (file_name), INSERT); = file_table->find_slot_with_hash (file_name, htab_hash_string (file_name),
INSERT);
if (*slot) if (*slot)
return (struct dwarf_file_data *) *slot; return *slot;
created = ggc_alloc<dwarf_file_data> (); created = ggc_alloc<dwarf_file_data> ();
created->filename = file_name; created->filename = file_name;
@ -21525,10 +21544,10 @@ dwarf2out_var_location (rtx_insn *loc_note)
/* Note in one location list that text section has changed. */ /* Note in one location list that text section has changed. */
static int int
var_location_switch_text_section_1 (void **slot, void *data ATTRIBUTE_UNUSED) var_location_switch_text_section_1 (var_loc_list **slot, void *)
{ {
var_loc_list *list = (var_loc_list *) *slot; var_loc_list *list = *slot;
if (list->first) if (list->first)
list->last_before_switch list->last_before_switch
= list->last->next ? list->last->next : list->last; = list->last->next ? list->last->next : list->last;
@ -21543,7 +21562,7 @@ var_location_switch_text_section (void)
if (decl_loc_table == NULL) if (decl_loc_table == NULL)
return; return;
htab_traverse (decl_loc_table, var_location_switch_text_section_1, NULL); decl_loc_table->traverse<void *, var_location_switch_text_section_1> (NULL);
} }
/* Create a new line number table. */ /* Create a new line number table. */
@ -21652,13 +21671,12 @@ dwarf2out_begin_function (tree fun)
Set have_multiple_function_sections to true in that case and Set have_multiple_function_sections to true in that case and
terminate htab traversal. */ terminate htab traversal. */
static int int
find_empty_loc_ranges_at_text_label (void **slot, void *) find_empty_loc_ranges_at_text_label (var_loc_list **slot, int)
{ {
var_loc_list *entry; var_loc_list *entry = *slot;
struct var_loc_node *node; struct var_loc_node *node;
entry = (var_loc_list *) *slot;
node = entry->first; node = entry->first;
if (node && node->next && node->next->label) if (node && node->next && node->next->label)
{ {
@ -21689,8 +21707,7 @@ dwarf2out_end_function (unsigned int)
&& !have_multiple_function_sections && !have_multiple_function_sections
&& first_loclabel_num_not_at_text_label && first_loclabel_num_not_at_text_label
&& decl_loc_table) && decl_loc_table)
htab_traverse (decl_loc_table, find_empty_loc_ranges_at_text_label, decl_loc_table->traverse<int, find_empty_loc_ranges_at_text_label> (0);
NULL);
in_first_function_p = false; in_first_function_p = false;
maybe_at_text_label_p = false; maybe_at_text_label_p = false;
} }
@ -22303,21 +22320,16 @@ static void
dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
{ {
/* Allocate the file_table. */ /* Allocate the file_table. */
file_table = htab_create_ggc (50, file_table_hash, file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
file_table_eq, NULL);
/* Allocate the decl_die_table. */ /* Allocate the decl_die_table. */
decl_die_table = htab_create_ggc (10, decl_die_table_hash, decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);
decl_die_table_eq, NULL);
/* Allocate the decl_loc_table. */ /* Allocate the decl_loc_table. */
decl_loc_table = htab_create_ggc (10, decl_loc_table_hash, decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);
decl_loc_table_eq, NULL);
/* Allocate the cached_dw_loc_list_table. */ /* Allocate the cached_dw_loc_list_table. */
cached_dw_loc_list_table cached_dw_loc_list_table = hash_table<dw_loc_list_hasher>::create_ggc (10);
= htab_create_ggc (10, cached_dw_loc_list_table_hash,
cached_dw_loc_list_table_eq, NULL);
/* Allocate the initial hunk of the decl_scope_table. */ /* Allocate the initial hunk of the decl_scope_table. */
vec_alloc (decl_scope_table, 256); vec_alloc (decl_scope_table, 256);
@ -22450,11 +22462,10 @@ dwarf2out_assembly_start (void)
because the indexing code relies on htab_traverse to traverse nodes because the indexing code relies on htab_traverse to traverse nodes
in the same order for each run. */ in the same order for each run. */
static int int
index_string (void **h, void *v) index_string (indirect_string_node **h, unsigned int *index)
{ {
struct indirect_string_node *node = (struct indirect_string_node *) *h; indirect_string_node *node = *h;
unsigned int *index = (unsigned int *) v;
find_string_form (node); find_string_form (node);
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0) if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
@ -22470,11 +22481,10 @@ index_string (void **h, void *v)
htab_traverse. Output the offset to a string and update the htab_traverse. Output the offset to a string and update the
current offset. */ current offset. */
static int int
output_index_string_offset (void **h, void *v) output_index_string_offset (indirect_string_node **h, unsigned int *offset)
{ {
struct indirect_string_node *node = (struct indirect_string_node *) *h; indirect_string_node *node = *h;
unsigned int *offset = (unsigned int *) v;
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0) if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
{ {
@ -22491,11 +22501,10 @@ output_index_string_offset (void **h, void *v)
/* A helper function for dwarf2out_finish called through /* A helper function for dwarf2out_finish called through
htab_traverse. Output the indexed string. */ htab_traverse. Output the indexed string. */
static int int
output_index_string (void **h, void *v) output_index_string (indirect_string_node **h, unsigned int *cur_idx)
{ {
struct indirect_string_node *node = (struct indirect_string_node *) *h; struct indirect_string_node *node = *h;
unsigned int *cur_idx = (unsigned int *) v;
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0) if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
{ {
@ -22511,10 +22520,10 @@ output_index_string (void **h, void *v)
/* A helper function for dwarf2out_finish called through /* A helper function for dwarf2out_finish called through
htab_traverse. Emit one queued .debug_str string. */ htab_traverse. Emit one queued .debug_str string. */
static int int
output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED) output_indirect_string (indirect_string_node **h, void *)
{ {
struct indirect_string_node *node = (struct indirect_string_node *) *h; struct indirect_string_node *node = *h;
node->form = find_string_form (node); node->form = find_string_form (node);
if (node->form == DW_FORM_strp && node->refcount > 0) if (node->form == DW_FORM_strp && node->refcount > 0)
@ -22533,33 +22542,30 @@ output_indirect_strings (void)
{ {
switch_to_section (debug_str_section); switch_to_section (debug_str_section);
if (!dwarf_split_debug_info) if (!dwarf_split_debug_info)
htab_traverse (debug_str_hash, output_indirect_string, NULL); debug_str_hash->traverse<void *, output_indirect_string> (NULL);
else else
{ {
unsigned int offset = 0; unsigned int offset = 0;
unsigned int cur_idx = 0; unsigned int cur_idx = 0;
htab_traverse (skeleton_debug_str_hash, output_indirect_string, NULL); skeleton_debug_str_hash->traverse<void *, output_indirect_string> (NULL);
switch_to_section (debug_str_offsets_section); switch_to_section (debug_str_offsets_section);
htab_traverse_noresize (debug_str_hash, debug_str_hash->traverse_noresize
output_index_string_offset, <unsigned int *, output_index_string_offset> (&offset);
&offset);
switch_to_section (debug_str_dwo_section); switch_to_section (debug_str_dwo_section);
htab_traverse_noresize (debug_str_hash, debug_str_hash->traverse_noresize<unsigned int *, output_index_string>
output_index_string, (&cur_idx);
&cur_idx);
} }
} }
/* Callback for htab_traverse to assign an index to an entry in the /* Callback for htab_traverse to assign an index to an entry in the
table, and to write that entry to the .debug_addr section. */ table, and to write that entry to the .debug_addr section. */
static int int
output_addr_table_entry (void **slot, void *data) output_addr_table_entry (addr_table_entry **slot, unsigned int *cur_index)
{ {
addr_table_entry *entry = (addr_table_entry *) *slot; addr_table_entry *entry = *slot;
unsigned int *cur_index = (unsigned int *)data;
if (entry->refcount == 0) if (entry->refcount == 0)
{ {
@ -22600,11 +22606,12 @@ static void
output_addr_table (void) output_addr_table (void)
{ {
unsigned int index = 0; unsigned int index = 0;
if (addr_index_table == NULL || htab_size (addr_index_table) == 0) if (addr_index_table == NULL || addr_index_table->size () == 0)
return; return;
switch_to_section (debug_addr_section); switch_to_section (debug_addr_section);
htab_traverse_noresize (addr_index_table, output_addr_table_entry, &index); addr_index_table
->traverse_noresize<unsigned int *, output_addr_table_entry> (&index);
} }
#if ENABLE_ASSERT_CHECKING #if ENABLE_ASSERT_CHECKING
@ -22859,10 +22866,10 @@ prune_unused_types_update_strings (dw_die_ref die)
if (s->refcount if (s->refcount
== ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2)) == ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2))
{ {
void ** slot; indirect_string_node **slot
slot = htab_find_slot_with_hash (debug_str_hash, s->str, = debug_str_hash->find_slot_with_hash (s->str,
htab_hash_string (s->str), htab_hash_string (s->str),
INSERT); INSERT);
gcc_assert (*slot == NULL); gcc_assert (*slot == NULL);
*slot = s; *slot = s;
} }
@ -22950,9 +22957,9 @@ prune_unused_types (void)
prune_unused_types_mark (base_type, 1); prune_unused_types_mark (base_type, 1);
if (debug_str_hash) if (debug_str_hash)
htab_empty (debug_str_hash); debug_str_hash->empty ();
if (skeleton_debug_str_hash) if (skeleton_debug_str_hash)
htab_empty (skeleton_debug_str_hash); skeleton_debug_str_hash->empty ();
prune_unused_types_prune (comp_unit_die ()); prune_unused_types_prune (comp_unit_die ());
for (node = limbo_die_list; node; node = node->next) for (node = limbo_die_list; node; node = node->next)
prune_unused_types_prune (node->die); prune_unused_types_prune (node->die);
@ -22969,11 +22976,10 @@ prune_unused_types (void)
/* Set the parameter to true if there are any relative pathnames in /* Set the parameter to true if there are any relative pathnames in
the file table. */ the file table. */
static int int
file_table_relative_p (void ** slot, void *param) file_table_relative_p (dwarf_file_data **slot, bool *p)
{ {
bool *p = (bool *) param; struct dwarf_file_data *d = *slot;
struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
if (!IS_ABSOLUTE_PATH (d->filename)) if (!IS_ABSOLUTE_PATH (d->filename))
{ {
*p = true; *p = true;
@ -24222,7 +24228,7 @@ dwarf2out_finish (const char *filename)
else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL) else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
{ {
bool p = false; bool p = false;
htab_traverse (file_table, file_table_relative_p, &p); file_table->traverse<bool *, file_table_relative_p> (&p);
if (p) if (p)
add_comp_dir_attribute (comp_unit_die ()); add_comp_dir_attribute (comp_unit_die ());
} }
@ -24444,8 +24450,9 @@ dwarf2out_finish (const char *filename)
if (addr_index_table != NULL) if (addr_index_table != NULL)
{ {
unsigned int index = 0; unsigned int index = 0;
htab_traverse_noresize (addr_index_table, addr_index_table
index_addr_table_entry, &index); ->traverse_noresize<unsigned int *, index_addr_table_entry>
(&index);
} }
} }
@ -24464,7 +24471,7 @@ dwarf2out_finish (const char *filename)
skeleton die attrs are added when the skeleton type unit is skeleton die attrs are added when the skeleton type unit is
created, so ensure it is created by this point. */ created, so ensure it is created by this point. */
add_top_level_skeleton_die_attrs (main_comp_unit_die); add_top_level_skeleton_die_attrs (main_comp_unit_die);
htab_traverse_noresize (debug_str_hash, index_string, &index); debug_str_hash->traverse_noresize<unsigned int *, index_string> (&index);
} }
/* Output all of the compilation units. We put the main one last so that /* Output all of the compilation units. We put the main one last so that

View File

@ -1,3 +1,7 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* trans-decl.c, trans.c, trans.h: Use hash_table instead of hashtab.
2014-10-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 2014-10-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/48979 PR fortran/48979

View File

@ -4228,72 +4228,62 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE); gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
} }
static GTY ((param_is (struct module_htab_entry))) htab_t module_htab; struct module_hasher : ggc_hasher<module_htab_entry *>
/* Hash and equality functions for module_htab. */
static hashval_t
module_htab_do_hash (const void *x)
{ {
return htab_hash_string (((const struct module_htab_entry *)x)->name); typedef const char *compare_type;
}
static int static hashval_t hash (module_htab_entry *s) { return htab_hash_string (s); }
module_htab_eq (const void *x1, const void *x2) static bool
{ equal (module_htab_entry *a, const char *b)
return strcmp ((((const struct module_htab_entry *)x1)->name), {
(const char *)x2) == 0; return !strcmp (a->name, b);
} }
};
static GTY (()) hash_table<module_hasher> *module_htab;
/* Hash and equality functions for module_htab's decls. */ /* Hash and equality functions for module_htab's decls. */
static hashval_t hashval_t
module_htab_decls_hash (const void *x) module_decl_hasher::hash (tree t)
{ {
const_tree t = (const_tree) x;
const_tree n = DECL_NAME (t); const_tree n = DECL_NAME (t);
if (n == NULL_TREE) if (n == NULL_TREE)
n = TYPE_NAME (TREE_TYPE (t)); n = TYPE_NAME (TREE_TYPE (t));
return htab_hash_string (IDENTIFIER_POINTER (n)); return htab_hash_string (IDENTIFIER_POINTER (n));
} }
static int bool
module_htab_decls_eq (const void *x1, const void *x2) module_decl_hasher::equal (tree t1, const char *x2)
{ {
const_tree t1 = (const_tree) x1;
const_tree n1 = DECL_NAME (t1); const_tree n1 = DECL_NAME (t1);
if (n1 == NULL_TREE) if (n1 == NULL_TREE)
n1 = TYPE_NAME (TREE_TYPE (t1)); n1 = TYPE_NAME (TREE_TYPE (t1));
return strcmp (IDENTIFIER_POINTER (n1), (const char *) x2) == 0; return strcmp (IDENTIFIER_POINTER (n1), x2) == 0;
} }
struct module_htab_entry * struct module_htab_entry *
gfc_find_module (const char *name) gfc_find_module (const char *name)
{ {
void **slot;
if (! module_htab) if (! module_htab)
module_htab = htab_create_ggc (10, module_htab_do_hash, module_htab = hash_table<module_hasher>::create_ggc (10);
module_htab_eq, NULL);
slot = htab_find_slot_with_hash (module_htab, name, module_htab_entry **slot
htab_hash_string (name), INSERT); = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> (); module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
entry->name = gfc_get_string (name); entry->name = gfc_get_string (name);
entry->decls = htab_create_ggc (10, module_htab_decls_hash, entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
module_htab_decls_eq, NULL); *slot = entry;
*slot = (void *) entry;
} }
return (struct module_htab_entry *) *slot; return *slot;
} }
void void
gfc_module_add_decl (struct module_htab_entry *entry, tree decl) gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
{ {
void **slot;
const char *name; const char *name;
if (DECL_NAME (decl)) if (DECL_NAME (decl))
@ -4303,10 +4293,11 @@ gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
gcc_assert (TREE_CODE (decl) == TYPE_DECL); gcc_assert (TREE_CODE (decl) == TYPE_DECL);
name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))); name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
} }
slot = htab_find_slot_with_hash (entry->decls, name, tree *slot
htab_hash_string (name), INSERT); = entry->decls->find_slot_with_hash (name, htab_hash_string (name),
INSERT);
if (*slot == NULL) if (*slot == NULL)
*slot = (void *) decl; *slot = decl;
} }
static struct module_htab_entry *cur_module; static struct module_htab_entry *cur_module;
@ -4485,14 +4476,13 @@ gfc_trans_use_stmts (gfc_namespace * ns)
for (rent = use_stmt->rename; rent; rent = rent->next) for (rent = use_stmt->rename; rent; rent = rent->next)
{ {
tree decl, local_name; tree decl, local_name;
void **slot;
if (rent->op != INTRINSIC_NONE) if (rent->op != INTRINSIC_NONE)
continue; continue;
slot = htab_find_slot_with_hash (entry->decls, rent->use_name, hashval_t hash = htab_hash_string (rent->use_name);
htab_hash_string (rent->use_name), tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
INSERT); INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
gfc_symtree *st; gfc_symtree *st;
@ -4547,7 +4537,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
else else
{ {
*slot = error_mark_node; *slot = error_mark_node;
htab_clear_slot (entry->decls, slot); entry->decls->clear_slot (slot);
continue; continue;
} }
*slot = decl; *slot = decl;

View File

@ -1963,7 +1963,7 @@ gfc_generate_module_code (gfc_namespace * ns)
entry = gfc_find_module (ns->proc_name->name); entry = gfc_find_module (ns->proc_name->name);
if (entry->namespace_decl) if (entry->namespace_decl)
/* Buggy sourcecode, using a module before defining it? */ /* Buggy sourcecode, using a module before defining it? */
htab_empty (entry->decls); entry->decls->empty ();
entry->namespace_decl = ns->proc_name->backend_decl; entry->namespace_decl = ns->proc_name->backend_decl;
gfc_generate_module_vars (ns); gfc_generate_module_vars (ns);

View File

@ -575,10 +575,18 @@ void gfc_generate_module_vars (gfc_namespace *);
/* Get the appropriate return statement for a procedure. */ /* Get the appropriate return statement for a procedure. */
tree gfc_generate_return (void); tree gfc_generate_return (void);
struct GTY(()) module_htab_entry { struct module_decl_hasher : ggc_hasher<tree_node *>
{
typedef const char *compare_type;
static hashval_t hash (tree);
static bool equal (tree, const char *);
};
struct GTY((for_user)) module_htab_entry {
const char *name; const char *name;
tree namespace_decl; tree namespace_decl;
htab_t GTY ((param_is (union tree_node))) decls; hash_table<module_decl_hasher> *GTY (()) decls;
}; };
struct module_htab_entry *gfc_find_module (const char *); struct module_htab_entry *gfc_find_module (const char *);

View File

@ -108,7 +108,7 @@ static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
htab_t epilogue_insn_hash; htab_t epilogue_insn_hash;
htab_t types_used_by_vars_hash = NULL; hash_table<used_type_hasher> *types_used_by_vars_hash = NULL;
vec<tree, va_gc> *types_used_by_cur_var_decl; vec<tree, va_gc> *types_used_by_cur_var_decl;
/* Forward declarations. */ /* Forward declarations. */
@ -540,18 +540,24 @@ struct GTY(()) temp_slot {
HOST_WIDE_INT full_size; HOST_WIDE_INT full_size;
}; };
/* A table of addresses that represent a stack slot. The table is a mapping /* Entry for the below hash table. */
from address RTXen to a temp slot. */ struct GTY((for_user)) temp_slot_address_entry {
static GTY((param_is(struct temp_slot_address_entry))) htab_t temp_slot_address_table;
static size_t n_temp_slots_in_use;
/* Entry for the above hash table. */
struct GTY(()) temp_slot_address_entry {
hashval_t hash; hashval_t hash;
rtx address; rtx address;
struct temp_slot *temp_slot; struct temp_slot *temp_slot;
}; };
struct temp_address_hasher : ggc_hasher<temp_slot_address_entry *>
{
static hashval_t hash (temp_slot_address_entry *);
static bool equal (temp_slot_address_entry *, temp_slot_address_entry *);
};
/* A table of addresses that represent a stack slot. The table is a mapping
from address RTXen to a temp slot. */
static GTY(()) hash_table<temp_address_hasher> *temp_slot_address_table;
static size_t n_temp_slots_in_use;
/* Removes temporary slot TEMP from LIST. */ /* Removes temporary slot TEMP from LIST. */
static void static void
@ -634,21 +640,17 @@ temp_slot_address_compute_hash (struct temp_slot_address_entry *t)
} }
/* Return the hash value for an address -> temp slot mapping. */ /* Return the hash value for an address -> temp slot mapping. */
static hashval_t hashval_t
temp_slot_address_hash (const void *p) temp_address_hasher::hash (temp_slot_address_entry *t)
{ {
const struct temp_slot_address_entry *t;
t = (const struct temp_slot_address_entry *) p;
return t->hash; return t->hash;
} }
/* Compare two address -> temp slot mapping entries. */ /* Compare two address -> temp slot mapping entries. */
static int bool
temp_slot_address_eq (const void *p1, const void *p2) temp_address_hasher::equal (temp_slot_address_entry *t1,
temp_slot_address_entry *t2)
{ {
const struct temp_slot_address_entry *t1, *t2;
t1 = (const struct temp_slot_address_entry *) p1;
t2 = (const struct temp_slot_address_entry *) p2;
return exp_equiv_p (t1->address, t2->address, 0, true); return exp_equiv_p (t1->address, t2->address, 0, true);
} }
@ -656,24 +658,21 @@ temp_slot_address_eq (const void *p1, const void *p2)
static void static void
insert_temp_slot_address (rtx address, struct temp_slot *temp_slot) insert_temp_slot_address (rtx address, struct temp_slot *temp_slot)
{ {
void **slot;
struct temp_slot_address_entry *t = ggc_alloc<temp_slot_address_entry> (); struct temp_slot_address_entry *t = ggc_alloc<temp_slot_address_entry> ();
t->address = address; t->address = address;
t->temp_slot = temp_slot; t->temp_slot = temp_slot;
t->hash = temp_slot_address_compute_hash (t); t->hash = temp_slot_address_compute_hash (t);
slot = htab_find_slot_with_hash (temp_slot_address_table, t, t->hash, INSERT); *temp_slot_address_table->find_slot_with_hash (t, t->hash, INSERT) = t;
*slot = t;
} }
/* Remove an address -> temp slot mapping entry if the temp slot is /* Remove an address -> temp slot mapping entry if the temp slot is
not in use anymore. Callback for remove_unused_temp_slot_addresses. */ not in use anymore. Callback for remove_unused_temp_slot_addresses. */
static int int
remove_unused_temp_slot_addresses_1 (void **slot, void *data ATTRIBUTE_UNUSED) remove_unused_temp_slot_addresses_1 (temp_slot_address_entry **slot, void *)
{ {
const struct temp_slot_address_entry *t; const struct temp_slot_address_entry *t = *slot;
t = (const struct temp_slot_address_entry *) *slot;
if (! t->temp_slot->in_use) if (! t->temp_slot->in_use)
htab_clear_slot (temp_slot_address_table, slot); temp_slot_address_table->clear_slot (slot);
return 1; return 1;
} }
@ -683,11 +682,10 @@ remove_unused_temp_slot_addresses (void)
{ {
/* Use quicker clearing if there aren't any active temp slots. */ /* Use quicker clearing if there aren't any active temp slots. */
if (n_temp_slots_in_use) if (n_temp_slots_in_use)
htab_traverse (temp_slot_address_table, temp_slot_address_table->traverse
remove_unused_temp_slot_addresses_1, <void *, remove_unused_temp_slot_addresses_1> (NULL);
NULL);
else else
htab_empty (temp_slot_address_table); temp_slot_address_table->empty ();
} }
/* Find the temp slot corresponding to the object at address X. */ /* Find the temp slot corresponding to the object at address X. */
@ -703,8 +701,7 @@ find_temp_slot_from_address (rtx x)
tmp.address = x; tmp.address = x;
tmp.temp_slot = NULL; tmp.temp_slot = NULL;
tmp.hash = temp_slot_address_compute_hash (&tmp); tmp.hash = temp_slot_address_compute_hash (&tmp);
t = (struct temp_slot_address_entry *) t = temp_slot_address_table->find_with_hash (&tmp, tmp.hash);
htab_find_with_hash (temp_slot_address_table, &tmp, tmp.hash);
if (t) if (t)
return t->temp_slot; return t->temp_slot;
@ -1195,12 +1192,9 @@ init_temp_slots (void)
/* Set up the table to map addresses to temp slots. */ /* Set up the table to map addresses to temp slots. */
if (! temp_slot_address_table) if (! temp_slot_address_table)
temp_slot_address_table = htab_create_ggc (32, temp_slot_address_table = hash_table<temp_address_hasher>::create_ggc (32);
temp_slot_address_hash,
temp_slot_address_eq,
NULL);
else else
htab_empty (temp_slot_address_table); temp_slot_address_table->empty ();
} }
/* Functions and data structures to keep track of the values hard regs /* Functions and data structures to keep track of the values hard regs
@ -6145,24 +6139,17 @@ hash_types_used_by_vars_entry (const struct types_used_by_vars_entry *entry)
/* Hash function of the types_used_by_vars_entry hash table. */ /* Hash function of the types_used_by_vars_entry hash table. */
hashval_t hashval_t
types_used_by_vars_do_hash (const void *x) used_type_hasher::hash (types_used_by_vars_entry *entry)
{ {
const struct types_used_by_vars_entry *entry =
(const struct types_used_by_vars_entry *) x;
return hash_types_used_by_vars_entry (entry); return hash_types_used_by_vars_entry (entry);
} }
/*Equality function of the types_used_by_vars_entry hash table. */ /*Equality function of the types_used_by_vars_entry hash table. */
int bool
types_used_by_vars_eq (const void *x1, const void *x2) used_type_hasher::equal (types_used_by_vars_entry *e1,
types_used_by_vars_entry *e2)
{ {
const struct types_used_by_vars_entry *e1 =
(const struct types_used_by_vars_entry *) x1;
const struct types_used_by_vars_entry *e2 =
(const struct types_used_by_vars_entry *)x2;
return (e1->var_decl == e2->var_decl && e1->type == e2->type); return (e1->var_decl == e2->var_decl && e1->type == e2->type);
} }
@ -6173,16 +6160,15 @@ types_used_by_var_decl_insert (tree type, tree var_decl)
{ {
if (type != NULL && var_decl != NULL) if (type != NULL && var_decl != NULL)
{ {
void **slot; types_used_by_vars_entry **slot;
struct types_used_by_vars_entry e; struct types_used_by_vars_entry e;
e.var_decl = var_decl; e.var_decl = var_decl;
e.type = type; e.type = type;
if (types_used_by_vars_hash == NULL) if (types_used_by_vars_hash == NULL)
types_used_by_vars_hash = types_used_by_vars_hash
htab_create_ggc (37, types_used_by_vars_do_hash, = hash_table<used_type_hasher>::create_ggc (37);
types_used_by_vars_eq, NULL);
slot = htab_find_slot_with_hash (types_used_by_vars_hash, &e, slot = types_used_by_vars_hash->find_slot (&e, INSERT);
hash_types_used_by_vars_entry (&e), INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
struct types_used_by_vars_entry *entry; struct types_used_by_vars_entry *entry;

View File

@ -703,21 +703,24 @@ extern int virtuals_instantiated;
/* Nonzero if at least one trampoline has been created. */ /* Nonzero if at least one trampoline has been created. */
extern int trampolines_created; extern int trampolines_created;
struct GTY(()) types_used_by_vars_entry { struct GTY((for_user)) types_used_by_vars_entry {
tree type; tree type;
tree var_decl; tree var_decl;
}; };
struct used_type_hasher : ggc_hasher<types_used_by_vars_entry *>
{
static hashval_t hash (types_used_by_vars_entry *);
static bool equal (types_used_by_vars_entry *, types_used_by_vars_entry *);
};
/* Hash table making the relationship between a global variable /* Hash table making the relationship between a global variable
and the types it references in its initializer. The key of the and the types it references in its initializer. The key of the
entry is a referenced type, and the value is the DECL of the global entry is a referenced type, and the value is the DECL of the global
variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are
the hash and equality functions to use for this hash table. */ the hash and equality functions to use for this hash table. */
extern GTY((param_is (struct types_used_by_vars_entry))) htab_t extern GTY(()) hash_table<used_type_hasher> *types_used_by_vars_hash;
types_used_by_vars_hash;
hashval_t types_used_by_vars_do_hash (const void*);
int types_used_by_vars_eq (const void *, const void *);
void types_used_by_var_decl_insert (tree type, tree var_decl); void types_used_by_var_decl_insert (tree type, tree var_decl);
/* During parsing of a global variable, this vector contains the types /* During parsing of a global variable, this vector contains the types

View File

@ -648,6 +648,12 @@ create_user_defined_type (const char *type_name, struct fileloc *pos)
if (is_ptr) if (is_ptr)
offset_to_star = star - type_id; offset_to_star = star - type_id;
if (strstr (type_id, "char*"))
{
type_id = strtoken (0, ",>", &next);
continue;
}
char *field_name = xstrdup (type_id); char *field_name = xstrdup (type_id);
type_p arg_type; type_p arg_type;
@ -2845,6 +2851,8 @@ walk_type (type_p t, struct walk_type_data *d)
; ;
else if (strcmp (oo->name, "variable_size") == 0) else if (strcmp (oo->name, "variable_size") == 0)
; ;
else if (strcmp (oo->name, "for_user") == 0)
;
else else
error_at_line (d->line, "unknown option `%s'\n", oo->name); error_at_line (d->line, "unknown option `%s'\n", oo->name);
@ -3642,7 +3650,6 @@ write_user_func_for_structure_body (type_p s, const char *prefix,
oprintf (d->of, "}\n"); oprintf (d->of, "}\n");
} }
/* Emit the user-callable functions needed to mark all the types used /* Emit the user-callable functions needed to mark all the types used
by the user structure S. PREFIX is the prefix to use to by the user structure S. PREFIX is the prefix to use to
distinguish ggc and pch markers. D contains data needed to pass to distinguish ggc and pch markers. D contains data needed to pass to
@ -3712,6 +3719,8 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
memset (&d, 0, sizeof (d)); memset (&d, 0, sizeof (d));
d.of = get_output_file_for_structure (s, param); d.of = get_output_file_for_structure (s, param);
bool for_user = false;
for (opt = s->u.s.opt; opt; opt = opt->next) for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "chain_next") == 0 if (strcmp (opt->name, "chain_next") == 0
&& opt->kind == OPTION_STRING) && opt->kind == OPTION_STRING)
@ -3725,6 +3734,8 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
else if (strcmp (opt->name, "mark_hook") == 0 else if (strcmp (opt->name, "mark_hook") == 0
&& opt->kind == OPTION_STRING) && opt->kind == OPTION_STRING)
mark_hook_name = opt->info.string; mark_hook_name = opt->info.string;
else if (strcmp (opt->name, "for_user") == 0)
for_user = true;
if (chain_prev != NULL && chain_next == NULL) if (chain_prev != NULL && chain_next == NULL)
error_at_line (&s->u.s.line, "chain_prev without chain_next"); error_at_line (&s->u.s.line, "chain_prev without chain_next");
if (chain_circular != NULL && chain_next != NULL) if (chain_circular != NULL && chain_next != NULL)
@ -3868,6 +3879,12 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
if (orig_s->kind == TYPE_USER_STRUCT) if (orig_s->kind == TYPE_USER_STRUCT)
write_user_marking_functions (orig_s, wtd, &d); write_user_marking_functions (orig_s, wtd, &d);
if (for_user)
{
write_user_func_for_structure_body (orig_s, wtd->prefix, &d);
write_user_func_for_structure_ptr (d.of, orig_s, wtd);
}
} }
@ -4244,6 +4261,13 @@ write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param)
/* Write user-callable entry points for the PCH walking routines. */ /* Write user-callable entry points for the PCH walking routines. */
if (orig_s->kind == TYPE_USER_STRUCT) if (orig_s->kind == TYPE_USER_STRUCT)
write_pch_user_walking_functions (s, &d); write_pch_user_walking_functions (s, &d);
for (options_p o = s->u.s.opt; o; o = o->next)
if (strcmp (o->name, "for_user") == 0)
{
write_pch_user_walking_for_structure_body (s, &d);
break;
}
} }
/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */ /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
@ -5690,6 +5714,19 @@ main (int argc, char **argv)
hence enlarge the param_structs list of types. */ hence enlarge the param_structs list of types. */
set_gc_used (variables); set_gc_used (variables);
for (type_p t = structures; t; t = t->next)
{
bool for_user = false;
for (options_p o = t->u.s.opt; o; o = o->next)
if (strcmp (o->name, "for_user") == 0)
{
for_user = true;
break;
}
if (for_user)
set_gc_used_type (t, GC_POINTED_TO, NULL);
}
/* The state at this point is read from the state input file or by /* The state at this point is read from the state input file or by
parsing source files and optionally augmented by parsing plugin parsing source files and optionally augmented by parsing plugin
source files. Write it now. */ source files. Write it now. */

View File

@ -358,4 +358,9 @@ gt_pch_nx (int)
{ {
} }
static inline void
gt_pch_nx (unsigned int)
{
}
#endif #endif

View File

@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_GIMPLE_SSA_H #define GCC_GIMPLE_SSA_H
#include "hash-map.h" #include "hash-map.h"
#include "tree-hasher.h"
#include "tree-ssa-operands.h" #include "tree-ssa-operands.h"
/* This structure is used to map a gimple statement to a label, /* This structure is used to map a gimple statement to a label,
@ -32,6 +33,25 @@ struct GTY(()) tm_restart_node {
tree label_or_list; tree label_or_list;
}; };
struct ssa_name_hasher : ggc_hasher<tree>
{
/* Hash a tree in a uid_decl_map. */
static hashval_t
hash (tree item)
{
return item->ssa_name.var->decl_minimal.uid;
}
/* Return true if the DECL_UID in both trees are equal. */
static bool
equal (tree a, tree b)
{
return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
}
};
/* Gimple dataflow datastructure. All publicly available fields shall have /* Gimple dataflow datastructure. All publicly available fields shall have
gimple_ accessor defined, all publicly modifiable fields should have gimple_ accessor defined, all publicly modifiable fields should have
gimple_set accessor. */ gimple_set accessor. */
@ -63,7 +83,7 @@ struct GTY(()) gimple_df {
means that the first reference to this variable in the function is a means that the first reference to this variable in the function is a
USE or a VUSE. In those cases, the SSA renamer creates an SSA name USE or a VUSE. In those cases, the SSA renamer creates an SSA name
for this variable with an empty defining statement. */ for this variable with an empty defining statement. */
htab_t GTY((param_is (union tree_node))) default_defs; hash_table<ssa_name_hasher> *default_defs;
/* True if there are any symbols that need to be renamed. */ /* True if there are any symbols that need to be renamed. */
unsigned int ssa_renaming_needed : 1; unsigned int ssa_renaming_needed : 1;

View File

@ -168,6 +168,16 @@ class GTY((user)) hash_map
{ {
} }
static void
pch_nx_helper (unsigned int, gt_pointer_operator, void *)
{
}
static void
pch_nx_helper (bool, gt_pointer_operator, void *)
{
}
template<typename T> template<typename T>
static void static void
pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie) pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie)

View File

@ -198,6 +198,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h" #include "ggc.h"
#include "hashtab.h" #include "hashtab.h"
#include <new>
template<typename, typename, typename> class hash_map; template<typename, typename, typename> class hash_map;
template<typename, typename> class hash_set; template<typename, typename> class hash_set;
@ -301,6 +302,38 @@ pointer_hash <Type>::equal (const value_type &existing,
return existing == candidate; return existing == candidate;
} }
/* Hasher for entry in gc memory. */
template<typename T>
struct ggc_hasher
{
typedef T value_type;
typedef T compare_type;
typedef int store_values_directly;
static void remove (T) {}
static void
ggc_mx (T p)
{
extern void gt_ggc_mx (T &);
gt_ggc_mx (p);
}
static void
pch_nx (T &p)
{
extern void gt_pch_nx (T &);
gt_pch_nx (p);
}
static void
pch_nx (T &p, gt_pointer_operator op, void *cookie)
{
op (&p, cookie);
}
};
/* Table of primes and their inversion information. */ /* Table of primes and their inversion information. */
@ -1004,6 +1037,16 @@ public:
explicit hash_table (size_t, bool ggc = false); explicit hash_table (size_t, bool ggc = false);
~hash_table (); ~hash_table ();
/* Create a hash_table in gc memory. */
static hash_table *
create_ggc (size_t n)
{
hash_table *table = ggc_alloc<hash_table> ();
new (table) hash_table (n, true);
return table;
}
/* Current size (in entries) of the hash table. */ /* Current size (in entries) of the hash table. */
size_t size () const { return m_size; } size_t size () const { return m_size; }
@ -1110,9 +1153,15 @@ public:
private: private:
template<typename T> friend void gt_ggc_mx (hash_table<T> *); template<typename T> friend void gt_ggc_mx (hash_table<T> *);
template<typename T> friend void gt_pch_nx (hash_table<T> *); template<typename T> friend void gt_pch_nx (hash_table<T> *);
template<typename T> friend void hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *); template<typename T> friend void
template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *); hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *, 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> friend void gt_pch_nx (hash_set<T, U> *,
gt_pointer_operator,
void *);
template<typename T> friend void gt_pch_nx (hash_table<T> *,
gt_pointer_operator, void *);
value_type *find_empty_slot_for_expand (hashval_t); value_type *find_empty_slot_for_expand (hashval_t);
void expand (); void expand ();
@ -1598,7 +1647,7 @@ template<typename D>
static void static void
gt_pch_nx (hash_table<D> *h) gt_pch_nx (hash_table<D> *h)
{ {
bool success ATTRIBUTE_UNUSED bool success
= gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>); = gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>);
gcc_checking_assert (success); gcc_checking_assert (success);
for (size_t i = 0; i < h->m_size; i++) for (size_t i = 0; i < h->m_size; i++)
@ -1611,4 +1660,11 @@ gt_pch_nx (hash_table<D> *h)
} }
} }
template<typename D>
static inline void
gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
{
op (&h->m_entries, cookie);
}
#endif /* TYPED_HASHTAB_H */ #endif /* TYPED_HASHTAB_H */

View File

@ -1,3 +1,8 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* class.c, decl.c, except.c, expr.c, java-tree.h, lang.c: Use
hash_table instead of hashtab.
2014-10-07 Marek Polacek <polacek@redhat.com> 2014-10-07 Marek Polacek <polacek@redhat.com>
* jvgenmain.c (main): Provide declarations for JvRunMain{,Name}. * jvgenmain.c (main): Provide declarations for JvRunMain{,Name}.

View File

@ -774,7 +774,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
/* Initialize the initialized (static) class table. */ /* Initialize the initialized (static) class table. */
if (access_flags & ACC_STATIC) if (access_flags & ACC_STATIC)
DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) = DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
htab_create_ggc (50, htab_hash_pointer, htab_eq_pointer, NULL); hash_table<ict_hasher>::create_ggc (50);
DECL_CHAIN (fndecl) = TYPE_METHODS (this_class); DECL_CHAIN (fndecl) = TYPE_METHODS (this_class);
TYPE_METHODS (this_class) = fndecl; TYPE_METHODS (this_class) = fndecl;
@ -3070,14 +3070,12 @@ build_assertion_table_entry (tree code, tree op1, tree op2)
/* Add an entry to the type assertion table. Callback used during hashtable /* Add an entry to the type assertion table. Callback used during hashtable
traversal. */ traversal. */
static int int
add_assertion_table_entry (void **htab_entry, void *ptr) add_assertion_table_entry (type_assertion **slot, vec<constructor_elt, va_gc> **v)
{ {
tree entry; tree entry;
tree code_val, op1_utf8, op2_utf8; tree code_val, op1_utf8, op2_utf8;
vec<constructor_elt, va_gc> **v type_assertion *as = *slot;
= ((vec<constructor_elt, va_gc> **) ptr);
type_assertion *as = (type_assertion *) *htab_entry;
code_val = build_int_cst (NULL_TREE, as->assertion_code); code_val = build_int_cst (NULL_TREE, as->assertion_code);
@ -3103,11 +3101,12 @@ static tree
emit_assertion_table (tree klass) emit_assertion_table (tree klass)
{ {
tree null_entry, ctor, table_decl; tree null_entry, ctor, table_decl;
htab_t assertions_htab = TYPE_ASSERTIONS (klass); hash_table<type_assertion_hasher> *assertions_htab = TYPE_ASSERTIONS (klass);
vec<constructor_elt, va_gc> *v = NULL; vec<constructor_elt, va_gc> *v = NULL;
/* Iterate through the hash table. */ /* Iterate through the hash table. */
htab_traverse (assertions_htab, add_assertion_table_entry, &v); assertions_htab
->traverse<vec<constructor_elt, va_gc> **, add_assertion_table_entry> (&v);
/* Finish with a null entry. */ /* Finish with a null entry. */
null_entry = build_assertion_table_entry (integer_zero_node, null_entry = build_assertion_table_entry (integer_zero_node,
@ -3146,36 +3145,28 @@ init_class_processing (void)
gcc_obstack_init (&temporary_obstack); gcc_obstack_init (&temporary_obstack);
} }
static hashval_t java_treetreehash_hash (const void *);
static int java_treetreehash_compare (const void *, const void *);
/* A hash table mapping trees to trees. Used generally. */ /* A hash table mapping trees to trees. Used generally. */
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t)) #define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
static hashval_t hashval_t
java_treetreehash_hash (const void *k_p) treetreehasher::hash (treetreehash_entry *k)
{ {
const struct treetreehash_entry *const k
= (const struct treetreehash_entry *) k_p;
return JAVA_TREEHASHHASH_H (k->key); return JAVA_TREEHASHHASH_H (k->key);
} }
static int bool
java_treetreehash_compare (const void * k1_p, const void * k2_p) treetreehasher::equal (treetreehash_entry *k1, tree k2)
{ {
const struct treetreehash_entry *const k1
= (const struct treetreehash_entry *) k1_p;
const_tree const k2 = (const_tree) k2_p;
return (k1->key == k2); return (k1->key == k2);
} }
tree tree
java_treetreehash_find (htab_t ht, tree t) java_treetreehash_find (hash_table<treetreehasher> *ht, tree t)
{ {
struct treetreehash_entry *e; struct treetreehash_entry *e;
hashval_t hv = JAVA_TREEHASHHASH_H (t); hashval_t hv = JAVA_TREEHASHHASH_H (t);
e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv); e = ht->find_with_hash (t, hv);
if (e == NULL) if (e == NULL)
return NULL; return NULL;
else else
@ -3183,13 +3174,12 @@ java_treetreehash_find (htab_t ht, tree t)
} }
tree * tree *
java_treetreehash_new (htab_t ht, tree t) java_treetreehash_new (hash_table<treetreehasher> *ht, tree t)
{ {
void **e;
struct treetreehash_entry *tthe; struct treetreehash_entry *tthe;
hashval_t hv = JAVA_TREEHASHHASH_H (t); hashval_t hv = JAVA_TREEHASHHASH_H (t);
e = htab_find_slot_with_hash (ht, t, hv, INSERT); treetreehash_entry **e = ht->find_slot_with_hash (t, hv, INSERT);
if (*e == NULL) if (*e == NULL)
{ {
tthe = ggc_cleared_alloc<treetreehash_entry> (); tthe = ggc_cleared_alloc<treetreehash_entry> ();
@ -3197,15 +3187,14 @@ java_treetreehash_new (htab_t ht, tree t)
*e = tthe; *e = tthe;
} }
else else
tthe = (struct treetreehash_entry *) *e; tthe = *e;
return &tthe->value; return &tthe->value;
} }
htab_t hash_table<treetreehasher> *
java_treetreehash_create (size_t size) java_treetreehash_create (size_t size)
{ {
return htab_create_ggc (size, java_treetreehash_hash, return hash_table<treetreehasher>::create_ggc (size);
java_treetreehash_compare, NULL);
} }
/* Break down qualified IDENTIFIER into package and class-name components. /* Break down qualified IDENTIFIER into package and class-name components.

View File

@ -1846,8 +1846,8 @@ end_java_method (void)
variable to the block_body */ variable to the block_body */
fbody = DECL_SAVED_TREE (fndecl); fbody = DECL_SAVED_TREE (fndecl);
block_body = BIND_EXPR_BODY (fbody); block_body = BIND_EXPR_BODY (fbody);
htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fndecl), hash_table<treetreehasher> *ht = DECL_FUNCTION_INIT_TEST_TABLE (fndecl);
attach_init_test_initialization_flags, block_body); ht->traverse<tree, attach_init_test_initialization_flags> (block_body);
} }
finish_method (fndecl); finish_method (fndecl);

View File

@ -433,10 +433,10 @@ prepare_eh_table_type (tree type)
return exp; return exp;
} }
static int int
expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED) expand_catch_class (treetreehash_entry **entry, int)
{ {
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry; struct treetreehash_entry *ite = *entry;
tree addr = TREE_VALUE ((tree)ite->value); tree addr = TREE_VALUE ((tree)ite->value);
tree decl; tree decl;
STRIP_NOPS (addr); STRIP_NOPS (addr);
@ -452,9 +452,7 @@ void
java_expand_catch_classes (tree this_class) java_expand_catch_classes (tree this_class)
{ {
if (TYPE_TO_RUNTIME_MAP (this_class)) if (TYPE_TO_RUNTIME_MAP (this_class))
htab_traverse TYPE_TO_RUNTIME_MAP (this_class)->traverse<int, expand_catch_class> (0);
(TYPE_TO_RUNTIME_MAP (this_class),
expand_catch_class, NULL);
} }
/* Build and push the variable that will hold the exception object /* Build and push the variable that will hold the exception object

View File

@ -398,22 +398,19 @@ pop_type (tree type)
/* Return true if two type assertions are equal. */ /* Return true if two type assertions are equal. */
static int bool
type_assertion_eq (const void * k1_p, const void * k2_p) type_assertion_hasher::equal (type_assertion *k1, type_assertion *k2)
{ {
const type_assertion k1 = *(const type_assertion *)k1_p; return (k1->assertion_code == k2->assertion_code
const type_assertion k2 = *(const type_assertion *)k2_p; && k1->op1 == k2->op1
return (k1.assertion_code == k2.assertion_code && k1->op2 == k2->op2);
&& k1.op1 == k2.op1
&& k1.op2 == k2.op2);
} }
/* Hash a type assertion. */ /* Hash a type assertion. */
static hashval_t hashval_t
type_assertion_hash (const void *p) type_assertion_hasher::hash (type_assertion *k_p)
{ {
const type_assertion *k_p = (const type_assertion *) p;
hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
k_p->assertion_code, 0); k_p->assertion_code, 0);
@ -449,15 +446,14 @@ type_assertion_hash (const void *p)
void void
add_type_assertion (tree klass, int assertion_code, tree op1, tree op2) add_type_assertion (tree klass, int assertion_code, tree op1, tree op2)
{ {
htab_t assertions_htab; hash_table<type_assertion_hasher> *assertions_htab;
type_assertion as; type_assertion as;
void **as_pp; type_assertion **as_pp;
assertions_htab = TYPE_ASSERTIONS (klass); assertions_htab = TYPE_ASSERTIONS (klass);
if (assertions_htab == NULL) if (assertions_htab == NULL)
{ {
assertions_htab = htab_create_ggc (7, type_assertion_hash, assertions_htab = hash_table<type_assertion_hasher>::create_ggc (7);
type_assertion_eq, NULL);
TYPE_ASSERTIONS (current_class) = assertions_htab; TYPE_ASSERTIONS (current_class) = assertions_htab;
} }
@ -465,14 +461,14 @@ add_type_assertion (tree klass, int assertion_code, tree op1, tree op2)
as.op1 = op1; as.op1 = op1;
as.op2 = op2; as.op2 = op2;
as_pp = htab_find_slot (assertions_htab, &as, INSERT); as_pp = assertions_htab->find_slot (&as, INSERT);
/* Don't add the same assertion twice. */ /* Don't add the same assertion twice. */
if (*as_pp) if (*as_pp)
return; return;
*as_pp = ggc_alloc<type_assertion> (); *as_pp = ggc_alloc<type_assertion> ();
**(type_assertion **)as_pp = as; **as_pp = as;
} }
@ -1946,10 +1942,9 @@ pop_arguments (tree method_type)
/* Attach to PTR (a block) the declaration found in ENTRY. */ /* Attach to PTR (a block) the declaration found in ENTRY. */
int int
attach_init_test_initialization_flags (void **entry, void *ptr) attach_init_test_initialization_flags (treetreehash_entry **slot, tree block)
{ {
tree block = (tree)ptr; treetreehash_entry *ite = *slot;
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
if (block != error_mark_node) if (block != error_mark_node)
{ {

View File

@ -710,6 +710,25 @@ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
&& TREE_CODE (TREE_TYPE (NODE)) != POINTER_TYPE) \ && TREE_CODE (TREE_TYPE (NODE)) != POINTER_TYPE) \
|| TREE_CODE (NODE) == REAL_CST) || TREE_CODE (NODE) == REAL_CST)
struct GTY((for_user)) treetreehash_entry {
tree key;
tree value;
};
struct treetreehasher : ggc_hasher<treetreehash_entry *>
{
typedef tree compare_type;
static hashval_t hash (treetreehash_entry *);
static bool equal (treetreehash_entry *, tree);
};
struct ict_hasher : ggc_hasher<tree_node *>
{
static hashval_t hash (tree t) { return htab_hash_pointer (t); }
static bool equal (tree a, tree b) { return a == b; }
};
/* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */ /* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */
struct GTY(()) lang_decl_func { struct GTY(()) lang_decl_func {
/* tree chain; not yet used. */ /* tree chain; not yet used. */
@ -726,10 +745,10 @@ struct GTY(()) lang_decl_func {
tree exc_obj; /* Decl holding the exception object. */ tree exc_obj; /* Decl holding the exception object. */
/* Class initialization test variables */ /* Class initialization test variables */
htab_t GTY ((param_is (struct treetreehash_entry))) init_test_table; hash_table<treetreehasher> *init_test_table;
/* Initialized (static) Class Table */ /* Initialized (static) Class Table */
htab_t GTY ((param_is (union tree_node))) ict; hash_table<ict_hasher> *ict;
unsigned int native : 1; /* Nonzero if this is a native method */ unsigned int native : 1; /* Nonzero if this is a native method */
unsigned int strictfp : 1; unsigned int strictfp : 1;
@ -742,11 +761,6 @@ struct GTY(()) lang_decl_func {
unsigned int varargs : 1; /* Varargs method. */ unsigned int varargs : 1; /* Varargs method. */
}; };
struct GTY(()) treetreehash_entry {
tree key;
tree value;
};
/* These represent the possible assertion_codes that can be emitted in the /* These represent the possible assertion_codes that can be emitted in the
type assertion table. */ type assertion table. */
enum enum
@ -778,15 +792,21 @@ typedef enum
JV_ANNOTATION_DEFAULT_KIND JV_ANNOTATION_DEFAULT_KIND
} jv_attr_kind; } jv_attr_kind;
typedef struct GTY(()) type_assertion { typedef struct GTY((for_user)) type_assertion {
int assertion_code; /* 'opcode' for the type of this assertion. */ int assertion_code; /* 'opcode' for the type of this assertion. */
tree op1; /* First operand. */ tree op1; /* First operand. */
tree op2; /* Second operand. */ tree op2; /* Second operand. */
} type_assertion; } type_assertion;
extern tree java_treetreehash_find (htab_t, tree); struct type_assertion_hasher : ggc_hasher<type_assertion *>
extern tree * java_treetreehash_new (htab_t, tree); {
extern htab_t java_treetreehash_create (size_t size); static hashval_t hash (type_assertion *);
static bool equal (type_assertion *, type_assertion *);
};
extern tree java_treetreehash_find (hash_table<treetreehasher> *, tree);
extern tree * java_treetreehash_new (hash_table<treetreehasher> *, tree);
extern hash_table<treetreehasher> *java_treetreehash_create (size_t size);
/* DECL_LANG_SPECIFIC for VAR_DECL, PARM_DECL and sometimes FIELD_DECL /* DECL_LANG_SPECIFIC for VAR_DECL, PARM_DECL and sometimes FIELD_DECL
(access methods on outer class fields) and final fields. */ (access methods on outer class fields) and final fields. */
@ -893,11 +913,11 @@ struct GTY(()) lang_type {
type matcher. */ type matcher. */
vec<constructor_elt, va_gc> *catch_classes; vec<constructor_elt, va_gc> *catch_classes;
htab_t GTY ((param_is (struct treetreehash_entry))) type_to_runtime_map; hash_table<treetreehasher> *type_to_runtime_map;
/* The mapping of classes to exception region /* The mapping of classes to exception region
markers. */ markers. */
htab_t GTY ((param_is (struct type_assertion))) type_assertions; hash_table<type_assertion_hasher> *type_assertions;
/* Table of type assertions to be evaluated /* Table of type assertions to be evaluated
by the runtime when this class is loaded. */ by the runtime when this class is loaded. */
@ -1013,7 +1033,7 @@ extern void maybe_rewrite_invocation (tree *, vec<tree, va_gc> **, tree *,
extern tree build_known_method_ref (tree, tree, tree, tree, vec<tree, va_gc> *, extern tree build_known_method_ref (tree, tree, tree, tree, vec<tree, va_gc> *,
tree); tree);
extern tree build_class_init (tree, tree); extern tree build_class_init (tree, tree);
extern int attach_init_test_initialization_flags (void **, void *); extern int attach_init_test_initialization_flags (treetreehash_entry **, tree);
extern tree build_invokevirtual (tree, tree, tree); extern tree build_invokevirtual (tree, tree, tree);
extern tree build_invokeinterface (tree, tree); extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree); extern tree build_jni_stub (tree);

View File

@ -57,8 +57,6 @@ static void put_decl_string (const char *, int);
static void put_decl_node (tree, int); static void put_decl_node (tree, int);
static void java_print_error_function (diagnostic_context *, const char *, static void java_print_error_function (diagnostic_context *, const char *,
diagnostic_info *); diagnostic_info *);
static int merge_init_test_initialization (void * *, void *);
static int inline_init_test_initialization (void * *, void *);
static bool java_dump_tree (void *, tree); static bool java_dump_tree (void *, tree);
static void dump_compound_expr (dump_info_p, tree); static void dump_compound_expr (dump_info_p, tree);
static bool java_decl_ok_for_sibcall (const_tree); static bool java_decl_ok_for_sibcall (const_tree);
@ -713,10 +711,10 @@ decl_constant_value (tree decl)
/* Create a mapping from a boolean variable in a method being inlined /* Create a mapping from a boolean variable in a method being inlined
to one in the scope of the method being inlined into. */ to one in the scope of the method being inlined into. */
static int int
merge_init_test_initialization (void **entry, void *x) merge_init_test_initialization (treetreehash_entry **entry, void *x)
{ {
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry; struct treetreehash_entry *ite = *entry;
splay_tree decl_map = (splay_tree)x; splay_tree decl_map = (splay_tree)x;
splay_tree_node n; splay_tree_node n;
tree *init_test_decl; tree *init_test_decl;
@ -761,9 +759,8 @@ merge_init_test_initialization (void **entry, void *x)
void void
java_inlining_merge_static_initializers (tree fn, void *decl_map) java_inlining_merge_static_initializers (tree fn, void *decl_map)
{ {
htab_traverse DECL_FUNCTION_INIT_TEST_TABLE (fn)
(DECL_FUNCTION_INIT_TEST_TABLE (fn), ->traverse<void *, merge_init_test_initialization> (decl_map);
merge_init_test_initialization, decl_map);
} }
/* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're /* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
@ -772,10 +769,10 @@ java_inlining_merge_static_initializers (tree fn, void *decl_map)
from the variable in the inlined class to the corresponding from the variable in the inlined class to the corresponding
pre-existing one. */ pre-existing one. */
static int int
inline_init_test_initialization (void **entry, void *x) inline_init_test_initialization (treetreehash_entry **entry, void *x)
{ {
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry; struct treetreehash_entry *ite = *entry;
splay_tree decl_map = (splay_tree)x; splay_tree decl_map = (splay_tree)x;
tree h = java_treetreehash_find tree h = java_treetreehash_find
@ -796,9 +793,8 @@ inline_init_test_initialization (void **entry, void *x)
void void
java_inlining_map_static_initializers (tree fn, void *decl_map) java_inlining_map_static_initializers (tree fn, void *decl_map)
{ {
htab_traverse DECL_FUNCTION_INIT_TEST_TABLE (fn)
(DECL_FUNCTION_INIT_TEST_TABLE (fn), ->traverse<void *, inline_init_test_initialization> (decl_map);
inline_init_test_initialization, decl_map);
} }
/* Avoid voluminous output for deep recursion of compound exprs. */ /* Avoid voluminous output for deep recursion of compound exprs. */

View File

@ -55,11 +55,19 @@ enum libfunc_index
We use the same hashtable for normal optabs and conversion optabs. In We use the same hashtable for normal optabs and conversion optabs. In
the first case mode2 is forced to VOIDmode. */ the first case mode2 is forced to VOIDmode. */
struct GTY(()) libfunc_entry { struct GTY((for_user)) libfunc_entry {
int op, mode1, mode2; int op, mode1, mode2;
rtx libfunc; rtx libfunc;
}; };
/* Descriptor for libfunc_entry. */
struct libfunc_hasher : ggc_hasher<libfunc_entry *>
{
static hashval_t hash (libfunc_entry *);
static bool equal (libfunc_entry *, libfunc_entry *);
};
/* Target-dependent globals. */ /* Target-dependent globals. */
struct GTY(()) target_libfuncs { struct GTY(()) target_libfuncs {
/* SYMBOL_REF rtx's for the library functions that are called /* SYMBOL_REF rtx's for the library functions that are called
@ -67,7 +75,7 @@ struct GTY(()) target_libfuncs {
rtx x_libfunc_table[LTI_MAX]; rtx x_libfunc_table[LTI_MAX];
/* Hash table used to convert declarations into nodes. */ /* Hash table used to convert declarations into nodes. */
htab_t GTY((param_is (struct libfunc_entry))) x_libfunc_hash; hash_table<libfunc_hasher> *GTY(()) x_libfunc_hash;
}; };
extern GTY(()) struct target_libfuncs default_target_libfuncs; extern GTY(()) struct target_libfuncs default_target_libfuncs;

View File

@ -1,3 +1,7 @@
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* objc-act.c: use hash_table instead of hashtab.
2014-09-15 Jakub Jelinek <jakub@redhat.com> 2014-09-15 Jakub Jelinek <jakub@redhat.com>
* Make-lang.in (check_objc_parallelize): Change to just an upper * Make-lang.in (check_objc_parallelize): Change to just an upper

View File

@ -253,7 +253,7 @@ vec<tree, va_gc> *local_variables_to_volatilize = NULL;
/* Store all constructed constant strings in a hash table so that /* Store all constructed constant strings in a hash table so that
they get uniqued properly. */ they get uniqued properly. */
struct GTY(()) string_descriptor { struct GTY((for_user)) string_descriptor {
/* The literal argument . */ /* The literal argument . */
tree literal; tree literal;
@ -261,7 +261,13 @@ struct GTY(()) string_descriptor {
tree constructor; tree constructor;
}; };
static GTY((param_is (struct string_descriptor))) htab_t string_htab; struct objc_string_hasher : ggc_hasher<string_descriptor *>
{
static hashval_t hash (string_descriptor *);
static bool equal (string_descriptor *, string_descriptor *);
};
static GTY(()) hash_table<objc_string_hasher> *string_htab;
FILE *gen_declaration_file; FILE *gen_declaration_file;
@ -3107,10 +3113,10 @@ my_build_string_pointer (int len, const char *str)
return build1 (ADDR_EXPR, ptrtype, string); return build1 (ADDR_EXPR, ptrtype, string);
} }
static hashval_t hashval_t
string_hash (const void *ptr) objc_string_hasher::hash (string_descriptor *ptr)
{ {
const_tree const str = ((const struct string_descriptor *)ptr)->literal; const_tree const str = ptr->literal;
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str); const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
int i, len = TREE_STRING_LENGTH (str); int i, len = TREE_STRING_LENGTH (str);
hashval_t h = len; hashval_t h = len;
@ -3121,11 +3127,11 @@ string_hash (const void *ptr)
return h; return h;
} }
static int bool
string_eq (const void *ptr1, const void *ptr2) objc_string_hasher::equal (string_descriptor *ptr1, string_descriptor *ptr2)
{ {
const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal; const_tree const str1 = ptr1->literal;
const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal; const_tree const str2 = ptr2->literal;
int len1 = TREE_STRING_LENGTH (str1); int len1 = TREE_STRING_LENGTH (str1);
return (len1 == TREE_STRING_LENGTH (str2) return (len1 == TREE_STRING_LENGTH (str2)
@ -3147,7 +3153,6 @@ objc_build_string_object (tree string)
int length; int length;
tree addr; tree addr;
struct string_descriptor *desc, key; struct string_descriptor *desc, key;
void **loc;
/* We should be passed a STRING_CST. */ /* We should be passed a STRING_CST. */
gcc_checking_assert (TREE_CODE (string) == STRING_CST); gcc_checking_assert (TREE_CODE (string) == STRING_CST);
@ -3198,8 +3203,8 @@ objc_build_string_object (tree string)
/* Perhaps we already constructed a constant string just like this one? */ /* Perhaps we already constructed a constant string just like this one? */
key.literal = string; key.literal = string;
loc = htab_find_slot (string_htab, &key, INSERT); string_descriptor **loc = string_htab->find_slot (&key, INSERT);
desc = (struct string_descriptor *) *loc; desc = *loc;
if (!desc) if (!desc)
{ {
@ -5776,8 +5781,7 @@ hash_init (void)
alias_name_map = objc_map_alloc_ggc (200); alias_name_map = objc_map_alloc_ggc (200);
/* Initialize the hash table used to hold the constant string objects. */ /* Initialize the hash table used to hold the constant string objects. */
string_htab = htab_create_ggc (31, string_hash, string_htab = hash_table<objc_string_hasher>::create_ggc (31);
string_eq, NULL);
} }
/* Use the following to add a method to class_method_map or /* Use the following to add a method to class_method_map or

View File

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "insn-config.h" #include "insn-config.h"
#include "rtl.h" #include "rtl.h"
#include "tree.h" #include "tree.h"
#include "tree-hasher.h"
#include "stor-layout.h" #include "stor-layout.h"
#include "stringpool.h" #include "stringpool.h"
#include "varasm.h" #include "varasm.h"
@ -73,20 +74,17 @@ void debug_optab_libfuncs (void);
/* Used for libfunc_hash. */ /* Used for libfunc_hash. */
static hashval_t hashval_t
hash_libfunc (const void *p) libfunc_hasher::hash (libfunc_entry *e)
{ {
const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op); return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
} }
/* Used for libfunc_hash. */ /* Used for libfunc_hash. */
static int bool
eq_libfunc (const void *p, const void *q) libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2)
{ {
const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2; return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
} }
@ -109,8 +107,7 @@ convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
e.op = optab; e.op = optab;
e.mode1 = mode1; e.mode1 = mode1;
e.mode2 = mode2; e.mode2 = mode2;
slot = (struct libfunc_entry **) slot = libfunc_hash->find_slot (&e, NO_INSERT);
htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot) if (!slot)
{ {
const struct convert_optab_libcall_d *d const struct convert_optab_libcall_d *d
@ -120,8 +117,7 @@ convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
return NULL; return NULL;
d->libcall_gen (optab, d->libcall_basename, mode1, mode2); d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
slot = (struct libfunc_entry **) slot = libfunc_hash->find_slot (&e, NO_INSERT);
htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot) if (!slot)
return NULL; return NULL;
} }
@ -146,8 +142,7 @@ optab_libfunc (optab optab, enum machine_mode mode)
e.op = optab; e.op = optab;
e.mode1 = mode; e.mode1 = mode;
e.mode2 = VOIDmode; e.mode2 = VOIDmode;
slot = (struct libfunc_entry **) slot = libfunc_hash->find_slot (&e, NO_INSERT);
htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot) if (!slot)
{ {
const struct optab_libcall_d *d const struct optab_libcall_d *d
@ -157,8 +152,7 @@ optab_libfunc (optab optab, enum machine_mode mode)
return NULL; return NULL;
d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode); d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
slot = (struct libfunc_entry **) slot = libfunc_hash->find_slot (&e, NO_INSERT);
htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot) if (!slot)
return NULL; return NULL;
} }
@ -6100,22 +6094,25 @@ gen_satfractuns_conv_libfunc (convert_optab tab,
gen_interclass_conv_libfunc (tab, opname, tmode, fmode); gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
} }
/* A table of previously-created libfuncs, hashed by name. */
static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
/* Hashtable callbacks for libfunc_decls. */ /* Hashtable callbacks for libfunc_decls. */
static hashval_t struct libfunc_decl_hasher : ggc_hasher<tree>
libfunc_decl_hash (const void *entry)
{ {
return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry)); static hashval_t
} hash (tree entry)
{
return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
}
static int static bool
libfunc_decl_eq (const void *entry1, const void *entry2) equal (tree decl, tree name)
{ {
return DECL_NAME ((const_tree) entry1) == (const_tree) entry2; return DECL_NAME (decl) == name;
} }
};
/* A table of previously-created libfuncs, hashed by name. */
static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
/* Build a decl for a libfunc named NAME. */ /* Build a decl for a libfunc named NAME. */
@ -6143,18 +6140,16 @@ rtx
init_one_libfunc (const char *name) init_one_libfunc (const char *name)
{ {
tree id, decl; tree id, decl;
void **slot;
hashval_t hash; hashval_t hash;
if (libfunc_decls == NULL) if (libfunc_decls == NULL)
libfunc_decls = htab_create_ggc (37, libfunc_decl_hash, libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
libfunc_decl_eq, NULL);
/* See if we have already created a libfunc decl for this function. */ /* See if we have already created a libfunc decl for this function. */
id = get_identifier (name); id = get_identifier (name);
hash = IDENTIFIER_HASH_VALUE (id); hash = IDENTIFIER_HASH_VALUE (id);
slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT); tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
decl = (tree) *slot; decl = *slot;
if (decl == NULL) if (decl == NULL)
{ {
/* Create a new decl, so that it can be passed to /* Create a new decl, so that it can be passed to
@ -6171,12 +6166,11 @@ rtx
set_user_assembler_libfunc (const char *name, const char *asmspec) set_user_assembler_libfunc (const char *name, const char *asmspec)
{ {
tree id, decl; tree id, decl;
void **slot;
hashval_t hash; hashval_t hash;
id = get_identifier (name); id = get_identifier (name);
hash = IDENTIFIER_HASH_VALUE (id); hash = IDENTIFIER_HASH_VALUE (id);
slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT); tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
gcc_assert (slot); gcc_assert (slot);
decl = (tree) *slot; decl = (tree) *slot;
set_user_assembler_name (decl, asmspec); set_user_assembler_name (decl, asmspec);
@ -6200,7 +6194,7 @@ set_optab_libfunc (optab op, enum machine_mode mode, const char *name)
val = init_one_libfunc (name); val = init_one_libfunc (name);
else else
val = 0; val = 0;
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT); slot = libfunc_hash->find_slot (&e, INSERT);
if (*slot == NULL) if (*slot == NULL)
*slot = ggc_alloc<libfunc_entry> (); *slot = ggc_alloc<libfunc_entry> ();
(*slot)->op = op; (*slot)->op = op;
@ -6228,7 +6222,7 @@ set_conv_libfunc (convert_optab optab, enum machine_mode tmode,
val = init_one_libfunc (name); val = init_one_libfunc (name);
else else
val = 0; val = 0;
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT); slot = libfunc_hash->find_slot (&e, INSERT);
if (*slot == NULL) if (*slot == NULL)
*slot = ggc_alloc<libfunc_entry> (); *slot = ggc_alloc<libfunc_entry> ();
(*slot)->op = optab; (*slot)->op = optab;
@ -6244,9 +6238,9 @@ void
init_optabs (void) init_optabs (void)
{ {
if (libfunc_hash) if (libfunc_hash)
htab_empty (libfunc_hash); libfunc_hash->empty ();
else else
libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
/* Fill in the optabs with the insns we support. */ /* Fill in the optabs with the insns we support. */
init_all_optabs (this_fn_optabs); init_all_optabs (this_fn_optabs);

View File

@ -486,7 +486,7 @@ struct GTY(()) noswitch_section {
}; };
/* Information about a section, which may be named or unnamed. */ /* Information about a section, which may be named or unnamed. */
union GTY ((desc ("SECTION_STYLE (&(%h))"))) section { union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
struct section_common GTY ((skip)) common; struct section_common GTY ((skip)) common;
struct named_section GTY ((tag ("SECTION_NAMED"))) named; struct named_section GTY ((tag ("SECTION_NAMED"))) named;
struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed; struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed;

View File

@ -224,7 +224,7 @@ struct GTY(()) block_symbol {
/* Describes a group of objects that are to be placed together in such /* Describes a group of objects that are to be placed together in such
a way that their relative positions are known. */ a way that their relative positions are known. */
struct GTY(()) object_block { struct GTY((for_user)) object_block {
/* The section in which these objects should be placed. */ /* The section in which these objects should be placed. */
section *sect; section *sect;

View File

@ -618,9 +618,9 @@ if_region_set_false_region (ifsese if_region, sese region)
edge exit_region = SESE_EXIT (region); edge exit_region = SESE_EXIT (region);
basic_block before_region = entry_region->src; basic_block before_region = entry_region->src;
basic_block last_in_region = exit_region->src; basic_block last_in_region = exit_region->src;
void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region, hashval_t hash = htab_hash_pointer (exit_region);
htab_hash_pointer (exit_region), loop_exit **slot
NO_INSERT); = current_loops->exits->find_slot_with_hash (exit_region, hash, NO_INSERT);
entry_region->flags = false_edge->flags; entry_region->flags = false_edge->flags;
false_edge->flags = exit_region->flags; false_edge->flags = exit_region->flags;
@ -644,11 +644,11 @@ if_region_set_false_region (ifsese if_region, sese region)
struct loop_exit *loop_exit = ggc_cleared_alloc<struct loop_exit> (); struct loop_exit *loop_exit = ggc_cleared_alloc<struct loop_exit> ();
memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit)); memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit));
htab_clear_slot (current_loops->exits, slot); current_loops->exits->clear_slot (slot);
slot = htab_find_slot_with_hash (current_loops->exits, false_edge, hashval_t hash = htab_hash_pointer (false_edge);
htab_hash_pointer (false_edge), slot = current_loops->exits->find_slot_with_hash (false_edge, hash,
INSERT); INSERT);
loop_exit->e = false_edge; loop_exit->e = false_edge;
*slot = loop_exit; *slot = loop_exit;
false_edge->src->loop_father->exits->next = loop_exit; false_edge->src->loop_father->exits->next = loop_exit;

View File

@ -83,15 +83,6 @@ symbol_table::decl_assembler_name_hash (const_tree asmname)
} }
/* Returns a hash code for P. */
hashval_t
symbol_table::hash_node_by_assembler_name (const void *p)
{
const symtab_node *n = (const symtab_node *) p;
return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
}
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */ /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
bool bool
@ -150,14 +141,6 @@ symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
/* Returns nonzero if P1 and P2 are equal. */ /* Returns nonzero if P1 and P2 are equal. */
int
symbol_table::eq_assembler_name (const void *p1, const void *p2)
{
const symtab_node *n1 = (const symtab_node *) p1;
const_tree name = (const_tree)p2;
return (decl_assembler_name_equal (n1->decl, name));
}
/* Insert NODE to assembler name hash. */ /* Insert NODE to assembler name hash. */
void void
@ -170,19 +153,18 @@ symbol_table::insert_to_assembler_name_hash (symtab_node *node,
&& !node->next_sharing_asm_name); && !node->next_sharing_asm_name);
if (assembler_name_hash) if (assembler_name_hash)
{ {
void **aslot; symtab_node **aslot;
cgraph_node *cnode; cgraph_node *cnode;
tree decl = node->decl; tree decl = node->decl;
tree name = DECL_ASSEMBLER_NAME (node->decl); tree name = DECL_ASSEMBLER_NAME (node->decl);
aslot = htab_find_slot_with_hash (assembler_name_hash, name, hashval_t hash = decl_assembler_name_hash (name);
decl_assembler_name_hash (name), aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
INSERT);
gcc_assert (*aslot != node); gcc_assert (*aslot != node);
node->next_sharing_asm_name = (symtab_node *)*aslot; node->next_sharing_asm_name = (symtab_node *)*aslot;
if (*aslot != NULL) if (*aslot != NULL)
((symtab_node *)*aslot)->previous_sharing_asm_name = node; (*aslot)->previous_sharing_asm_name = node;
*aslot = node; *aslot = node;
/* Update also possible inline clones sharing a decl. */ /* Update also possible inline clones sharing a decl. */
@ -217,13 +199,13 @@ symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
else else
{ {
tree name = DECL_ASSEMBLER_NAME (node->decl); tree name = DECL_ASSEMBLER_NAME (node->decl);
void **slot; symtab_node **slot;
slot = htab_find_slot_with_hash (assembler_name_hash, name, hashval_t hash = decl_assembler_name_hash (name);
decl_assembler_name_hash (name), slot = assembler_name_hash->find_slot_with_hash (name, hash,
NO_INSERT); NO_INSERT);
gcc_assert (*slot == node); gcc_assert (*slot == node);
if (!node->next_sharing_asm_name) if (!node->next_sharing_asm_name)
htab_clear_slot (assembler_name_hash, slot); assembler_name_hash->clear_slot (slot);
else else
*slot = node->next_sharing_asm_name; *slot = node->next_sharing_asm_name;
} }
@ -256,9 +238,7 @@ symbol_table::symtab_initialize_asm_name_hash (void)
symtab_node *node; symtab_node *node;
if (!assembler_name_hash) if (!assembler_name_hash)
{ {
assembler_name_hash = assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
NULL);
FOR_EACH_SYMBOL (node) FOR_EACH_SYMBOL (node)
insert_to_assembler_name_hash (node, false); insert_to_assembler_name_hash (node, false);
} }
@ -322,20 +302,17 @@ resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
/* Hash sections by their names. */ /* Hash sections by their names. */
static hashval_t hashval_t
hash_section_hash_entry (const void *p) section_name_hasher::hash (section_hash_entry *n)
{ {
const section_hash_entry *n = (const section_hash_entry *) p;
return htab_hash_string (n->name); return htab_hash_string (n->name);
} }
/* Return true if section P1 name equals to P2. */ /* Return true if section P1 name equals to P2. */
static int bool
eq_sections (const void *p1, const void *p2) section_name_hasher::equal (section_hash_entry *n1, const char *name)
{ {
const section_hash_entry *n1 = (const section_hash_entry *) p1;
const char *name = (const char *)p2;
return n1->name == name || !strcmp (n1->name, name); return n1->name == name || !strcmp (n1->name, name);
} }
@ -936,16 +913,16 @@ symtab_node *
symtab_node::get_for_asmname (const_tree asmname) symtab_node::get_for_asmname (const_tree asmname)
{ {
symtab_node *node; symtab_node *node;
void **slot;
symtab->symtab_initialize_asm_name_hash (); symtab->symtab_initialize_asm_name_hash ();
slot = htab_find_slot_with_hash (symtab->assembler_name_hash, asmname, hashval_t hash = symtab->decl_assembler_name_hash (asmname);
symtab->decl_assembler_name_hash (asmname), symtab_node **slot
NO_INSERT); = symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
NO_INSERT);
if (slot) if (slot)
{ {
node = (symtab_node *) *slot; node = *slot;
return node; return node;
} }
return NULL; return NULL;
@ -1382,7 +1359,7 @@ void
symtab_node::set_section_for_node (const char *section) symtab_node::set_section_for_node (const char *section)
{ {
const char *current = get_section (); const char *current = get_section ();
void **slot; section_hash_entry **slot;
if (current == section if (current == section
|| (current && section || (current && section
@ -1394,11 +1371,11 @@ symtab_node::set_section_for_node (const char *section)
x_section->ref_count--; x_section->ref_count--;
if (!x_section->ref_count) if (!x_section->ref_count)
{ {
slot = htab_find_slot_with_hash (symtab->section_hash, x_section->name, hashval_t hash = htab_hash_string (x_section->name);
htab_hash_string (x_section->name), slot = symtab->section_hash->find_slot_with_hash (x_section->name,
INSERT); hash, INSERT);
ggc_free (x_section); ggc_free (x_section);
htab_clear_slot (symtab->section_hash, slot); symtab->section_hash->clear_slot (slot);
} }
x_section = NULL; x_section = NULL;
} }
@ -1408,11 +1385,10 @@ symtab_node::set_section_for_node (const char *section)
return; return;
} }
if (!symtab->section_hash) if (!symtab->section_hash)
symtab->section_hash = htab_create_ggc (10, hash_section_hash_entry, symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
eq_sections, NULL); slot = symtab->section_hash->find_slot_with_hash (section,
slot = htab_find_slot_with_hash (symtab->section_hash, section, htab_hash_string (section),
htab_hash_string (section), INSERT);
INSERT);
if (*slot) if (*slot)
x_section = (section_hash_entry *)*slot; x_section = (section_hash_entry *)*slot;
else else

View File

@ -6980,11 +6980,12 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
if (loops_for_fn (saved_cfun)->exits) if (loops_for_fn (saved_cfun)->exits)
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
{ {
void **slot = htab_find_slot_with_hash struct loops *l = loops_for_fn (saved_cfun);
(loops_for_fn (saved_cfun)->exits, e, loop_exit **slot
htab_hash_pointer (e), NO_INSERT); = l->exits->find_slot_with_hash (e, htab_hash_pointer (e),
NO_INSERT);
if (slot) if (slot)
htab_clear_slot (loops_for_fn (saved_cfun)->exits, slot); l->exits->clear_slot (slot);
} }
} }

View File

@ -322,7 +322,7 @@ ssa_default_def (struct function *fn, tree var)
|| TREE_CODE (var) == RESULT_DECL); || TREE_CODE (var) == RESULT_DECL);
in.var = (tree)&ind; in.var = (tree)&ind;
ind.uid = DECL_UID (var); ind.uid = DECL_UID (var);
return (tree) htab_find_with_hash (DEFAULT_DEFS (fn), &in, DECL_UID (var)); return DEFAULT_DEFS (fn)->find_with_hash ((tree)&in, DECL_UID (var));
} }
/* Insert the pair VAR's UID, DEF into the default_defs hashtable /* Insert the pair VAR's UID, DEF into the default_defs hashtable
@ -333,7 +333,6 @@ set_ssa_default_def (struct function *fn, tree var, tree def)
{ {
struct tree_decl_minimal ind; struct tree_decl_minimal ind;
struct tree_ssa_name in; struct tree_ssa_name in;
void **loc;
gcc_assert (TREE_CODE (var) == VAR_DECL gcc_assert (TREE_CODE (var) == VAR_DECL
|| TREE_CODE (var) == PARM_DECL || TREE_CODE (var) == PARM_DECL
@ -342,25 +341,26 @@ set_ssa_default_def (struct function *fn, tree var, tree def)
ind.uid = DECL_UID (var); ind.uid = DECL_UID (var);
if (!def) if (!def)
{ {
loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in, tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
DECL_UID (var), NO_INSERT); DECL_UID (var),
NO_INSERT);
if (loc) if (loc)
{ {
SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false; SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false;
htab_clear_slot (DEFAULT_DEFS (fn), loc); DEFAULT_DEFS (fn)->clear_slot (loc);
} }
return; return;
} }
gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var); gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var);
loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in, tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
DECL_UID (var), INSERT); DECL_UID (var), INSERT);
/* Default definition might be changed by tail call optimization. */ /* Default definition might be changed by tail call optimization. */
if (*loc) if (*loc)
SSA_NAME_IS_DEFAULT_DEF (*(tree *) loc) = false; SSA_NAME_IS_DEFAULT_DEF (*loc) = false;
/* Mark DEF as the default definition for VAR. */ /* Mark DEF as the default definition for VAR. */
*(tree *) loc = def; *loc = def;
SSA_NAME_IS_DEFAULT_DEF (def) = true; SSA_NAME_IS_DEFAULT_DEF (def) = true;
} }

View File

@ -1055,24 +1055,6 @@ err:
internal_error ("verify_ssa failed"); internal_error ("verify_ssa failed");
} }
/* Return true if the DECL_UID in both trees are equal. */
static int
uid_ssaname_map_eq (const void *va, const void *vb)
{
const_tree a = (const_tree) va;
const_tree b = (const_tree) vb;
return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
}
/* Hash a tree in a uid_decl_map. */
static unsigned int
uid_ssaname_map_hash (const void *item)
{
return ((const_tree)item)->ssa_name.var->decl_minimal.uid;
}
/* Initialize global DFA and SSA structures. */ /* Initialize global DFA and SSA structures. */
@ -1080,8 +1062,7 @@ void
init_tree_ssa (struct function *fn) init_tree_ssa (struct function *fn)
{ {
fn->gimple_df = ggc_cleared_alloc<gimple_df> (); fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash, fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
uid_ssaname_map_eq, NULL);
pt_solution_reset (&fn->gimple_df->escaped); pt_solution_reset (&fn->gimple_df->escaped);
init_ssanames (fn, 0); init_ssanames (fn, 0);
} }
@ -1153,7 +1134,7 @@ delete_tree_ssa (void)
if (ssa_operands_active (cfun)) if (ssa_operands_active (cfun))
fini_ssa_operands (cfun); fini_ssa_operands (cfun);
htab_delete (cfun->gimple_df->default_defs); cfun->gimple_df->default_defs->empty ();
cfun->gimple_df->default_defs = NULL; cfun->gimple_df->default_defs = NULL;
pt_solution_reset (&cfun->gimple_df->escaped); pt_solution_reset (&cfun->gimple_df->escaped);
if (cfun->gimple_df->decls_to_pointers != NULL) if (cfun->gimple_df->decls_to_pointers != NULL)

View File

@ -110,8 +110,6 @@ static int contains_pointers_p (tree);
static bool incorporeal_function_p (tree); static bool incorporeal_function_p (tree);
#endif #endif
static void decode_addr_const (tree, struct addr_const *); static void decode_addr_const (tree, struct addr_const *);
static hashval_t const_desc_hash (const void *);
static int const_desc_eq (const void *, const void *);
static hashval_t const_hash_1 (const tree); static hashval_t const_hash_1 (const tree);
static int compare_constant (const tree, const tree); static int compare_constant (const tree, const tree);
static void output_constant_def_contents (rtx); static void output_constant_def_contents (rtx);
@ -175,11 +173,27 @@ static GTY(()) section *unnamed_sections;
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
&& DECL_SECTION_NAME (DECL) != NULL) && DECL_SECTION_NAME (DECL) != NULL)
struct section_hasher : ggc_hasher<section *>
{
typedef const char *compare_type;
static hashval_t hash (section *);
static bool equal (section *, const char *);
};
/* Hash table of named sections. */ /* Hash table of named sections. */
static GTY((param_is (section))) htab_t section_htab; static GTY(()) hash_table<section_hasher> *section_htab;
struct object_block_hasher : ggc_hasher<object_block *>
{
typedef const section *compare_type;
static hashval_t hash (object_block *);
static bool equal (object_block *, const section *);
};
/* A table of object_blocks, indexed by section. */ /* A table of object_blocks, indexed by section. */
static GTY((param_is (struct object_block))) htab_t object_block_htab; static GTY(()) hash_table<object_block_hasher> *object_block_htab;
/* The next number to use for internal anchor labels. */ /* The next number to use for internal anchor labels. */
static GTY(()) int anchor_labelno; static GTY(()) int anchor_labelno;
@ -189,19 +203,15 @@ static GTY(()) struct rtx_constant_pool *shared_constant_pool;
/* Helper routines for maintaining section_htab. */ /* Helper routines for maintaining section_htab. */
static int bool
section_entry_eq (const void *p1, const void *p2) section_hasher::equal (section *old, const char *new_name)
{ {
const section *old = (const section *) p1;
const char *new_name = (const char *) p2;
return strcmp (old->named.name, new_name) == 0; return strcmp (old->named.name, new_name) == 0;
} }
static hashval_t hashval_t
section_entry_hash (const void *p) section_hasher::hash (section *old)
{ {
const section *old = (const section *) p;
return htab_hash_string (old->named.name); return htab_hash_string (old->named.name);
} }
@ -217,19 +227,15 @@ hash_section (section *sect)
/* Helper routines for maintaining object_block_htab. */ /* Helper routines for maintaining object_block_htab. */
static int inline bool
object_block_entry_eq (const void *p1, const void *p2) object_block_hasher::equal (object_block *old, const section *new_section)
{ {
const struct object_block *old = (const struct object_block *) p1;
const section *new_section = (const section *) p2;
return old->sect == new_section; return old->sect == new_section;
} }
static hashval_t hashval_t
object_block_entry_hash (const void *p) object_block_hasher::hash (object_block *old)
{ {
const struct object_block *old = (const struct object_block *) p;
return hash_section (old->sect); return hash_section (old->sect);
} }
@ -273,9 +279,8 @@ get_section (const char *name, unsigned int flags, tree decl)
{ {
section *sect, **slot; section *sect, **slot;
slot = (section **) slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
htab_find_slot_with_hash (section_htab, name, INSERT);
htab_hash_string (name), INSERT);
flags |= SECTION_NAMED; flags |= SECTION_NAMED;
if (*slot == NULL) if (*slot == NULL)
{ {
@ -350,14 +355,14 @@ static struct object_block *
get_block_for_section (section *sect) get_block_for_section (section *sect)
{ {
struct object_block *block; struct object_block *block;
void **slot;
if (sect == NULL) if (sect == NULL)
return NULL; return NULL;
slot = htab_find_slot_with_hash (object_block_htab, sect, object_block **slot
hash_section (sect), INSERT); = object_block_htab->find_slot_with_hash (sect, hash_section (sect),
block = (struct object_block *) *slot; INSERT);
block = *slot;
if (block == NULL) if (block == NULL)
{ {
block = ggc_cleared_alloc<object_block> (); block = ggc_cleared_alloc<object_block> ();
@ -2824,15 +2829,13 @@ decode_addr_const (tree exp, struct addr_const *value)
value->offset = offset; value->offset = offset;
} }
static GTY(()) hash_table<tree_descriptor_hasher> *const_desc_htab;
static GTY((param_is (struct constant_descriptor_tree)))
htab_t const_desc_htab;
static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int); static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
/* Constant pool accessor function. */ /* Constant pool accessor function. */
htab_t hash_table<tree_descriptor_hasher> *
constant_pool_htab (void) constant_pool_htab (void)
{ {
return const_desc_htab; return const_desc_htab;
@ -2840,10 +2843,10 @@ constant_pool_htab (void)
/* Compute a hash code for a constant expression. */ /* Compute a hash code for a constant expression. */
static hashval_t hashval_t
const_desc_hash (const void *ptr) tree_descriptor_hasher::hash (constant_descriptor_tree *ptr)
{ {
return ((const struct constant_descriptor_tree *)ptr)->hash; return ptr->hash;
} }
static hashval_t static hashval_t
@ -2956,13 +2959,10 @@ const_hash_1 (const tree exp)
} }
/* Wrapper of compare_constant, for the htab interface. */ /* Wrapper of compare_constant, for the htab interface. */
static int bool
const_desc_eq (const void *p1, const void *p2) tree_descriptor_hasher::equal (constant_descriptor_tree *c1,
constant_descriptor_tree *c2)
{ {
const struct constant_descriptor_tree *const c1
= (const struct constant_descriptor_tree *) p1;
const struct constant_descriptor_tree *const c2
= (const struct constant_descriptor_tree *) p2;
if (c1->hash != c2->hash) if (c1->hash != c2->hash)
return 0; return 0;
return compare_constant (c1->value, c2->value); return compare_constant (c1->value, c2->value);
@ -3264,15 +3264,15 @@ output_constant_def (tree exp, int defer)
{ {
struct constant_descriptor_tree *desc; struct constant_descriptor_tree *desc;
struct constant_descriptor_tree key; struct constant_descriptor_tree key;
void **loc;
/* Look up EXP in the table of constant descriptors. If we didn't find /* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */ it, create a new one. */
key.value = exp; key.value = exp;
key.hash = const_hash_1 (exp); key.hash = const_hash_1 (exp);
loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT); constant_descriptor_tree **loc
= const_desc_htab->find_slot_with_hash (&key, key.hash, INSERT);
desc = (struct constant_descriptor_tree *) *loc; desc = *loc;
if (desc == 0) if (desc == 0)
{ {
desc = build_constant_desc (exp); desc = build_constant_desc (exp);
@ -3387,13 +3387,12 @@ output_constant_def_contents (rtx symbol)
rtx rtx
lookup_constant_def (tree exp) lookup_constant_def (tree exp)
{ {
struct constant_descriptor_tree *desc;
struct constant_descriptor_tree key; struct constant_descriptor_tree key;
key.value = exp; key.value = exp;
key.hash = const_hash_1 (exp); key.hash = const_hash_1 (exp);
desc = (struct constant_descriptor_tree *) constant_descriptor_tree *desc
htab_find_with_hash (const_desc_htab, &key, key.hash); = const_desc_htab->find_with_hash (&key, key.hash);
return (desc ? desc->rtl : NULL_RTX); return (desc ? desc->rtl : NULL_RTX);
} }
@ -3407,16 +3406,16 @@ tree
tree_output_constant_def (tree exp) tree_output_constant_def (tree exp)
{ {
struct constant_descriptor_tree *desc, key; struct constant_descriptor_tree *desc, key;
void **loc;
tree decl; tree decl;
/* Look up EXP in the table of constant descriptors. If we didn't find /* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */ it, create a new one. */
key.value = exp; key.value = exp;
key.hash = const_hash_1 (exp); key.hash = const_hash_1 (exp);
loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT); constant_descriptor_tree **loc
= const_desc_htab->find_slot_with_hash (&key, key.hash, INSERT);
desc = (struct constant_descriptor_tree *) *loc; desc = *loc;
if (desc == 0) if (desc == 0)
{ {
desc = build_constant_desc (exp); desc = build_constant_desc (exp);
@ -3429,6 +3428,25 @@ tree_output_constant_def (tree exp)
return decl; return decl;
} }
struct GTY((chain_next ("%h.next"), for_user)) constant_descriptor_rtx {
struct constant_descriptor_rtx *next;
rtx mem;
rtx sym;
rtx constant;
HOST_WIDE_INT offset;
hashval_t hash;
enum machine_mode mode;
unsigned int align;
int labelno;
int mark;
};
struct const_rtx_desc_hasher : ggc_hasher<constant_descriptor_rtx *>
{
static hashval_t hash (constant_descriptor_rtx *);
static bool equal (constant_descriptor_rtx *, constant_descriptor_rtx *);
};
/* Used in the hash tables to avoid outputting the same constant /* Used in the hash tables to avoid outputting the same constant
twice. Unlike 'struct constant_descriptor_tree', RTX constants twice. Unlike 'struct constant_descriptor_tree', RTX constants
are output once per function, not once per file. */ are output once per function, not once per file. */
@ -3445,44 +3463,25 @@ struct GTY(()) rtx_constant_pool {
It is used on RISC machines where immediate integer arguments and It is used on RISC machines where immediate integer arguments and
constant addresses are restricted so that such constants must be stored constant addresses are restricted so that such constants must be stored
in memory. */ in memory. */
htab_t GTY((param_is (struct constant_descriptor_rtx))) const_rtx_htab; hash_table<const_rtx_desc_hasher> *const_rtx_htab;
/* Current offset in constant pool (does not include any /* Current offset in constant pool (does not include any
machine-specific header). */ machine-specific header). */
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
}; };
struct GTY((chain_next ("%h.next"))) constant_descriptor_rtx {
struct constant_descriptor_rtx *next;
rtx mem;
rtx sym;
rtx constant;
HOST_WIDE_INT offset;
hashval_t hash;
enum machine_mode mode;
unsigned int align;
int labelno;
int mark;
};
/* Hash and compare functions for const_rtx_htab. */ /* Hash and compare functions for const_rtx_htab. */
static hashval_t hashval_t
const_desc_rtx_hash (const void *ptr) const_rtx_desc_hasher::hash (constant_descriptor_rtx *desc)
{ {
const struct constant_descriptor_rtx *const desc
= (const struct constant_descriptor_rtx *) ptr;
return desc->hash; return desc->hash;
} }
static int bool
const_desc_rtx_eq (const void *a, const void *b) const_rtx_desc_hasher::equal (constant_descriptor_rtx *x,
constant_descriptor_rtx *y)
{ {
const struct constant_descriptor_rtx *const x
= (const struct constant_descriptor_rtx *) a;
const struct constant_descriptor_rtx *const y
= (const struct constant_descriptor_rtx *) b;
if (x->mode != y->mode) if (x->mode != y->mode)
return 0; return 0;
return rtx_equal_p (x->constant, y->constant); return rtx_equal_p (x->constant, y->constant);
@ -3585,8 +3584,7 @@ create_constant_pool (void)
struct rtx_constant_pool *pool; struct rtx_constant_pool *pool;
pool = ggc_alloc<rtx_constant_pool> (); pool = ggc_alloc<rtx_constant_pool> ();
pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash, pool->const_rtx_htab = hash_table<const_rtx_desc_hasher>::create_ggc (31);
const_desc_rtx_eq, NULL);
pool->first = NULL; pool->first = NULL;
pool->last = NULL; pool->last = NULL;
pool->offset = 0; pool->offset = 0;
@ -3624,7 +3622,7 @@ force_const_mem (enum machine_mode mode, rtx x)
rtx def, symbol; rtx def, symbol;
hashval_t hash; hashval_t hash;
unsigned int align; unsigned int align;
void **slot; constant_descriptor_rtx **slot;
/* If we're not allowed to drop X into the constant pool, don't. */ /* If we're not allowed to drop X into the constant pool, don't. */
if (targetm.cannot_force_const_mem (mode, x)) if (targetm.cannot_force_const_mem (mode, x))
@ -3642,8 +3640,8 @@ force_const_mem (enum machine_mode mode, rtx x)
tmp.constant = x; tmp.constant = x;
tmp.mode = mode; tmp.mode = mode;
hash = const_rtx_hash (x); hash = const_rtx_hash (x);
slot = htab_find_slot_with_hash (pool->const_rtx_htab, &tmp, hash, INSERT); slot = pool->const_rtx_htab->find_slot_with_hash (&tmp, hash, INSERT);
desc = (struct constant_descriptor_rtx *) *slot; desc = *slot;
/* If the constant was already present, return its memory. */ /* If the constant was already present, return its memory. */
if (desc) if (desc)
@ -5923,12 +5921,9 @@ make_decl_one_only (tree decl, tree comdat_group)
void void
init_varasm_once (void) init_varasm_once (void)
{ {
section_htab = htab_create_ggc (31, section_entry_hash, section_htab = hash_table<section_hasher>::create_ggc (31);
section_entry_eq, NULL); object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
object_block_htab = htab_create_ggc (31, object_block_entry_hash, const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
object_block_entry_eq, NULL);
const_desc_htab = htab_create_ggc (1009, const_desc_hash,
const_desc_eq, NULL);
const_alias_set = new_alias_set (); const_alias_set = new_alias_set ();
shared_constant_pool = create_constant_pool (); shared_constant_pool = create_constant_pool ();
@ -7255,10 +7250,10 @@ output_object_block (struct object_block *block)
/* A htab_traverse callback used to call output_object_block for /* A htab_traverse callback used to call output_object_block for
each member of object_block_htab. */ each member of object_block_htab. */
static int int
output_object_block_htab (void **slot, void *data ATTRIBUTE_UNUSED) output_object_block_htab (object_block **slot, void *)
{ {
output_object_block ((struct object_block *) (*slot)); output_object_block (*slot);
return 1; return 1;
} }
@ -7267,7 +7262,7 @@ output_object_block_htab (void **slot, void *data ATTRIBUTE_UNUSED)
void void
output_object_blocks (void) output_object_blocks (void)
{ {
htab_traverse (object_block_htab, output_object_block_htab, NULL); object_block_htab->traverse<void *, output_object_block_htab> (NULL);
} }
/* This function provides a possible implementation of the /* This function provides a possible implementation of the