mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 22:41:28 +08:00
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:
parent
7b262a51ea
commit
2a22f99cb1
@ -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>
|
||||
|
||||
* config/sh/sh.h (TARGET_SH4A_ARCH): Remove macro.
|
||||
|
30
gcc/asan.c
30
gcc/asan.c
@ -2368,15 +2368,15 @@ initialize_sanitizer_builtins (void)
|
||||
/* Called via htab_traverse. Count number of emitted
|
||||
STRING_CSTs in the constant hash table. */
|
||||
|
||||
static int
|
||||
count_string_csts (void **slot, void *data)
|
||||
int
|
||||
count_string_csts (constant_descriptor_tree **slot,
|
||||
unsigned HOST_WIDE_INT *data)
|
||||
{
|
||||
struct constant_descriptor_tree *desc
|
||||
= (struct constant_descriptor_tree *) *slot;
|
||||
struct constant_descriptor_tree *desc = *slot;
|
||||
if (TREE_CODE (desc->value) == STRING_CST
|
||||
&& TREE_ASM_WRITTEN (desc->value)
|
||||
&& asan_protect_global (desc->value))
|
||||
++*((unsigned HOST_WIDE_INT *) data);
|
||||
++*data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2389,20 +2389,18 @@ struct asan_add_string_csts_data
|
||||
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. */
|
||||
|
||||
static int
|
||||
add_string_csts (void **slot, void *data)
|
||||
int
|
||||
add_string_csts (constant_descriptor_tree **slot,
|
||||
asan_add_string_csts_data *aascd)
|
||||
{
|
||||
struct constant_descriptor_tree *desc
|
||||
= (struct constant_descriptor_tree *) *slot;
|
||||
struct constant_descriptor_tree *desc = *slot;
|
||||
if (TREE_CODE (desc->value) == STRING_CST
|
||||
&& TREE_ASM_WRITTEN (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)),
|
||||
aascd->type, aascd->v);
|
||||
}
|
||||
@ -2440,8 +2438,9 @@ asan_finish_file (void)
|
||||
if (TREE_ASM_WRITTEN (vnode->decl)
|
||||
&& asan_protect_global (vnode->decl))
|
||||
++gcount;
|
||||
htab_t const_desc_htab = constant_pool_htab ();
|
||||
htab_traverse (const_desc_htab, count_string_csts, &gcount);
|
||||
hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
|
||||
const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
|
||||
(&gcount);
|
||||
if (gcount)
|
||||
{
|
||||
tree type = asan_global_struct (), var, ctor;
|
||||
@ -2465,7 +2464,8 @@ asan_finish_file (void)
|
||||
struct asan_add_string_csts_data aascd;
|
||||
aascd.type = TREE_TYPE (type);
|
||||
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);
|
||||
TREE_CONSTANT (ctor) = 1;
|
||||
TREE_STATIC (ctor) = 1;
|
||||
|
@ -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>
|
||||
|
||||
* c-family/c-cppbuiltin.c: Move __cpp_attribute_deprecated to the
|
||||
|
@ -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
|
||||
different files. This must hash all types that will compare
|
||||
equal via comptypes to the same value. In practice it hashes
|
||||
on some of the simple stuff and leaves the details to comptypes. */
|
||||
|
||||
static hashval_t
|
||||
c_type_hash (const void *p)
|
||||
hashval_t
|
||||
c_type_hasher::hash (tree t)
|
||||
{
|
||||
int n_elements;
|
||||
int shift, size;
|
||||
const_tree const t = (const_tree) p;
|
||||
tree t2;
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
/* For pointers, hash on pointee type plus some swizzling. */
|
||||
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. */
|
||||
case ENUMERAL_TYPE:
|
||||
shift = 3;
|
||||
@ -4851,7 +4856,13 @@ c_type_hash (const void *p)
|
||||
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
|
||||
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)
|
||||
{
|
||||
tree u;
|
||||
PTR *slot;
|
||||
|
||||
/* For VLAs, use the alias set of the element type rather than the
|
||||
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
|
||||
alias set is recorded in the table. */
|
||||
if (!type_hash_table)
|
||||
type_hash_table = htab_create_ggc (1021, c_type_hash,
|
||||
(htab_eq) lang_hooks.types_compatible_p,
|
||||
NULL);
|
||||
slot = htab_find_slot (type_hash_table, t, INSERT);
|
||||
type_hash_table = hash_table<c_type_hasher>::create_ggc (1021);
|
||||
tree *slot = type_hash_table->find_slot (t, INSERT);
|
||||
if (*slot != NULL)
|
||||
{
|
||||
TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot);
|
||||
|
@ -958,31 +958,26 @@ get_loop_body_in_bfs_order (const struct loop *loop)
|
||||
|
||||
/* Hash function for struct loop_exit. */
|
||||
|
||||
static hashval_t
|
||||
loop_exit_hash (const void *ex)
|
||||
hashval_t
|
||||
loop_exit_hasher::hash (loop_exit *exit)
|
||||
{
|
||||
const struct loop_exit *const exit = (const struct loop_exit *) ex;
|
||||
|
||||
return htab_hash_pointer (exit->e);
|
||||
}
|
||||
|
||||
/* Equality function for struct loop_exit. Compares with edge. */
|
||||
|
||||
static int
|
||||
loop_exit_eq (const void *ex, const void *e)
|
||||
bool
|
||||
loop_exit_hasher::equal (loop_exit *exit, edge e)
|
||||
{
|
||||
const struct loop_exit *const exit = (const struct loop_exit *) ex;
|
||||
|
||||
return exit->e == e;
|
||||
}
|
||||
|
||||
/* Frees the list of loop exit descriptions EX. */
|
||||
|
||||
static void
|
||||
loop_exit_free (void *ex)
|
||||
void
|
||||
loop_exit_hasher::remove (loop_exit *exit)
|
||||
{
|
||||
struct loop_exit *exit = (struct loop_exit *) ex, *next;
|
||||
|
||||
loop_exit *next;
|
||||
for (; exit; exit = next)
|
||||
{
|
||||
next = exit->next_e;
|
||||
@ -999,8 +994,7 @@ loop_exit_free (void *ex)
|
||||
static struct loop_exit *
|
||||
get_exit_descriptions (edge e)
|
||||
{
|
||||
return (struct loop_exit *) htab_find_with_hash (current_loops->exits, e,
|
||||
htab_hash_pointer (e));
|
||||
return current_loops->exits->find_with_hash (e, htab_hash_pointer (e));
|
||||
}
|
||||
|
||||
/* Updates the lists of loop exits in that E appears.
|
||||
@ -1012,7 +1006,6 @@ get_exit_descriptions (edge e)
|
||||
void
|
||||
rescan_loop_exit (edge e, bool new_edge, bool removed)
|
||||
{
|
||||
void **slot;
|
||||
struct loop_exit *exits = NULL, *exit;
|
||||
struct loop *aloop, *cloop;
|
||||
|
||||
@ -1045,20 +1038,20 @@ rescan_loop_exit (edge e, bool new_edge, bool removed)
|
||||
if (!exits && new_edge)
|
||||
return;
|
||||
|
||||
slot = htab_find_slot_with_hash (current_loops->exits, e,
|
||||
htab_hash_pointer (e),
|
||||
exits ? INSERT : NO_INSERT);
|
||||
loop_exit **slot
|
||||
= current_loops->exits->find_slot_with_hash (e, htab_hash_pointer (e),
|
||||
exits ? INSERT : NO_INSERT);
|
||||
if (!slot)
|
||||
return;
|
||||
|
||||
if (exits)
|
||||
{
|
||||
if (*slot)
|
||||
loop_exit_free (*slot);
|
||||
loop_exit_hasher::remove (*slot);
|
||||
*slot = exits;
|
||||
}
|
||||
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
|
||||
@ -1079,9 +1072,8 @@ record_loop_exits (void)
|
||||
loops_state_set (LOOPS_HAVE_RECORDED_EXITS);
|
||||
|
||||
gcc_assert (current_loops->exits == NULL);
|
||||
current_loops->exits = htab_create_ggc (2 * number_of_loops (cfun),
|
||||
loop_exit_hash, loop_exit_eq,
|
||||
loop_exit_free);
|
||||
current_loops->exits
|
||||
= hash_table<loop_exit_hasher>::create_ggc (2 * number_of_loops (cfun));
|
||||
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
@ -1095,17 +1087,17 @@ record_loop_exits (void)
|
||||
/* Dumps information about the exit in *SLOT to FILE.
|
||||
Callback for htab_traverse. */
|
||||
|
||||
static int
|
||||
dump_recorded_exit (void **slot, void *file)
|
||||
int
|
||||
dump_recorded_exit (loop_exit **slot, FILE *file)
|
||||
{
|
||||
struct loop_exit *exit = (struct loop_exit *) *slot;
|
||||
struct loop_exit *exit = *slot;
|
||||
unsigned n = 0;
|
||||
edge e = exit->e;
|
||||
|
||||
for (; exit != NULL; exit = exit->next_e)
|
||||
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);
|
||||
|
||||
return 1;
|
||||
@ -1119,7 +1111,7 @@ dump_recorded_exits (FILE *file)
|
||||
{
|
||||
if (!current_loops->exits)
|
||||
return;
|
||||
htab_traverse (current_loops->exits, dump_recorded_exit, file);
|
||||
current_loops->exits->traverse<FILE *, dump_recorded_exit> (file);
|
||||
}
|
||||
|
||||
/* Releases lists of loop exits. */
|
||||
@ -1128,7 +1120,7 @@ void
|
||||
release_recorded_exits (void)
|
||||
{
|
||||
gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS));
|
||||
htab_delete (current_loops->exits);
|
||||
current_loops->exits->empty ();
|
||||
current_loops->exits = NULL;
|
||||
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");
|
||||
err = 1;
|
||||
|
@ -76,7 +76,7 @@ struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
|
||||
|
||||
/* Description of the loop exit. */
|
||||
|
||||
struct GTY (()) loop_exit {
|
||||
struct GTY ((for_user)) loop_exit {
|
||||
/* The exit edge. */
|
||||
edge e;
|
||||
|
||||
@ -88,6 +88,15 @@ struct GTY (()) loop_exit {
|
||||
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;
|
||||
|
||||
/* 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
|
||||
whose sources or destinations have loop_father == NULL (which may
|
||||
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. */
|
||||
struct loop *tree_root;
|
||||
|
97
gcc/cgraph.c
97
gcc/cgraph.c
@ -103,30 +103,34 @@ struct cgraph_2node_hook_list {
|
||||
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.
|
||||
The cgraph_function_version_info has a THIS_NODE field that is the
|
||||
corresponding cgraph_node.. */
|
||||
|
||||
static GTY((param_is (cgraph_function_version_info))) htab_t
|
||||
cgraph_fnver_htab = NULL;
|
||||
static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
|
||||
|
||||
/* Hash function for cgraph_fnver_htab. */
|
||||
static hashval_t
|
||||
cgraph_fnver_htab_hash (const void *ptr)
|
||||
hashval_t
|
||||
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);
|
||||
}
|
||||
|
||||
/* eq function for cgraph_fnver_htab. */
|
||||
static int
|
||||
cgraph_fnver_htab_eq (const void *p1, const void *p2)
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
@ -138,17 +142,13 @@ static GTY(()) struct cgraph_function_version_info *
|
||||
cgraph_function_version_info *
|
||||
cgraph_node::function_version (void)
|
||||
{
|
||||
cgraph_function_version_info *ret;
|
||||
cgraph_function_version_info key;
|
||||
key.this_node = this;
|
||||
|
||||
if (cgraph_fnver_htab == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = (cgraph_function_version_info *)
|
||||
htab_find (cgraph_fnver_htab, &key);
|
||||
|
||||
return ret;
|
||||
return cgraph_fnver_htab->find (&key);
|
||||
}
|
||||
|
||||
/* 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_node::insert_new_function_version (void)
|
||||
{
|
||||
void **slot;
|
||||
|
||||
version_info_node = NULL;
|
||||
version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
|
||||
version_info_node->this_node = this;
|
||||
|
||||
if (cgraph_fnver_htab == NULL)
|
||||
cgraph_fnver_htab = htab_create_ggc (2, cgraph_fnver_htab_hash,
|
||||
cgraph_fnver_htab_eq, NULL);
|
||||
cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
|
||||
|
||||
slot = htab_find_slot (cgraph_fnver_htab, version_info_node, INSERT);
|
||||
gcc_assert (slot != NULL);
|
||||
*slot = version_info_node;
|
||||
*cgraph_fnver_htab->find_slot (version_info_node, INSERT)
|
||||
= 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;
|
||||
|
||||
if (cgraph_fnver_htab != NULL)
|
||||
htab_remove_elt (cgraph_fnver_htab, decl_v);
|
||||
cgraph_fnver_htab->remove_elt (decl_v);
|
||||
|
||||
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). */
|
||||
|
||||
static hashval_t
|
||||
edge_hash (const void *x)
|
||||
hashval_t
|
||||
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. */
|
||||
|
||||
static int
|
||||
edge_eq (const void *x, const void *y)
|
||||
inline bool
|
||||
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. */
|
||||
@ -615,12 +611,10 @@ edge_eq (const void *x, const void *y)
|
||||
static inline void
|
||||
cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
|
||||
{
|
||||
void **slot;
|
||||
slot = htab_find_slot_with_hash (e->caller->call_site_hash,
|
||||
e->call_stmt,
|
||||
htab_hash_pointer (e->call_stmt),
|
||||
INSERT);
|
||||
*slot = e;
|
||||
gimple call = e->call_stmt;
|
||||
*e->caller->call_site_hash->find_slot_with_hash (call,
|
||||
htab_hash_pointer (call),
|
||||
INSERT) = e;
|
||||
}
|
||||
|
||||
/* 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
|
||||
cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
|
||||
{
|
||||
void **slot;
|
||||
/* There are two speculative edges for every statement (one direct,
|
||||
one indirect); always hash the direct one. */
|
||||
if (e->speculative && e->indirect_unknown_callee)
|
||||
return;
|
||||
slot = htab_find_slot_with_hash (e->caller->call_site_hash,
|
||||
e->call_stmt,
|
||||
htab_hash_pointer (e->call_stmt),
|
||||
INSERT);
|
||||
cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
|
||||
(e->call_stmt,
|
||||
htab_hash_pointer (e->call_stmt), INSERT);
|
||||
if (*slot)
|
||||
{
|
||||
gcc_assert (((cgraph_edge *)*slot)->speculative);
|
||||
@ -658,9 +650,8 @@ cgraph_node::get_edge (gimple call_stmt)
|
||||
int n = 0;
|
||||
|
||||
if (call_site_hash)
|
||||
return (cgraph_edge *)
|
||||
htab_find_with_hash (call_site_hash, call_stmt,
|
||||
htab_hash_pointer (call_stmt));
|
||||
return call_site_hash->find_with_hash (call_stmt,
|
||||
htab_hash_pointer (call_stmt));
|
||||
|
||||
/* This loop may turn out to be performance problem. In such case adding
|
||||
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)
|
||||
{
|
||||
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)
|
||||
cgraph_add_edge_to_call_site_hash (e2);
|
||||
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
|
||||
&& (!speculative || !indirect_unknown_callee))
|
||||
{
|
||||
htab_remove_elt_with_hash (caller->call_site_hash,
|
||||
call_stmt,
|
||||
htab_hash_pointer (call_stmt));
|
||||
caller->call_site_hash->remove_elt_with_hash
|
||||
(call_stmt, htab_hash_pointer (call_stmt));
|
||||
}
|
||||
|
||||
cgraph_edge *e = this;
|
||||
@ -942,9 +932,8 @@ cgraph_edge::remove_caller (void)
|
||||
caller->callees = next_callee;
|
||||
}
|
||||
if (caller->call_site_hash)
|
||||
htab_remove_elt_with_hash (caller->call_site_hash,
|
||||
call_stmt,
|
||||
htab_hash_pointer (call_stmt));
|
||||
caller->call_site_hash->remove_elt_with_hash (call_stmt,
|
||||
htab_hash_pointer (call_stmt));
|
||||
}
|
||||
|
||||
/* Put the edge onto the free list. */
|
||||
@ -1564,7 +1553,7 @@ cgraph_node::remove_callees (void)
|
||||
callees = NULL;
|
||||
if (call_site_hash)
|
||||
{
|
||||
htab_delete (call_site_hash);
|
||||
call_site_hash->empty ();
|
||||
call_site_hash = NULL;
|
||||
}
|
||||
}
|
||||
@ -1743,7 +1732,7 @@ cgraph_node::remove (void)
|
||||
decl = NULL;
|
||||
if (call_site_hash)
|
||||
{
|
||||
htab_delete (call_site_hash);
|
||||
call_site_hash->empty ();
|
||||
call_site_hash = NULL;
|
||||
}
|
||||
|
||||
|
94
gcc/cgraph.h
94
gcc/cgraph.h
@ -42,7 +42,7 @@ enum symtab_type
|
||||
/* Section names are stored as reference counted strings in GGC safe hashtable
|
||||
(to make them survive through PCH). */
|
||||
|
||||
struct GTY(()) section_hash_entry_d
|
||||
struct GTY((for_user)) section_hash_entry_d
|
||||
{
|
||||
int ref_count;
|
||||
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;
|
||||
|
||||
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
|
||||
{
|
||||
/* Not yet set by cgraph_function_body_availability. */
|
||||
@ -704,7 +712,7 @@ struct GTY(()) cgraph_simd_clone {
|
||||
};
|
||||
|
||||
/* 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. */
|
||||
cgraph_node *this_node;
|
||||
/* Chains all the semantically identical function versions. The
|
||||
@ -743,6 +751,14 @@ enum cgraph_inline_failed_type_t
|
||||
|
||||
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.
|
||||
Each function decl has assigned cgraph_node listing callees and callers. */
|
||||
|
||||
@ -1175,7 +1191,7 @@ public:
|
||||
cgraph_node *clone_of;
|
||||
/* For functions with many calls sites it holds map from call expression
|
||||
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. */
|
||||
tree former_clone_of;
|
||||
|
||||
@ -1401,7 +1417,8 @@ struct GTY(()) cgraph_indirect_call_info
|
||||
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;
|
||||
|
||||
/* Remove the edge in the cgraph. */
|
||||
@ -1733,6 +1750,20 @@ enum symtab_state
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -1969,10 +2000,10 @@ public:
|
||||
bool cpp_implicit_aliases_done;
|
||||
|
||||
/* 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. */
|
||||
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_map<symtab_node *, symbol_priority_map> *init_priority_hash;
|
||||
@ -2005,11 +2036,7 @@ private:
|
||||
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
|
||||
static bool decl_assembler_name_equal (tree decl, const_tree asmname);
|
||||
|
||||
/* Returns a hash code for P. */
|
||||
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);
|
||||
friend struct asmname_hasher;
|
||||
|
||||
/* List of hooks triggered when an edge is removed. */
|
||||
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;
|
||||
|
||||
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 */
|
||||
void release_function_body (tree);
|
||||
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
|
||||
in `const_desc_table'. */
|
||||
|
||||
struct GTY(()) constant_descriptor_tree {
|
||||
struct GTY((for_user)) constant_descriptor_tree {
|
||||
/* A MEM for the constant. */
|
||||
rtx rtl;
|
||||
|
||||
@ -2544,8 +2606,14 @@ varpool_node::all_refs_explicit_p ()
|
||||
&& !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. */
|
||||
htab_t constant_pool_htab (void);
|
||||
hash_table<tree_descriptor_hasher> *constant_pool_htab (void);
|
||||
|
||||
/* Return node that alias is aliasing. */
|
||||
|
||||
|
@ -450,7 +450,7 @@ machopic_should_output_picbase_label (void)
|
||||
/* The suffix attached to stub symbols. */
|
||||
#define STUB_SUFFIX "$stub"
|
||||
|
||||
typedef struct GTY (()) machopic_indirection
|
||||
typedef struct GTY ((for_user)) machopic_indirection
|
||||
{
|
||||
/* The SYMBOL_REF for the entity referenced. */
|
||||
rtx symbol;
|
||||
@ -463,29 +463,33 @@ typedef struct GTY (()) machopic_indirection
|
||||
bool used;
|
||||
} 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
|
||||
SYMBOL_REFs for the stubbed-to and pointed-to entities. */
|
||||
|
||||
static GTY ((param_is (struct machopic_indirection))) htab_t
|
||||
machopic_indirections;
|
||||
static GTY (()) hash_table<indirection_hasher> *machopic_indirections;
|
||||
|
||||
/* Return a hash value for a SLOT in the indirections hash table. */
|
||||
|
||||
static hashval_t
|
||||
machopic_indirection_hash (const void *slot)
|
||||
hashval_t
|
||||
indirection_hasher::hash (machopic_indirection *p)
|
||||
{
|
||||
const machopic_indirection *p = (const machopic_indirection *) slot;
|
||||
return htab_hash_string (p->ptr_name);
|
||||
}
|
||||
|
||||
/* Returns true if the KEY is the same as that associated with
|
||||
SLOT. */
|
||||
|
||||
static int
|
||||
machopic_indirection_eq (const void *slot, const void *key)
|
||||
bool
|
||||
indirection_hasher::equal (machopic_indirection *s, const char *k)
|
||||
{
|
||||
return strcmp (((const machopic_indirection *) slot)->ptr_name,
|
||||
(const char *) key) == 0;
|
||||
return strcmp (s->ptr_name, k) == 0;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
size_t namelen = strlen (name);
|
||||
machopic_indirection *p;
|
||||
void ** slot;
|
||||
bool needs_quotes;
|
||||
const char *suffix;
|
||||
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);
|
||||
|
||||
if (!machopic_indirections)
|
||||
machopic_indirections = htab_create_ggc (37,
|
||||
machopic_indirection_hash,
|
||||
machopic_indirection_eq,
|
||||
/*htab_del=*/NULL);
|
||||
machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);
|
||||
|
||||
slot = htab_find_slot_with_hash (machopic_indirections, buffer,
|
||||
htab_hash_string (buffer), INSERT);
|
||||
machopic_indirection **slot
|
||||
= machopic_indirections->find_slot_with_hash (buffer,
|
||||
htab_hash_string (buffer),
|
||||
INSERT);
|
||||
if (*slot)
|
||||
{
|
||||
p = (machopic_indirection *) *slot;
|
||||
p = *slot;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -589,11 +591,8 @@ machopic_mcount_stub_name (void)
|
||||
void
|
||||
machopic_validate_stub_or_non_lazy_ptr (const char *name)
|
||||
{
|
||||
machopic_indirection *p;
|
||||
|
||||
p = ((machopic_indirection *)
|
||||
(htab_find_with_hash (machopic_indirections, name,
|
||||
htab_hash_string (name))));
|
||||
machopic_indirection *p
|
||||
= machopic_indirections->find_with_hash (name, htab_hash_string (name));
|
||||
if (p && ! p->used)
|
||||
{
|
||||
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
|
||||
htab_traverse. */
|
||||
|
||||
static int
|
||||
machopic_output_indirection (void **slot, void *data)
|
||||
int
|
||||
machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
|
||||
{
|
||||
machopic_indirection *p = *((machopic_indirection **) slot);
|
||||
FILE *asm_out_file = (FILE *) data;
|
||||
machopic_indirection *p = *slot;
|
||||
rtx symbol;
|
||||
const char *sym_name;
|
||||
const char *ptr_name;
|
||||
@ -1180,9 +1178,8 @@ void
|
||||
machopic_finish (FILE *asm_out_file)
|
||||
{
|
||||
if (machopic_indirections)
|
||||
htab_traverse_noresize (machopic_indirections,
|
||||
machopic_output_indirection,
|
||||
asm_out_file);
|
||||
machopic_indirections
|
||||
->traverse_noresize<FILE *, machopic_output_indirection> (asm_out_file);
|
||||
}
|
||||
|
||||
int
|
||||
@ -3254,17 +3251,20 @@ static enum built_in_function darwin_builtin_cfstring;
|
||||
/* Store all constructed constant CFStrings in a hash table so that
|
||||
they get uniqued properly. */
|
||||
|
||||
typedef struct GTY (()) cfstring_descriptor {
|
||||
typedef struct GTY ((for_user)) cfstring_descriptor {
|
||||
/* The string literal. */
|
||||
tree literal;
|
||||
/* The resulting constant CFString. */
|
||||
tree constructor;
|
||||
} 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 int cfstring_eq (const void *, const void *);
|
||||
static GTY (()) hash_table<cfstring_hasher> *cfstring_htab;
|
||||
|
||||
static tree
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@ -3421,10 +3421,10 @@ darwin_libc_has_function (enum function_class fn_class)
|
||||
return true;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
cfstring_hash (const void *ptr)
|
||||
hashval_t
|
||||
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);
|
||||
int i, len = TREE_STRING_LENGTH (str);
|
||||
hashval_t h = len;
|
||||
@ -3435,11 +3435,11 @@ cfstring_hash (const void *ptr)
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
cfstring_eq (const void *ptr1, const void *ptr2)
|
||||
bool
|
||||
cfstring_hasher::equal (cfstring_descriptor *ptr1, cfstring_descriptor *ptr2)
|
||||
{
|
||||
tree str1 = ((const struct cfstring_descriptor *)ptr1)->literal;
|
||||
tree str2 = ((const struct cfstring_descriptor *)ptr2)->literal;
|
||||
tree str1 = ptr1->literal;
|
||||
tree str2 = ptr2->literal;
|
||||
int len1 = TREE_STRING_LENGTH (str1);
|
||||
|
||||
return (len1 == TREE_STRING_LENGTH (str2)
|
||||
@ -3451,7 +3451,6 @@ tree
|
||||
darwin_build_constant_cfstring (tree str)
|
||||
{
|
||||
struct cfstring_descriptor *desc, key;
|
||||
void **loc;
|
||||
tree addr;
|
||||
|
||||
if (!str)
|
||||
@ -3473,8 +3472,8 @@ darwin_build_constant_cfstring (tree str)
|
||||
|
||||
/* Perhaps we already constructed a constant CFString just like this one? */
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, INSERT);
|
||||
desc = (struct cfstring_descriptor *) *loc;
|
||||
cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
|
||||
desc = *loc;
|
||||
|
||||
if (!desc)
|
||||
{
|
||||
@ -3550,7 +3549,6 @@ bool
|
||||
darwin_cfstring_p (tree str)
|
||||
{
|
||||
struct cfstring_descriptor key;
|
||||
void **loc;
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
@ -3564,7 +3562,7 @@ darwin_cfstring_p (tree str)
|
||||
return false;
|
||||
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, NO_INSERT);
|
||||
cfstring_descriptor **loc = cfstring_htab->find_slot (&key, NO_INSERT);
|
||||
|
||||
if (loc)
|
||||
return true;
|
||||
@ -3576,10 +3574,9 @@ void
|
||||
darwin_enter_string_into_cfstring_table (tree str)
|
||||
{
|
||||
struct cfstring_descriptor key;
|
||||
void **loc;
|
||||
|
||||
key.literal = str;
|
||||
loc = htab_find_slot (cfstring_htab, &key, INSERT);
|
||||
cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
|
||||
|
||||
if (!*loc)
|
||||
{
|
||||
|
@ -3035,66 +3035,41 @@ m32c_insert_attributes (tree node ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
struct GTY(()) pragma_entry {
|
||||
const char *varname;
|
||||
unsigned address;
|
||||
struct pragma_traits : default_hashmap_traits
|
||||
{
|
||||
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. */
|
||||
static GTY((param_is (pragma_entry))) htab_t 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);
|
||||
}
|
||||
static GTY(()) hash_map<const char *, unsigned, pragma_traits> *pragma_htab;
|
||||
|
||||
void
|
||||
m32c_note_pragma_address (const char *varname, unsigned address)
|
||||
{
|
||||
pragma_entry **slot;
|
||||
|
||||
if (!pragma_htab)
|
||||
pragma_htab = htab_create_ggc (31, pragma_entry_hash,
|
||||
pragma_entry_eq, NULL);
|
||||
pragma_htab
|
||||
= hash_map<const char *, unsigned, pragma_traits>::create_ggc (31);
|
||||
|
||||
slot = (pragma_entry **)
|
||||
htab_find_slot_with_hash (pragma_htab, varname,
|
||||
htab_hash_string (varname), INSERT);
|
||||
|
||||
if (!*slot)
|
||||
{
|
||||
*slot = ggc_alloc<pragma_entry> ();
|
||||
(*slot)->varname = ggc_strdup (varname);
|
||||
}
|
||||
(*slot)->address = address;
|
||||
const char *name = ggc_strdup (varname);
|
||||
unsigned int *slot = &pragma_htab->get_or_insert (name);
|
||||
*slot = address;
|
||||
}
|
||||
|
||||
static bool
|
||||
m32c_get_pragma_address (const char *varname, unsigned *address)
|
||||
{
|
||||
pragma_entry **slot;
|
||||
|
||||
if (!pragma_htab)
|
||||
return false;
|
||||
|
||||
slot = (pragma_entry **)
|
||||
htab_find_slot_with_hash (pragma_htab, varname,
|
||||
htab_hash_string (varname), NO_INSERT);
|
||||
if (slot && *slot)
|
||||
unsigned int *slot = pragma_htab->get (varname);
|
||||
if (slot)
|
||||
{
|
||||
*address = (*slot)->address;
|
||||
*address = *slot;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -4061,69 +4061,53 @@ mep_can_inline_p (tree caller, tree callee)
|
||||
struct GTY(()) pragma_entry {
|
||||
int used;
|
||||
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. */
|
||||
static GTY((param_is (pragma_entry))) htab_t 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 GTY(()) hash_map<const char *, pragma_entry, pragma_traits> *
|
||||
pragma_htab;
|
||||
|
||||
static void
|
||||
mep_note_pragma_flag (const char *funcname, int flag)
|
||||
{
|
||||
pragma_entry **slot;
|
||||
|
||||
if (!pragma_htab)
|
||||
pragma_htab = htab_create_ggc (31, pragma_entry_hash,
|
||||
pragma_entry_eq, NULL);
|
||||
pragma_htab
|
||||
= hash_map<const char *, pragma_entry, pragma_traits>::create_ggc (31);
|
||||
|
||||
slot = (pragma_entry **)
|
||||
htab_find_slot_with_hash (pragma_htab, funcname,
|
||||
htab_hash_string (funcname), INSERT);
|
||||
|
||||
if (!*slot)
|
||||
bool existed;
|
||||
const char *name = ggc_strdup (funcname);
|
||||
pragma_entry *slot = &pragma_htab->get_or_insert (name, &existed);
|
||||
if (!existed)
|
||||
{
|
||||
*slot = ggc_alloc<pragma_entry> ();
|
||||
(*slot)->flag = 0;
|
||||
(*slot)->used = 0;
|
||||
(*slot)->funcname = ggc_strdup (funcname);
|
||||
slot->flag = 0;
|
||||
slot->used = 0;
|
||||
}
|
||||
(*slot)->flag |= flag;
|
||||
slot->flag |= flag;
|
||||
}
|
||||
|
||||
static bool
|
||||
mep_lookup_pragma_flag (const char *funcname, int flag)
|
||||
{
|
||||
pragma_entry **slot;
|
||||
|
||||
if (!pragma_htab)
|
||||
return false;
|
||||
|
||||
if (funcname[0] == '@' && funcname[2] == '.')
|
||||
funcname += 3;
|
||||
|
||||
slot = (pragma_entry **)
|
||||
htab_find_slot_with_hash (pragma_htab, funcname,
|
||||
htab_hash_string (funcname), NO_INSERT);
|
||||
if (slot && *slot && ((*slot)->flag & flag))
|
||||
pragma_entry *slot = pragma_htab->get (funcname);
|
||||
if (slot && (slot->flag & flag))
|
||||
{
|
||||
(*slot)->used |= flag;
|
||||
slot->used |= flag;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -4153,14 +4137,13 @@ mep_note_pragma_disinterrupt (const char *funcname)
|
||||
mep_note_pragma_flag (funcname, FUNC_DISINTERRUPT);
|
||||
}
|
||||
|
||||
static int
|
||||
note_unused_pragma_disinterrupt (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
bool
|
||||
note_unused_pragma_disinterrupt (const char *const &s, const pragma_entry &e,
|
||||
void *)
|
||||
{
|
||||
const pragma_entry *d = (const pragma_entry *)(*slot);
|
||||
|
||||
if ((d->flag & FUNC_DISINTERRUPT)
|
||||
&& !(d->used & FUNC_DISINTERRUPT))
|
||||
warning (0, "\"#pragma disinterrupt %s\" not used", d->funcname);
|
||||
if ((e.flag & FUNC_DISINTERRUPT)
|
||||
&& !(e.used & FUNC_DISINTERRUPT))
|
||||
warning (0, "\"#pragma disinterrupt %s\" not used", s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -4168,7 +4151,7 @@ void
|
||||
mep_file_cleanups (void)
|
||||
{
|
||||
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
|
||||
|
@ -1202,28 +1202,20 @@ static int mips_register_move_cost (enum machine_mode, reg_class_t,
|
||||
reg_class_t);
|
||||
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
|
||||
for -mflip_mips16. It maps decl names onto a boolean mode setting. */
|
||||
struct GTY (()) mflip_mips16_entry {
|
||||
const char *name;
|
||||
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;
|
||||
}
|
||||
static GTY (()) hash_map<const char *, bool, mips16_flip_traits> *
|
||||
mflip_mips16_htab;
|
||||
|
||||
/* 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. */
|
||||
@ -1236,10 +1228,7 @@ static GTY(()) bool mips16_flipper;
|
||||
static bool
|
||||
mflip_mips16_use_mips16_p (tree decl)
|
||||
{
|
||||
struct mflip_mips16_entry *entry;
|
||||
const char *name;
|
||||
hashval_t hash;
|
||||
void **slot;
|
||||
bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (!mflip_mips16_htab)
|
||||
mflip_mips16_htab = htab_create_ggc (37, mflip_mips16_htab_hash,
|
||||
mflip_mips16_htab_eq, NULL);
|
||||
mflip_mips16_htab
|
||||
= hash_map<const char *, bool, mips16_flip_traits>::create_ggc (37);
|
||||
|
||||
name = IDENTIFIER_POINTER (DECL_NAME (decl));
|
||||
hash = htab_hash_string (name);
|
||||
slot = htab_find_slot_with_hash (mflip_mips16_htab, name, hash, INSERT);
|
||||
entry = (struct mflip_mips16_entry *) *slot;
|
||||
if (!entry)
|
||||
|
||||
bool existed;
|
||||
bool *slot = &mflip_mips16_htab->get_or_insert (name, &existed);
|
||||
if (!existed)
|
||||
{
|
||||
mips16_flipper = !mips16_flipper;
|
||||
entry = ggc_alloc<mflip_mips16_entry> ();
|
||||
entry->name = name;
|
||||
entry->mips16_p = mips16_flipper ? !base_is_mips16 : base_is_mips16;
|
||||
*slot = entry;
|
||||
*slot = mips16_flipper ? !base_is_mips16 : base_is_mips16;
|
||||
}
|
||||
return entry->mips16_p;
|
||||
return *slot;
|
||||
}
|
||||
|
||||
/* 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
|
||||
associated with it. This hash table maps the function symbol (FUNC)
|
||||
to the local symbol (LOCAL). */
|
||||
struct GTY(()) mips16_local_alias {
|
||||
rtx func;
|
||||
rtx local;
|
||||
};
|
||||
static GTY ((param_is (struct mips16_local_alias))) htab_t mips16_local_aliases;
|
||||
static GTY (()) hash_map<rtx, rtx, local_alias_traits> *mips16_local_aliases;
|
||||
|
||||
/* Hash table callbacks for mips16_local_aliases. */
|
||||
|
||||
static hashval_t
|
||||
mips16_local_aliases_hash (const void *entry)
|
||||
hashval_t
|
||||
local_alias_traits::hash (rtx func)
|
||||
{
|
||||
const struct mips16_local_alias *alias;
|
||||
|
||||
alias = (const struct mips16_local_alias *) entry;
|
||||
return htab_hash_string (XSTR (alias->func, 0));
|
||||
return htab_hash_string (XSTR (func, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
mips16_local_aliases_eq (const void *entry1, const void *entry2)
|
||||
bool
|
||||
local_alias_traits::equal_keys (rtx func1, rtx func2)
|
||||
{
|
||||
const struct mips16_local_alias *alias1, *alias2;
|
||||
|
||||
alias1 = (const struct mips16_local_alias *) entry1;
|
||||
alias2 = (const struct mips16_local_alias *) entry2;
|
||||
return rtx_equal_p (alias1->func, alias2->func);
|
||||
return rtx_equal_p (func1, func2);
|
||||
}
|
||||
|
||||
/* 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
|
||||
mips16_local_alias (rtx func)
|
||||
{
|
||||
struct mips16_local_alias *alias, tmp_alias;
|
||||
void **slot;
|
||||
|
||||
/* Create the hash table if this is the first call. */
|
||||
if (mips16_local_aliases == NULL)
|
||||
mips16_local_aliases = htab_create_ggc (37, mips16_local_aliases_hash,
|
||||
mips16_local_aliases_eq, NULL);
|
||||
mips16_local_aliases
|
||||
= hash_map<rtx, rtx, local_alias_traits>::create_ggc (37);
|
||||
|
||||
/* Look up the function symbol, creating a new entry if need be. */
|
||||
tmp_alias.func = func;
|
||||
slot = htab_find_slot (mips16_local_aliases, &tmp_alias, INSERT);
|
||||
bool existed;
|
||||
rtx *slot = &mips16_local_aliases->get_or_insert (func, &existed);
|
||||
gcc_assert (slot != NULL);
|
||||
|
||||
alias = (struct mips16_local_alias *) *slot;
|
||||
if (alias == NULL)
|
||||
if (!existed)
|
||||
{
|
||||
const char *func_name, *local_name;
|
||||
rtx local;
|
||||
@ -6455,12 +6432,9 @@ mips16_local_alias (rtx func)
|
||||
SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL;
|
||||
|
||||
/* Create a new structure to represent the mapping. */
|
||||
alias = ggc_alloc<struct mips16_local_alias> ();
|
||||
alias->func = func;
|
||||
alias->local = local;
|
||||
*slot = alias;
|
||||
*slot = local;
|
||||
}
|
||||
return alias->local;
|
||||
return *slot;
|
||||
}
|
||||
|
||||
/* A chained list of functions for which mips16_build_call_stub has already
|
||||
|
@ -1174,7 +1174,7 @@ rtl_opt_pass *make_pass_analyze_swaps (gcc::context*);
|
||||
|
||||
/* 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
|
||||
ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
|
||||
@ -1183,18 +1183,30 @@ struct GTY(()) toc_hash_struct
|
||||
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. */
|
||||
|
||||
struct GTY(()) builtin_hash_struct
|
||||
struct GTY((for_user)) builtin_hash_struct
|
||||
{
|
||||
tree type;
|
||||
enum machine_mode mode[4]; /* return value + 3 arguments. */
|
||||
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. */
|
||||
@ -15113,13 +15125,11 @@ htm_init_builtins (void)
|
||||
|
||||
/* Hash function for builtin functions with up to 3 arguments and a return
|
||||
type. */
|
||||
static unsigned
|
||||
builtin_hash_function (const void *hash_entry)
|
||||
hashval_t
|
||||
builtin_hasher::hash (builtin_hash_struct *bh)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
int i;
|
||||
const struct builtin_hash_struct *bh =
|
||||
(const struct builtin_hash_struct *) hash_entry;
|
||||
|
||||
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. */
|
||||
static int
|
||||
builtin_hash_eq (const void *h1, const void *h2)
|
||||
bool
|
||||
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])
|
||||
&& (p1->mode[1] == p2->mode[1])
|
||||
&& (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 *h2;
|
||||
void **found;
|
||||
int num_args = 3;
|
||||
int i;
|
||||
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. */
|
||||
if (builtin_hash_table == NULL)
|
||||
builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
|
||||
builtin_hash_eq, NULL);
|
||||
builtin_hash_table = hash_table<builtin_hasher>::create_ggc (1500);
|
||||
|
||||
h.type = NULL_TREE;
|
||||
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));
|
||||
}
|
||||
|
||||
found = htab_find_slot (builtin_hash_table, &h, INSERT);
|
||||
builtin_hash_struct **found = builtin_hash_table->find_slot (&h, INSERT);
|
||||
if (*found == NULL)
|
||||
{
|
||||
h2 = ggc_alloc<builtin_hash_struct> ();
|
||||
*h2 = h;
|
||||
*found = (void *)h2;
|
||||
*found = h2;
|
||||
|
||||
h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
|
||||
arg_type[2], NULL_TREE);
|
||||
}
|
||||
|
||||
return ((struct builtin_hash_struct *)(*found))->type;
|
||||
return (*found)->type;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -25561,24 +25566,21 @@ rs6000_hash_constant (rtx k)
|
||||
return result;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
toc_hash_function (const void *hash_entry)
|
||||
hashval_t
|
||||
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;
|
||||
}
|
||||
|
||||
/* Compare H1 and H2 for equivalence. */
|
||||
|
||||
static int
|
||||
toc_hash_eq (const void *h1, const void *h2)
|
||||
bool
|
||||
toc_hasher::equal (toc_hash_struct *h1, toc_hash_struct *h2)
|
||||
{
|
||||
rtx r1 = ((const struct toc_hash_struct *) h1)->key;
|
||||
rtx r2 = ((const struct toc_hash_struct *) h2)->key;
|
||||
rtx r1 = h1->key;
|
||||
rtx r2 = h2->key;
|
||||
|
||||
if (((const struct toc_hash_struct *) h1)->key_mode
|
||||
!= ((const struct toc_hash_struct *) h2)->key_mode)
|
||||
if (h1->key_mode != h2->key_mode)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
struct toc_hash_struct *h;
|
||||
void * * found;
|
||||
|
||||
/* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
|
||||
time because GGC is not initialized at that point. */
|
||||
if (toc_hash_table == NULL)
|
||||
toc_hash_table = htab_create_ggc (1021, toc_hash_function,
|
||||
toc_hash_eq, NULL);
|
||||
toc_hash_table = hash_table<toc_hasher>::create_ggc (1021);
|
||||
|
||||
h = ggc_alloc<toc_hash_struct> ();
|
||||
h->key = x;
|
||||
h->key_mode = mode;
|
||||
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)
|
||||
*found = h;
|
||||
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");
|
||||
fprintf (file, "%d,", labelno);
|
||||
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
|
||||
fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
|
||||
found)->labelno));
|
||||
fprintf (file, "%d\n", ((*found)->labelno));
|
||||
|
||||
#ifdef HAVE_AS_TLS
|
||||
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");
|
||||
fprintf (file, "%d,", labelno);
|
||||
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
|
||||
fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
|
||||
found)->labelno));
|
||||
fprintf (file, "%d\n", ((*found)->labelno));
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
|
@ -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>
|
||||
|
||||
PR c++/62115
|
||||
|
@ -758,20 +758,18 @@ is_invisiref_parm (const_tree t)
|
||||
|
||||
/* Return true if the uid in both int tree maps are equal. */
|
||||
|
||||
int
|
||||
cxx_int_tree_map_eq (const void *va, const void *vb)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
/* Hash a UID in a cxx_int_tree_map. */
|
||||
|
||||
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. */
|
||||
@ -911,9 +909,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
|
||||
{
|
||||
struct cxx_int_tree_map *h, in;
|
||||
in.uid = DECL_UID (stmt);
|
||||
h = (struct cxx_int_tree_map *)
|
||||
htab_find_with_hash (cp_function_chain->extern_decl_map,
|
||||
&in, in.uid);
|
||||
h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
|
||||
if (h)
|
||||
{
|
||||
*stmt_p = h->to;
|
||||
|
@ -1133,13 +1133,24 @@ struct GTY(()) saved_scope {
|
||||
|
||||
extern GTY(()) struct saved_scope *scope_chain;
|
||||
|
||||
struct GTY(()) cxx_int_tree_map {
|
||||
struct GTY((for_user)) cxx_int_tree_map {
|
||||
unsigned int uid;
|
||||
tree to;
|
||||
};
|
||||
|
||||
extern unsigned int cxx_int_tree_map_hash (const void *);
|
||||
extern int cxx_int_tree_map_eq (const void *, const void *);
|
||||
struct cxx_int_tree_map_hasher : ggc_hasher<cxx_int_tree_map *>
|
||||
{
|
||||
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. */
|
||||
|
||||
@ -1165,13 +1176,13 @@ struct GTY(()) language_function {
|
||||
/* True if this function can throw an exception. */
|
||||
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;
|
||||
vec<tree, va_gc> *x_local_names;
|
||||
/* Tracking possibly infinite loops. This is a vec<tree> only because
|
||||
vec<bool> doesn't work with gtype. */
|
||||
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. */
|
||||
|
124
gcc/cp/decl.c
124
gcc/cp/decl.c
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "stringpool.h"
|
||||
#include "stor-layout.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,
|
||||
int);
|
||||
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 record_builtin_java_type (const char *, int);
|
||||
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
|
||||
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. */
|
||||
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
|
||||
function. */
|
||||
|
||||
static int
|
||||
pop_labels_1 (void **slot, void *data)
|
||||
int
|
||||
pop_labels_1 (named_label_entry **slot, tree block)
|
||||
{
|
||||
struct named_label_entry *ent = (struct named_label_entry *) *slot;
|
||||
tree block = (tree) data;
|
||||
struct named_label_entry *ent = *slot;
|
||||
|
||||
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);
|
||||
BLOCK_VARS (block) = ent->label_decl;
|
||||
|
||||
htab_clear_slot (named_labels, slot);
|
||||
named_labels->clear_slot (slot);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -417,7 +415,7 @@ pop_labels (tree block)
|
||||
{
|
||||
if (named_labels)
|
||||
{
|
||||
htab_traverse (named_labels, pop_labels_1, block);
|
||||
named_labels->traverse<tree, pop_labels_1> (block);
|
||||
named_labels = NULL;
|
||||
}
|
||||
}
|
||||
@ -428,13 +426,12 @@ static void
|
||||
pop_local_label (tree label, tree old_value)
|
||||
{
|
||||
struct named_label_entry dummy;
|
||||
void **slot;
|
||||
|
||||
pop_label (label, old_value);
|
||||
|
||||
dummy.label_decl = label;
|
||||
slot = htab_find_slot (named_labels, &dummy, NO_INSERT);
|
||||
htab_clear_slot (named_labels, slot);
|
||||
named_label_entry **slot = named_labels->find_slot (&dummy, NO_INSERT);
|
||||
named_labels->clear_slot (slot);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
static int
|
||||
poplevel_named_label_1 (void **slot, void *data)
|
||||
int
|
||||
poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
|
||||
{
|
||||
struct named_label_entry *ent = (struct named_label_entry *) *slot;
|
||||
cp_binding_level *bl = (cp_binding_level *) data;
|
||||
named_label_entry *ent = *slot;
|
||||
cp_binding_level *obl = bl->level_chain;
|
||||
|
||||
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
|
||||
under constraints of next binding contour. */
|
||||
if (cfun && !functionbody && named_labels)
|
||||
htab_traverse (named_labels, poplevel_named_label_1,
|
||||
current_binding_level);
|
||||
named_labels->traverse<cp_binding_level *, poplevel_named_label_1>
|
||||
(current_binding_level);
|
||||
|
||||
/* Get the decls in the order they were written.
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
named_label_entry_hash (const void *data)
|
||||
hashval_t
|
||||
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);
|
||||
}
|
||||
|
||||
static int
|
||||
named_label_entry_eq (const void *a, const void *b)
|
||||
bool
|
||||
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;
|
||||
const struct named_label_entry *ent_b = (const struct named_label_entry *) b;
|
||||
return ent_a->label_decl == ent_b->label_decl;
|
||||
return a->label_decl == b->label_decl;
|
||||
}
|
||||
|
||||
/* Create a new label, named ID. */
|
||||
@ -2738,7 +2731,6 @@ static tree
|
||||
make_label_decl (tree id, int local_p)
|
||||
{
|
||||
struct named_label_entry *ent;
|
||||
void **slot;
|
||||
tree decl;
|
||||
|
||||
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. */
|
||||
if (!named_labels)
|
||||
named_labels = htab_create_ggc (13, named_label_entry_hash,
|
||||
named_label_entry_eq, NULL);
|
||||
named_labels = hash_table<named_label_hasher>::create_ggc (13);
|
||||
|
||||
/* 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
|
||||
@ -2765,7 +2756,7 @@ make_label_decl (tree id, int local_p)
|
||||
ent = ggc_cleared_alloc<named_label_entry> ();
|
||||
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);
|
||||
*slot = ent;
|
||||
|
||||
@ -2979,7 +2970,7 @@ check_goto (tree decl)
|
||||
return;
|
||||
|
||||
dummy.label_decl = decl;
|
||||
ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
|
||||
ent = named_labels->find (&dummy);
|
||||
gcc_assert (ent != NULL);
|
||||
|
||||
/* 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);
|
||||
|
||||
dummy.label_decl = decl;
|
||||
ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
|
||||
ent = named_labels->find (&dummy);
|
||||
gcc_assert (ent != NULL);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
|
||||
|
||||
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 {
|
||||
struct typename_info {
|
||||
tree scope;
|
||||
tree name;
|
||||
tree template_id;
|
||||
bool enum_p;
|
||||
bool class_p;
|
||||
} typename_info;
|
||||
};
|
||||
|
||||
/* Compare two TYPENAME_TYPEs. K1 is really of type `tree', K2 is
|
||||
really of type `typename_info*' */
|
||||
|
||||
static int
|
||||
typename_compare (const void * k1, const void * k2)
|
||||
struct typename_hasher : ggc_hasher<tree>
|
||||
{
|
||||
const_tree const t1 = (const_tree) k1;
|
||||
const typename_info *const t2 = (const typename_info *) k2;
|
||||
typedef typename_info *compare_type;
|
||||
|
||||
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);
|
||||
}
|
||||
/* Hash a TYPENAME_TYPE. */
|
||||
|
||||
static hashval_t
|
||||
hash (tree t)
|
||||
{
|
||||
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
|
||||
the type of `T', NAME is the IDENTIFIER_NODE for `t'.
|
||||
|
||||
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
|
||||
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 d;
|
||||
typename_info ti;
|
||||
void **e;
|
||||
tree *e;
|
||||
hashval_t hash;
|
||||
|
||||
if (typename_htab == NULL)
|
||||
typename_htab = htab_create_ggc (61, &typename_hash,
|
||||
&typename_compare, NULL);
|
||||
typename_htab = hash_table<typename_hasher>::create_ggc (61);
|
||||
|
||||
ti.scope = FROB_CONTEXT (context);
|
||||
ti.name = name;
|
||||
@ -3334,9 +3324,9 @@ build_typename_type (tree context, tree name, tree fullname,
|
||||
^ htab_hash_pointer (ti.name));
|
||||
|
||||
/* 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)
|
||||
t = (tree) *e;
|
||||
t = *e;
|
||||
else
|
||||
{
|
||||
/* Build the TYPENAME_TYPE. */
|
||||
|
@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "stor-layout.h"
|
||||
#include "stringpool.h"
|
||||
#include "tm_p.h"
|
||||
@ -3690,26 +3691,32 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
|
||||
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
|
||||
operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
hash_type (const void *val)
|
||||
hashval_t
|
||||
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). */
|
||||
|
||||
static int
|
||||
compare_type (const void *val1, const void *val2)
|
||||
bool
|
||||
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
|
||||
@ -3719,25 +3726,25 @@ compare_type (const void *val1, const void *val2)
|
||||
tree
|
||||
mangle_conv_op_name_for_type (const tree type)
|
||||
{
|
||||
void **slot;
|
||||
tree *slot;
|
||||
tree identifier;
|
||||
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
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,
|
||||
(hashval_t) TYPE_UID (type), INSERT);
|
||||
identifier = (tree)*slot;
|
||||
slot = conv_type_names->find_slot_with_hash (type,
|
||||
(hashval_t) TYPE_UID (type),
|
||||
INSERT);
|
||||
identifier = *slot;
|
||||
if (!identifier)
|
||||
{
|
||||
char buffer[64];
|
||||
|
||||
/* Create a unique name corresponding to TYPE. */
|
||||
sprintf (buffer, "operator %lu",
|
||||
(unsigned long) htab_elements (conv_type_names));
|
||||
sprintf (buffer, "operator %lu", conv_type_names->elements ());
|
||||
identifier = get_identifier (buffer);
|
||||
*slot = identifier;
|
||||
|
||||
|
@ -766,22 +766,19 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
|
||||
middle end. */
|
||||
{
|
||||
struct cxx_int_tree_map *h;
|
||||
void **loc;
|
||||
|
||||
TREE_PUBLIC (x) = TREE_PUBLIC (t);
|
||||
|
||||
if (cp_function_chain->extern_decl_map == NULL)
|
||||
cp_function_chain->extern_decl_map
|
||||
= htab_create_ggc (20, cxx_int_tree_map_hash,
|
||||
cxx_int_tree_map_eq, NULL);
|
||||
= hash_table<cxx_int_tree_map_hasher>::create_ggc (20);
|
||||
|
||||
h = ggc_alloc<cxx_int_tree_map> ();
|
||||
h->uid = DECL_UID (x);
|
||||
h->to = t;
|
||||
loc = htab_find_slot_with_hash
|
||||
(cp_function_chain->extern_decl_map, h,
|
||||
h->uid, INSERT);
|
||||
*(struct cxx_int_tree_map **) loc = h;
|
||||
cxx_int_tree_map **loc = cp_function_chain->extern_decl_map
|
||||
->find_slot (h, INSERT);
|
||||
*loc = h;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (t) == PARM_DECL)
|
||||
|
82
gcc/cp/pt.c
82
gcc/cp/pt.c
@ -80,18 +80,22 @@ static tree cur_stmt_expr;
|
||||
/* True if we've recursed into fn_type_unification too many times. */
|
||||
static bool excessive_deduction_depth;
|
||||
|
||||
typedef struct GTY(()) spec_entry
|
||||
struct GTY((for_user)) spec_entry
|
||||
{
|
||||
tree tmpl;
|
||||
tree args;
|
||||
tree spec;
|
||||
} spec_entry;
|
||||
};
|
||||
|
||||
static GTY ((param_is (spec_entry)))
|
||||
htab_t decl_specializations;
|
||||
struct spec_hasher : ggc_hasher<spec_entry *>
|
||||
{
|
||||
static hashval_t hash (spec_entry *);
|
||||
static bool equal (spec_entry *, spec_entry *);
|
||||
};
|
||||
|
||||
static GTY ((param_is (spec_entry)))
|
||||
htab_t type_specializations;
|
||||
static GTY (()) hash_table<spec_hasher> *decl_specializations;
|
||||
|
||||
static GTY (()) hash_table<spec_hasher> *type_specializations;
|
||||
|
||||
/* Contains canonical template parameter types. The vector is indexed by
|
||||
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 tree retrieve_local_specialization (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 int mark_template_parm (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. */
|
||||
spec_entry elt;
|
||||
spec_entry *entry;
|
||||
void **slot;
|
||||
|
||||
elt.tmpl = most_general_template (tmpl);
|
||||
elt.args = CLASSTYPE_TI_ARGS (inst);
|
||||
elt.spec = inst;
|
||||
|
||||
htab_remove_elt (type_specializations, &elt);
|
||||
type_specializations->remove_elt (&elt);
|
||||
|
||||
elt.tmpl = tmpl;
|
||||
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 = elt;
|
||||
*slot = entry;
|
||||
@ -1085,7 +1088,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
|
||||
{
|
||||
spec_entry *found;
|
||||
spec_entry elt;
|
||||
htab_t specializations;
|
||||
hash_table<spec_hasher> *specializations;
|
||||
|
||||
elt.tmpl = tmpl;
|
||||
elt.args = args;
|
||||
@ -1097,8 +1100,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
|
||||
specializations = decl_specializations;
|
||||
|
||||
if (hash == 0)
|
||||
hash = hash_specialization (&elt);
|
||||
found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash);
|
||||
hash = spec_hasher::hash (&elt);
|
||||
found = specializations->find_with_hash (&elt, hash);
|
||||
if (found)
|
||||
return found->spec;
|
||||
}
|
||||
@ -1343,7 +1346,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
|
||||
hashval_t hash)
|
||||
{
|
||||
tree fn;
|
||||
void **slot = NULL;
|
||||
spec_entry **slot = NULL;
|
||||
spec_entry elt;
|
||||
|
||||
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;
|
||||
|
||||
if (hash == 0)
|
||||
hash = hash_specialization (&elt);
|
||||
hash = spec_hasher::hash (&elt);
|
||||
|
||||
slot =
|
||||
htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT);
|
||||
decl_specializations->find_slot_with_hash (&elt, hash, INSERT);
|
||||
if (*slot)
|
||||
fn = ((spec_entry *) *slot)->spec;
|
||||
else
|
||||
@ -1500,11 +1503,9 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
|
||||
|
||||
int comparing_specializations;
|
||||
|
||||
static int
|
||||
eq_specializations (const void *p1, const void *p2)
|
||||
bool
|
||||
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;
|
||||
|
||||
++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,
|
||||
ignoring SPEC. */
|
||||
|
||||
static hashval_t
|
||||
hash_specialization (const void *p)
|
||||
hashval_t
|
||||
spec_hasher::hash (spec_entry *e)
|
||||
{
|
||||
const spec_entry *e = (const spec_entry *)p;
|
||||
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.spec = NULL_TREE;
|
||||
|
||||
entry = (spec_entry *) htab_find (decl_specializations, &elt);
|
||||
entry = decl_specializations->find (&elt);
|
||||
if (entry != NULL)
|
||||
{
|
||||
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 t;
|
||||
void **slot;
|
||||
spec_entry **slot;
|
||||
spec_entry *entry;
|
||||
spec_entry elt;
|
||||
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. */
|
||||
elt.tmpl = gen_tmpl;
|
||||
elt.args = arglist;
|
||||
hash = hash_specialization (&elt);
|
||||
entry = (spec_entry *) htab_find_with_hash (type_specializations,
|
||||
&elt, hash);
|
||||
hash = spec_hasher::hash (&elt);
|
||||
entry = type_specializations->find_with_hash (&elt, hash);
|
||||
|
||||
if (entry)
|
||||
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));
|
||||
|
||||
elt.spec = t;
|
||||
slot = htab_find_slot_with_hash (type_specializations,
|
||||
&elt, hash, INSERT);
|
||||
slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
|
||||
entry = ggc_alloc<spec_entry> ();
|
||||
*entry = elt;
|
||||
*slot = entry;
|
||||
@ -8652,7 +8650,7 @@ tsubst_friend_function (tree decl, tree args)
|
||||
elt.args = DECL_TI_ARGS (spec);
|
||||
elt.spec = NULL_TREE;
|
||||
|
||||
htab_remove_elt (decl_specializations, &elt);
|
||||
decl_specializations->remove_elt (&elt);
|
||||
|
||||
DECL_TI_ARGS (spec)
|
||||
= add_outermost_template_args (new_args,
|
||||
@ -22316,14 +22314,8 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
|
||||
void
|
||||
init_template_processing (void)
|
||||
{
|
||||
decl_specializations = htab_create_ggc (37,
|
||||
hash_specialization,
|
||||
eq_specializations,
|
||||
ggc_free);
|
||||
type_specializations = htab_create_ggc (37,
|
||||
hash_specialization,
|
||||
eq_specializations,
|
||||
ggc_free);
|
||||
decl_specializations = hash_table<spec_hasher>::create_ggc (37);
|
||||
type_specializations = hash_table<spec_hasher>::create_ggc (37);
|
||||
}
|
||||
|
||||
/* Print stats about the template hash tables for -fstats. */
|
||||
@ -22332,13 +22324,13 @@ void
|
||||
print_template_statistics (void)
|
||||
{
|
||||
fprintf (stderr, "decl_specializations: size %ld, %ld elements, "
|
||||
"%f collisions\n", (long) htab_size (decl_specializations),
|
||||
(long) htab_elements (decl_specializations),
|
||||
htab_collisions (decl_specializations));
|
||||
"%f collisions\n", decl_specializations->size (),
|
||||
decl_specializations->elements (),
|
||||
decl_specializations->collisions ());
|
||||
fprintf (stderr, "type_specializations: size %ld, %ld elements, "
|
||||
"%f collisions\n", (long) htab_size (type_specializations),
|
||||
(long) htab_elements (type_specializations),
|
||||
htab_collisions (type_specializations));
|
||||
"%f collisions\n", type_specializations->size (),
|
||||
type_specializations->elements (),
|
||||
type_specializations->collisions ());
|
||||
}
|
||||
|
||||
#include "gt-cp-pt.h"
|
||||
|
@ -7579,35 +7579,38 @@ ensure_literal_type_for_constexpr_object (tree decl)
|
||||
|
||||
/* Representation of entries in the constexpr function definition table. */
|
||||
|
||||
typedef struct GTY(()) constexpr_fundef {
|
||||
struct GTY((for_user)) constexpr_fundef {
|
||||
tree decl;
|
||||
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
|
||||
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.
|
||||
Return true if the entries pointed to by P and Q are for the
|
||||
same constexpr function. */
|
||||
|
||||
static inline int
|
||||
constexpr_fundef_equal (const void *p, const void *q)
|
||||
inline bool
|
||||
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;
|
||||
}
|
||||
|
||||
/* Utility function used for managing the constexpr function table.
|
||||
Return a hash value for the entry pointed to by Q. */
|
||||
|
||||
static inline hashval_t
|
||||
constexpr_fundef_hash (const void *p)
|
||||
inline hashval_t
|
||||
constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
|
||||
{
|
||||
const constexpr_fundef *fundef = (const constexpr_fundef *) p;
|
||||
return DECL_UID (fundef->decl);
|
||||
}
|
||||
|
||||
@ -7621,7 +7624,7 @@ retrieve_constexpr_fundef (tree fun)
|
||||
return NULL;
|
||||
|
||||
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
|
||||
@ -8236,14 +8239,12 @@ register_constexpr_fundef (tree fun, tree body)
|
||||
|
||||
/* Create the constexpr function table if necessary. */
|
||||
if (constexpr_fundef_table == NULL)
|
||||
constexpr_fundef_table = htab_create_ggc (101,
|
||||
constexpr_fundef_hash,
|
||||
constexpr_fundef_equal,
|
||||
ggc_free);
|
||||
constexpr_fundef_table
|
||||
= hash_table<constexpr_fundef_hasher>::create_ggc (101);
|
||||
|
||||
entry.decl = fun;
|
||||
entry.body = body;
|
||||
slot = (constexpr_fundef **)
|
||||
htab_find_slot (constexpr_fundef_table, &entry, INSERT);
|
||||
slot = constexpr_fundef_table->find_slot (&entry, INSERT);
|
||||
|
||||
gcc_assert (*slot == NULL);
|
||||
*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
|
||||
the purpose of compile time evaluation. */
|
||||
|
||||
typedef struct GTY(()) constexpr_call {
|
||||
struct GTY((for_user)) constexpr_call {
|
||||
/* Description of the constexpr function definition. */
|
||||
constexpr_fundef *fundef;
|
||||
/* 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
|
||||
recalculate it when expanding the hash table. */
|
||||
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
|
||||
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,
|
||||
bool, bool, bool *, bool *);
|
||||
|
||||
/* Compute a hash value for a constexpr call representation. */
|
||||
|
||||
static hashval_t
|
||||
constexpr_call_hash (const void *p)
|
||||
inline hashval_t
|
||||
constexpr_call_hasher::hash (constexpr_call *info)
|
||||
{
|
||||
const constexpr_call *info = (const constexpr_call *) p;
|
||||
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.
|
||||
Otherwise, return 0. */
|
||||
Otherwise, return false. */
|
||||
|
||||
static int
|
||||
constexpr_call_equal (const void *p, const void *q)
|
||||
bool
|
||||
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 rhs_bindings;
|
||||
if (lhs == rhs)
|
||||
return 1;
|
||||
if (!constexpr_fundef_equal (lhs->fundef, rhs->fundef))
|
||||
if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
|
||||
return 0;
|
||||
lhs_bindings = lhs->bindings;
|
||||
rhs_bindings = rhs->bindings;
|
||||
@ -8369,10 +8373,7 @@ static void
|
||||
maybe_initialize_constexpr_call_table (void)
|
||||
{
|
||||
if (constexpr_call_table == NULL)
|
||||
constexpr_call_table = htab_create_ggc (101,
|
||||
constexpr_call_hash,
|
||||
constexpr_call_equal,
|
||||
ggc_free);
|
||||
constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
|
||||
}
|
||||
|
||||
/* 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
|
||||
= 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. */
|
||||
maybe_initialize_constexpr_call_table ();
|
||||
slot = (constexpr_call **)
|
||||
htab_find_slot (constexpr_call_table, &new_call, INSERT);
|
||||
slot = constexpr_call_table->find_slot (&new_call, INSERT);
|
||||
entry = *slot;
|
||||
if (entry == NULL)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "stor-layout.h"
|
||||
#include "print-tree.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_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 (const void *);
|
||||
static tree build_target_expr (tree, tree, tsubst_flags_t);
|
||||
static tree count_trees_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'. */
|
||||
|
||||
static hashval_t
|
||||
cplus_array_hash (const void* k)
|
||||
hashval_t
|
||||
cplus_array_hasher::hash (tree t)
|
||||
{
|
||||
hashval_t hash;
|
||||
const_tree const t = (const_tree) k;
|
||||
|
||||
hash = TYPE_UID (TREE_TYPE (t));
|
||||
if (TYPE_DOMAIN (t))
|
||||
@ -736,26 +748,18 @@ cplus_array_hash (const void* k)
|
||||
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
|
||||
of type `cplus_array_info*'. */
|
||||
|
||||
static int
|
||||
cplus_array_compare (const void * k1, const void * k2)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
/* Hash table containing dependent array types, which are unsuitable for
|
||||
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. */
|
||||
|
||||
@ -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
|
||||
hash table. */
|
||||
void **e;
|
||||
cplus_array_info cai;
|
||||
hashval_t hash;
|
||||
|
||||
if (cplus_array_htab == NULL)
|
||||
cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
|
||||
&cplus_array_compare, NULL);
|
||||
cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
|
||||
|
||||
hash = TYPE_UID (elt_type);
|
||||
if (index_type)
|
||||
@ -827,7 +829,7 @@ build_cplus_array_type (tree elt_type, tree index_type)
|
||||
cai.type = elt_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)
|
||||
/* We have found the type: we're done. */
|
||||
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.
|
||||
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
|
||||
{
|
||||
tree purpose;
|
||||
@ -1656,15 +1650,28 @@ struct list_proxy
|
||||
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
|
||||
for a node we are thinking about adding). */
|
||||
|
||||
static int
|
||||
list_hash_eq (const void* entry, const void* data)
|
||||
bool
|
||||
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
|
||||
&& TREE_PURPOSE (t) == proxy->purpose
|
||||
&& TREE_CHAIN (t) == proxy->chain);
|
||||
@ -1695,10 +1702,9 @@ list_hash_pieces (tree purpose, tree value, tree chain)
|
||||
|
||||
/* Hash an already existing TREE_LIST. */
|
||||
|
||||
static hashval_t
|
||||
list_hash (const void* p)
|
||||
hashval_t
|
||||
list_hasher::hash (tree t)
|
||||
{
|
||||
const_tree const t = (const_tree) p;
|
||||
return list_hash_pieces (TREE_PURPOSE (t),
|
||||
TREE_VALUE (t),
|
||||
TREE_CHAIN (t));
|
||||
@ -1712,7 +1718,7 @@ tree
|
||||
hash_tree_cons (tree purpose, tree value, tree chain)
|
||||
{
|
||||
int hashcode = 0;
|
||||
void **slot;
|
||||
tree *slot;
|
||||
struct list_proxy proxy;
|
||||
|
||||
/* Hash the list node. */
|
||||
@ -1723,8 +1729,7 @@ hash_tree_cons (tree purpose, tree value, tree chain)
|
||||
proxy.value = value;
|
||||
proxy.chain = chain;
|
||||
/* See if it is already in the table. */
|
||||
slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode,
|
||||
INSERT);
|
||||
slot = list_hash_table->find_slot_with_hash (&proxy, hashcode, INSERT);
|
||||
/* If not, create a new node. */
|
||||
if (!*slot)
|
||||
*slot = tree_cons (purpose, value, chain);
|
||||
@ -3670,7 +3675,7 @@ cp_save_expr (tree expr)
|
||||
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)
|
||||
|
@ -135,7 +135,7 @@ cxx_readonly_error (tree arg, enum lvalue_use errstring)
|
||||
/* Structure that holds information about declarations whose type was
|
||||
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
|
||||
a DECL node, or an IDENTIFIER_NODE if we do not have a full
|
||||
declaration available. */
|
||||
@ -155,15 +155,19 @@ struct GTY((chain_next ("%h.next"))) pending_abstract_type {
|
||||
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
|
||||
hash table abstract_pending_vars. */
|
||||
|
||||
static hashval_t
|
||||
pat_calc_hash (const void* val)
|
||||
hashval_t
|
||||
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);
|
||||
}
|
||||
|
||||
@ -171,21 +175,16 @@ pat_calc_hash (const void* val)
|
||||
/* Compare node VAL1 with the type VAL2. This function is used by the
|
||||
hash table abstract_pending_vars. */
|
||||
|
||||
static int
|
||||
pat_compare (const void* val1, const void* val2)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
of the declaration. */
|
||||
static GTY ((param_is (struct pending_abstract_type)))
|
||||
htab_t abstract_pending_vars = NULL;
|
||||
static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
|
||||
|
||||
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
|
||||
complete_type_check_abstract (tree type)
|
||||
{
|
||||
void **slot;
|
||||
struct pending_abstract_type *pat;
|
||||
location_t cur_loc = input_location;
|
||||
|
||||
@ -207,11 +205,12 @@ complete_type_check_abstract (tree type)
|
||||
return;
|
||||
|
||||
/* Retrieve the list of pending declarations for this type. */
|
||||
slot = htab_find_slot_with_hash (abstract_pending_vars, type,
|
||||
(hashval_t)TYPE_UID (type), NO_INSERT);
|
||||
pending_abstract_type **slot
|
||||
= abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
|
||||
NO_INSERT);
|
||||
if (!slot)
|
||||
return;
|
||||
pat = (struct pending_abstract_type*)*slot;
|
||||
pat = *slot;
|
||||
gcc_assert (pat);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@ -282,17 +281,17 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
|
||||
name. */
|
||||
if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
|
||||
{
|
||||
void **slot;
|
||||
struct pending_abstract_type *pat;
|
||||
|
||||
gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
|
||||
|
||||
if (!abstract_pending_vars)
|
||||
abstract_pending_vars = htab_create_ggc (31, &pat_calc_hash,
|
||||
&pat_compare, NULL);
|
||||
abstract_pending_vars
|
||||
= hash_table<abstract_type_hasher>::create_ggc (31);
|
||||
|
||||
slot = htab_find_slot_with_hash (abstract_pending_vars, type,
|
||||
(hashval_t)TYPE_UID (type), INSERT);
|
||||
pending_abstract_type **slot
|
||||
= abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
|
||||
INSERT);
|
||||
|
||||
pat = ggc_alloc<pending_abstract_type> ();
|
||||
pat->type = type;
|
||||
@ -302,7 +301,7 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
|
||||
? DECL_SOURCE_LOCATION (decl)
|
||||
: input_location);
|
||||
|
||||
pat->next = (struct pending_abstract_type *) *slot;
|
||||
pat->next = *slot;
|
||||
*slot = pat;
|
||||
|
||||
return 0;
|
||||
|
@ -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
|
||||
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 tag
|
||||
@findex default
|
||||
|
395
gcc/dwarf2out.c
395
gcc/dwarf2out.c
@ -205,7 +205,7 @@ static GTY(()) section *debug_frame_section;
|
||||
|
||||
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;
|
||||
unsigned int refcount;
|
||||
enum dwarf_form form;
|
||||
@ -213,7 +213,15 @@ struct GTY(()) indirect_string_node {
|
||||
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
|
||||
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
|
||||
that need it. */
|
||||
|
||||
static GTY ((param_is (struct indirect_string_node)))
|
||||
htab_t skeleton_debug_str_hash;
|
||||
static GTY (()) hash_table<indirect_string_hasher> *skeleton_debug_str_hash;
|
||||
|
||||
static GTY(()) int dw2_string_counter;
|
||||
|
||||
@ -1235,7 +1242,7 @@ dwarf2out_switch_text_section (void)
|
||||
for emitting location expressions. */
|
||||
|
||||
/* Data about a single source file. */
|
||||
struct GTY(()) dwarf_file_data {
|
||||
struct GTY((for_user)) dwarf_file_data {
|
||||
const char * filename;
|
||||
int emitted_number;
|
||||
};
|
||||
@ -1258,7 +1265,7 @@ enum ate_kind {
|
||||
ate_kind_label
|
||||
};
|
||||
|
||||
typedef struct GTY(()) addr_table_entry_struct {
|
||||
typedef struct GTY((for_user)) addr_table_entry_struct {
|
||||
enum ate_kind kind;
|
||||
unsigned int refcount;
|
||||
unsigned int index;
|
||||
@ -2417,7 +2424,6 @@ build_cfa_aligned_loc (dw_cfa_location *cfa,
|
||||
/* And now, the support for symbolic debugging information. */
|
||||
|
||||
/* .debug_str support. */
|
||||
static int output_indirect_string (void **, void *);
|
||||
|
||||
static void dwarf2out_init (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
|
||||
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
|
||||
{
|
||||
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. */
|
||||
static GTY(()) limbo_die_node *deferred_asm_name;
|
||||
|
||||
/* Filenames referenced by this compilation unit. */
|
||||
static GTY((param_is (struct dwarf_file_data))) htab_t file_table;
|
||||
struct dwarf_file_hasher : ggc_hasher<dwarf_file_data *>
|
||||
{
|
||||
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.
|
||||
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.
|
||||
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 {
|
||||
dw_die_ref die;
|
||||
@ -2808,7 +2835,7 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node {
|
||||
};
|
||||
|
||||
/* Variable location list. */
|
||||
struct GTY (()) var_loc_list_def {
|
||||
struct GTY ((for_user)) var_loc_list_def {
|
||||
struct var_loc_node * GTY (()) first;
|
||||
|
||||
/* 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. */
|
||||
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. */
|
||||
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;
|
||||
|
||||
/* 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. */
|
||||
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;
|
||||
|
||||
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. */
|
||||
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
|
||||
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,
|
||||
unsigned int, 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 inline const char *AT_string (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 lookup_type_die_strip_naming_typedef (tree);
|
||||
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 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 void equate_decl_number_to_die (tree, dw_die_ref);
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
debug_str_do_hash (const void *x)
|
||||
hashval_t
|
||||
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
|
||||
debug_str_eq (const void *x1, const void *x2)
|
||||
bool
|
||||
indirect_string_hasher::equal (indirect_string_node *x1, const char *x2)
|
||||
{
|
||||
return strcmp ((((const struct indirect_string_node *)x1)->str),
|
||||
(const char *)x2) == 0;
|
||||
return strcmp (x1->str, x2) == 0;
|
||||
}
|
||||
|
||||
/* Add STR to the given string hash table. */
|
||||
|
||||
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;
|
||||
void **slot;
|
||||
|
||||
slot = htab_find_slot_with_hash (table, str,
|
||||
htab_hash_string (str), INSERT);
|
||||
indirect_string_node **slot
|
||||
= table->find_slot_with_hash (str, htab_hash_string (str), INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
node = ggc_cleared_alloc<indirect_string_node> ();
|
||||
@ -3938,7 +3973,7 @@ find_AT_string_in_table (const char *str, htab_t table)
|
||||
*slot = node;
|
||||
}
|
||||
else
|
||||
node = (struct indirect_string_node *) *slot;
|
||||
node = *slot;
|
||||
|
||||
node->refcount++;
|
||||
return node;
|
||||
@ -3950,8 +3985,7 @@ static struct indirect_string_node *
|
||||
find_AT_string (const char *str)
|
||||
{
|
||||
if (! debug_str_hash)
|
||||
debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
|
||||
debug_str_eq, NULL);
|
||||
debug_str_hash = hash_table<indirect_string_hasher>::create_ggc (10);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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. */
|
||||
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
addr_table_entry_do_hash (const void *x)
|
||||
hashval_t
|
||||
addr_hasher::hash (addr_table_entry *a)
|
||||
{
|
||||
const addr_table_entry *a = (const addr_table_entry *) x;
|
||||
inchash::hash hstate;
|
||||
switch (a->kind)
|
||||
{
|
||||
@ -4210,12 +4249,9 @@ addr_table_entry_do_hash (const void *x)
|
||||
|
||||
/* Determine equality for two address_table_entries. */
|
||||
|
||||
static int
|
||||
addr_table_entry_eq (const void *x1, const void *x2)
|
||||
bool
|
||||
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)
|
||||
return 0;
|
||||
switch (a1->kind)
|
||||
@ -4258,14 +4294,12 @@ add_addr_table_entry (void *addr, enum ate_kind kind)
|
||||
{
|
||||
addr_table_entry *node;
|
||||
addr_table_entry finder;
|
||||
void **slot;
|
||||
|
||||
gcc_assert (dwarf_split_debug_info);
|
||||
if (! addr_index_table)
|
||||
addr_index_table = htab_create_ggc (10, addr_table_entry_do_hash,
|
||||
addr_table_entry_eq, NULL);
|
||||
addr_index_table = hash_table<addr_hasher>::create_ggc (10);
|
||||
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)
|
||||
{
|
||||
@ -4274,7 +4308,7 @@ add_addr_table_entry (void *addr, enum ate_kind kind)
|
||||
*slot = node;
|
||||
}
|
||||
else
|
||||
node = (addr_table_entry *) *slot;
|
||||
node = *slot;
|
||||
|
||||
node->refcount++;
|
||||
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
|
||||
in the same order for each run. */
|
||||
|
||||
static int
|
||||
index_addr_table_entry (void **h, void *v)
|
||||
int
|
||||
index_addr_table_entry (addr_table_entry **h, unsigned int *index)
|
||||
{
|
||||
addr_table_entry *node = (addr_table_entry *) *h;
|
||||
unsigned int *index = (unsigned int *) v;
|
||||
addr_table_entry *node = *h;
|
||||
|
||||
/* Don't index unreferenced nodes. */
|
||||
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). */
|
||||
|
||||
static hashval_t
|
||||
decl_die_table_hash (const void *x)
|
||||
inline hashval_t
|
||||
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. */
|
||||
|
||||
static int
|
||||
decl_die_table_eq (const void *x, const void *y)
|
||||
inline bool
|
||||
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. */
|
||||
@ -4932,24 +4965,24 @@ decl_die_table_eq (const void *x, const void *y)
|
||||
static inline dw_die_ref
|
||||
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). */
|
||||
|
||||
static hashval_t
|
||||
decl_loc_table_hash (const void *x)
|
||||
inline hashval_t
|
||||
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
|
||||
UID of decl *Y. */
|
||||
|
||||
static int
|
||||
decl_loc_table_eq (const void *x, const void *y)
|
||||
inline bool
|
||||
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. */
|
||||
@ -4959,26 +4992,24 @@ lookup_decl_loc (const_tree decl)
|
||||
{
|
||||
if (!decl_loc_table)
|
||||
return NULL;
|
||||
return (var_loc_list *)
|
||||
htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
|
||||
return decl_loc_table->find_with_hash (decl, DECL_UID (decl));
|
||||
}
|
||||
|
||||
/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */
|
||||
|
||||
static hashval_t
|
||||
cached_dw_loc_list_table_hash (const void *x)
|
||||
inline hashval_t
|
||||
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
|
||||
UID of decl *Y. */
|
||||
|
||||
static int
|
||||
cached_dw_loc_list_table_eq (const void *x, const void *y)
|
||||
inline bool
|
||||
dw_loc_list_hasher::equal (cached_dw_loc_list *x, const_tree y)
|
||||
{
|
||||
return (((const cached_dw_loc_list *) x)->decl_id
|
||||
== DECL_UID ((const_tree) y));
|
||||
return (x->decl_id == DECL_UID (y));
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
unsigned int decl_id = DECL_UID (decl);
|
||||
void **slot;
|
||||
|
||||
slot = htab_find_slot_with_hash (decl_die_table, decl, decl_id, INSERT);
|
||||
*slot = decl_die;
|
||||
*decl_die_table->find_slot_with_hash (decl, decl_id, INSERT) = decl_die;
|
||||
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;
|
||||
var_loc_list *temp;
|
||||
void **slot;
|
||||
struct var_loc_node *loc = NULL;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
temp = (var_loc_list *) *slot;
|
||||
temp = *slot;
|
||||
|
||||
/* For PARM_DECLs try to keep around the original incoming value,
|
||||
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;
|
||||
|
||||
if (! skeleton_debug_str_hash)
|
||||
skeleton_debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
|
||||
debug_str_eq, NULL);
|
||||
skeleton_debug_str_hash
|
||||
= hash_table<indirect_string_hasher>::create_ggc (10);
|
||||
|
||||
node = find_AT_string_in_table (str, skeleton_debug_str_hash);
|
||||
find_string_form (node);
|
||||
@ -9739,11 +9768,10 @@ struct file_name_acquire_data
|
||||
|
||||
/* Traversal function for the hash table. */
|
||||
|
||||
static int
|
||||
file_name_acquire (void ** slot, void *data)
|
||||
int
|
||||
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 = (struct dwarf_file_data *) *slot;
|
||||
struct dwarf_file_data *d = *slot;
|
||||
struct file_info *fi;
|
||||
const char *f;
|
||||
|
||||
@ -9818,7 +9846,7 @@ output_file_names (void)
|
||||
fnad.files = files;
|
||||
fnad.used_files = 0;
|
||||
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);
|
||||
|
||||
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;
|
||||
var_loc_list *loc_list;
|
||||
cached_dw_loc_list *cache;
|
||||
void **slot;
|
||||
|
||||
if (TREE_CODE (decl) == ERROR_MARK)
|
||||
return false;
|
||||
@ -15856,8 +15883,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
|
||||
cache_p = false;
|
||||
if (cache_p)
|
||||
{
|
||||
cache = (cached_dw_loc_list *)
|
||||
htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl));
|
||||
cache = cached_dw_loc_list_table->find_with_hash (decl, DECL_UID (decl));
|
||||
if (cache)
|
||||
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. */
|
||||
if (cache_p && list && list->dw_loc_next)
|
||||
{
|
||||
slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl,
|
||||
DECL_UID (decl), INSERT);
|
||||
cached_dw_loc_list **slot
|
||||
= cached_dw_loc_list_table->find_slot_with_hash (decl,
|
||||
DECL_UID (decl),
|
||||
INSERT);
|
||||
cache = ggc_cleared_alloc<cached_dw_loc_list> ();
|
||||
cache->decl_id = DECL_UID (decl);
|
||||
cache->loc_list = list;
|
||||
@ -17991,8 +18019,8 @@ dwarf2out_abstract_function (tree decl)
|
||||
tree save_fn;
|
||||
tree context;
|
||||
int was_abstract;
|
||||
htab_t old_decl_loc_table;
|
||||
htab_t old_cached_dw_loc_list_table;
|
||||
hash_table<decl_loc_hasher> *old_decl_loc_table;
|
||||
hash_table<dw_loc_list_hasher> *old_cached_dw_loc_list_table;
|
||||
int old_call_site_count, old_tail_call_site_count;
|
||||
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
|
||||
only if the global variable using the type will actually be emitted. */
|
||||
|
||||
static int
|
||||
premark_types_used_by_global_vars_helper (void **slot,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
premark_types_used_by_global_vars_helper (types_used_by_vars_entry **slot,
|
||||
void *)
|
||||
{
|
||||
struct types_used_by_vars_entry *entry;
|
||||
dw_die_ref die;
|
||||
@ -18112,8 +18140,8 @@ static void
|
||||
premark_types_used_by_global_vars (void)
|
||||
{
|
||||
if (types_used_by_vars_hash)
|
||||
htab_traverse (types_used_by_vars_hash,
|
||||
premark_types_used_by_global_vars_helper, NULL);
|
||||
types_used_by_vars_hash
|
||||
->traverse<void *, premark_types_used_by_global_vars_helper> (NULL);
|
||||
}
|
||||
|
||||
/* 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). */
|
||||
|
||||
static hashval_t
|
||||
common_block_die_table_hash (const void *x)
|
||||
hashval_t
|
||||
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 nonzero if decl_id and die_parent of die_struct X is the same
|
||||
as decl_id and die_parent of die_struct Y. */
|
||||
|
||||
static int
|
||||
common_block_die_table_eq (const void *x, const void *y)
|
||||
bool
|
||||
block_die_hasher::equal (die_struct *x, die_struct *y)
|
||||
{
|
||||
const_dw_die_ref d = (const_dw_die_ref) x;
|
||||
const_dw_die_ref e = (const_dw_die_ref) y;
|
||||
return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
|
||||
return x->decl_id == y->decl_id && x->die_parent == y->die_parent;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
common_block_die_table
|
||||
= htab_create_ggc (10, common_block_die_table_hash,
|
||||
common_block_die_table_eq, NULL);
|
||||
common_block_die_table = hash_table<block_die_hasher>::create_ggc (10);
|
||||
|
||||
com_die_arg.decl_id = DECL_UID (com_decl);
|
||||
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);
|
||||
if (com_die == NULL)
|
||||
{
|
||||
const char *cnam
|
||||
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
|
||||
void **slot;
|
||||
die_node **slot;
|
||||
|
||||
com_die = new_die (DW_TAG_common_block, context_die, 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 ())
|
||||
add_pubname_string (cnam, com_die); /* ??? needed? */
|
||||
com_die->decl_id = DECL_UID (com_decl);
|
||||
slot = htab_find_slot (common_block_die_table, com_die, INSERT);
|
||||
*slot = (void *) com_die;
|
||||
slot = common_block_die_table->find_slot (com_die, INSERT);
|
||||
*slot = com_die;
|
||||
}
|
||||
else if (get_AT (com_die, DW_AT_location) == NULL && loc)
|
||||
{
|
||||
@ -21066,8 +21089,8 @@ dwarf2out_function_decl (tree decl)
|
||||
call_site_count = -1;
|
||||
tail_call_site_count = -1;
|
||||
block_map.release ();
|
||||
htab_empty (decl_loc_table);
|
||||
htab_empty (cached_dw_loc_list_table);
|
||||
decl_loc_table->empty ();
|
||||
cached_dw_loc_list_table->empty ();
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
static int
|
||||
file_table_eq (const void *p1_p, const void *p2_p)
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
file_table_hash (const void *p_p)
|
||||
hashval_t
|
||||
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);
|
||||
}
|
||||
|
||||
@ -21151,7 +21170,6 @@ file_table_hash (const void *p_p)
|
||||
static struct dwarf_file_data *
|
||||
lookup_filename (const char *file_name)
|
||||
{
|
||||
void ** slot;
|
||||
struct dwarf_file_data * created;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Didn't match the previous lookup, search the table. */
|
||||
slot = htab_find_slot_with_hash (file_table, file_name,
|
||||
htab_hash_string (file_name), INSERT);
|
||||
dwarf_file_data **slot
|
||||
= file_table->find_slot_with_hash (file_name, htab_hash_string (file_name),
|
||||
INSERT);
|
||||
if (*slot)
|
||||
return (struct dwarf_file_data *) *slot;
|
||||
return *slot;
|
||||
|
||||
created = ggc_alloc<dwarf_file_data> ();
|
||||
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. */
|
||||
|
||||
static int
|
||||
var_location_switch_text_section_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
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)
|
||||
list->last_before_switch
|
||||
= list->last->next ? list->last->next : list->last;
|
||||
@ -21543,7 +21562,7 @@ var_location_switch_text_section (void)
|
||||
if (decl_loc_table == NULL)
|
||||
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. */
|
||||
@ -21652,13 +21671,12 @@ dwarf2out_begin_function (tree fun)
|
||||
Set have_multiple_function_sections to true in that case and
|
||||
terminate htab traversal. */
|
||||
|
||||
static int
|
||||
find_empty_loc_ranges_at_text_label (void **slot, void *)
|
||||
int
|
||||
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;
|
||||
|
||||
entry = (var_loc_list *) *slot;
|
||||
node = entry->first;
|
||||
if (node && node->next && node->next->label)
|
||||
{
|
||||
@ -21689,8 +21707,7 @@ dwarf2out_end_function (unsigned int)
|
||||
&& !have_multiple_function_sections
|
||||
&& first_loclabel_num_not_at_text_label
|
||||
&& decl_loc_table)
|
||||
htab_traverse (decl_loc_table, find_empty_loc_ranges_at_text_label,
|
||||
NULL);
|
||||
decl_loc_table->traverse<int, find_empty_loc_ranges_at_text_label> (0);
|
||||
in_first_function_p = false;
|
||||
maybe_at_text_label_p = false;
|
||||
}
|
||||
@ -22303,21 +22320,16 @@ static void
|
||||
dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Allocate the file_table. */
|
||||
file_table = htab_create_ggc (50, file_table_hash,
|
||||
file_table_eq, NULL);
|
||||
file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
|
||||
|
||||
/* Allocate the decl_die_table. */
|
||||
decl_die_table = htab_create_ggc (10, decl_die_table_hash,
|
||||
decl_die_table_eq, NULL);
|
||||
decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);
|
||||
|
||||
/* Allocate the decl_loc_table. */
|
||||
decl_loc_table = htab_create_ggc (10, decl_loc_table_hash,
|
||||
decl_loc_table_eq, NULL);
|
||||
decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);
|
||||
|
||||
/* Allocate the cached_dw_loc_list_table. */
|
||||
cached_dw_loc_list_table
|
||||
= htab_create_ggc (10, cached_dw_loc_list_table_hash,
|
||||
cached_dw_loc_list_table_eq, NULL);
|
||||
cached_dw_loc_list_table = hash_table<dw_loc_list_hasher>::create_ggc (10);
|
||||
|
||||
/* Allocate the initial hunk of the decl_scope_table. */
|
||||
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
|
||||
in the same order for each run. */
|
||||
|
||||
static int
|
||||
index_string (void **h, void *v)
|
||||
int
|
||||
index_string (indirect_string_node **h, unsigned int *index)
|
||||
{
|
||||
struct indirect_string_node *node = (struct indirect_string_node *) *h;
|
||||
unsigned int *index = (unsigned int *) v;
|
||||
indirect_string_node *node = *h;
|
||||
|
||||
find_string_form (node);
|
||||
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
|
||||
current offset. */
|
||||
|
||||
static int
|
||||
output_index_string_offset (void **h, void *v)
|
||||
int
|
||||
output_index_string_offset (indirect_string_node **h, unsigned int *offset)
|
||||
{
|
||||
struct indirect_string_node *node = (struct indirect_string_node *) *h;
|
||||
unsigned int *offset = (unsigned int *) v;
|
||||
indirect_string_node *node = *h;
|
||||
|
||||
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
|
||||
htab_traverse. Output the indexed string. */
|
||||
|
||||
static int
|
||||
output_index_string (void **h, void *v)
|
||||
int
|
||||
output_index_string (indirect_string_node **h, unsigned int *cur_idx)
|
||||
{
|
||||
struct indirect_string_node *node = (struct indirect_string_node *) *h;
|
||||
unsigned int *cur_idx = (unsigned int *) v;
|
||||
struct indirect_string_node *node = *h;
|
||||
|
||||
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
|
||||
htab_traverse. Emit one queued .debug_str string. */
|
||||
|
||||
static int
|
||||
output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
|
||||
int
|
||||
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);
|
||||
if (node->form == DW_FORM_strp && node->refcount > 0)
|
||||
@ -22533,33 +22542,30 @@ output_indirect_strings (void)
|
||||
{
|
||||
switch_to_section (debug_str_section);
|
||||
if (!dwarf_split_debug_info)
|
||||
htab_traverse (debug_str_hash, output_indirect_string, NULL);
|
||||
debug_str_hash->traverse<void *, output_indirect_string> (NULL);
|
||||
else
|
||||
{
|
||||
unsigned int offset = 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);
|
||||
htab_traverse_noresize (debug_str_hash,
|
||||
output_index_string_offset,
|
||||
&offset);
|
||||
debug_str_hash->traverse_noresize
|
||||
<unsigned int *, output_index_string_offset> (&offset);
|
||||
switch_to_section (debug_str_dwo_section);
|
||||
htab_traverse_noresize (debug_str_hash,
|
||||
output_index_string,
|
||||
&cur_idx);
|
||||
debug_str_hash->traverse_noresize<unsigned int *, output_index_string>
|
||||
(&cur_idx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback for htab_traverse to assign an index to an entry in the
|
||||
table, and to write that entry to the .debug_addr section. */
|
||||
|
||||
static int
|
||||
output_addr_table_entry (void **slot, void *data)
|
||||
int
|
||||
output_addr_table_entry (addr_table_entry **slot, unsigned int *cur_index)
|
||||
{
|
||||
addr_table_entry *entry = (addr_table_entry *) *slot;
|
||||
unsigned int *cur_index = (unsigned int *)data;
|
||||
addr_table_entry *entry = *slot;
|
||||
|
||||
if (entry->refcount == 0)
|
||||
{
|
||||
@ -22600,11 +22606,12 @@ static void
|
||||
output_addr_table (void)
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
@ -22859,10 +22866,10 @@ prune_unused_types_update_strings (dw_die_ref die)
|
||||
if (s->refcount
|
||||
== ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2))
|
||||
{
|
||||
void ** slot;
|
||||
slot = htab_find_slot_with_hash (debug_str_hash, s->str,
|
||||
htab_hash_string (s->str),
|
||||
INSERT);
|
||||
indirect_string_node **slot
|
||||
= debug_str_hash->find_slot_with_hash (s->str,
|
||||
htab_hash_string (s->str),
|
||||
INSERT);
|
||||
gcc_assert (*slot == NULL);
|
||||
*slot = s;
|
||||
}
|
||||
@ -22950,9 +22957,9 @@ prune_unused_types (void)
|
||||
prune_unused_types_mark (base_type, 1);
|
||||
|
||||
if (debug_str_hash)
|
||||
htab_empty (debug_str_hash);
|
||||
debug_str_hash->empty ();
|
||||
if (skeleton_debug_str_hash)
|
||||
htab_empty (skeleton_debug_str_hash);
|
||||
skeleton_debug_str_hash->empty ();
|
||||
prune_unused_types_prune (comp_unit_die ());
|
||||
for (node = limbo_die_list; node; node = node->next)
|
||||
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
|
||||
the file table. */
|
||||
static int
|
||||
file_table_relative_p (void ** slot, void *param)
|
||||
int
|
||||
file_table_relative_p (dwarf_file_data **slot, bool *p)
|
||||
{
|
||||
bool *p = (bool *) param;
|
||||
struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
|
||||
struct dwarf_file_data *d = *slot;
|
||||
if (!IS_ABSOLUTE_PATH (d->filename))
|
||||
{
|
||||
*p = true;
|
||||
@ -24222,7 +24228,7 @@ dwarf2out_finish (const char *filename)
|
||||
else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
|
||||
{
|
||||
bool p = false;
|
||||
htab_traverse (file_table, file_table_relative_p, &p);
|
||||
file_table->traverse<bool *, file_table_relative_p> (&p);
|
||||
if (p)
|
||||
add_comp_dir_attribute (comp_unit_die ());
|
||||
}
|
||||
@ -24444,8 +24450,9 @@ dwarf2out_finish (const char *filename)
|
||||
if (addr_index_table != NULL)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
htab_traverse_noresize (addr_index_table,
|
||||
index_addr_table_entry, &index);
|
||||
addr_index_table
|
||||
->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
|
||||
created, so ensure it is created by this point. */
|
||||
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
|
||||
|
@ -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>
|
||||
|
||||
PR fortran/48979
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
static GTY ((param_is (struct module_htab_entry))) htab_t module_htab;
|
||||
|
||||
/* Hash and equality functions for module_htab. */
|
||||
|
||||
static hashval_t
|
||||
module_htab_do_hash (const void *x)
|
||||
struct module_hasher : ggc_hasher<module_htab_entry *>
|
||||
{
|
||||
return htab_hash_string (((const struct module_htab_entry *)x)->name);
|
||||
}
|
||||
typedef const char *compare_type;
|
||||
|
||||
static int
|
||||
module_htab_eq (const void *x1, const void *x2)
|
||||
{
|
||||
return strcmp ((((const struct module_htab_entry *)x1)->name),
|
||||
(const char *)x2) == 0;
|
||||
}
|
||||
static hashval_t hash (module_htab_entry *s) { return htab_hash_string (s); }
|
||||
static bool
|
||||
equal (module_htab_entry *a, const char *b)
|
||||
{
|
||||
return !strcmp (a->name, b);
|
||||
}
|
||||
};
|
||||
|
||||
static GTY (()) hash_table<module_hasher> *module_htab;
|
||||
|
||||
/* Hash and equality functions for module_htab's decls. */
|
||||
|
||||
static hashval_t
|
||||
module_htab_decls_hash (const void *x)
|
||||
hashval_t
|
||||
module_decl_hasher::hash (tree t)
|
||||
{
|
||||
const_tree t = (const_tree) x;
|
||||
const_tree n = DECL_NAME (t);
|
||||
if (n == NULL_TREE)
|
||||
n = TYPE_NAME (TREE_TYPE (t));
|
||||
return htab_hash_string (IDENTIFIER_POINTER (n));
|
||||
}
|
||||
|
||||
static int
|
||||
module_htab_decls_eq (const void *x1, const void *x2)
|
||||
bool
|
||||
module_decl_hasher::equal (tree t1, const char *x2)
|
||||
{
|
||||
const_tree t1 = (const_tree) x1;
|
||||
const_tree n1 = DECL_NAME (t1);
|
||||
if (n1 == NULL_TREE)
|
||||
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 *
|
||||
gfc_find_module (const char *name)
|
||||
{
|
||||
void **slot;
|
||||
|
||||
if (! module_htab)
|
||||
module_htab = htab_create_ggc (10, module_htab_do_hash,
|
||||
module_htab_eq, NULL);
|
||||
module_htab = hash_table<module_hasher>::create_ggc (10);
|
||||
|
||||
slot = htab_find_slot_with_hash (module_htab, name,
|
||||
htab_hash_string (name), INSERT);
|
||||
module_htab_entry **slot
|
||||
= module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
|
||||
|
||||
entry->name = gfc_get_string (name);
|
||||
entry->decls = htab_create_ggc (10, module_htab_decls_hash,
|
||||
module_htab_decls_eq, NULL);
|
||||
*slot = (void *) entry;
|
||||
entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
|
||||
*slot = entry;
|
||||
}
|
||||
return (struct module_htab_entry *) *slot;
|
||||
return *slot;
|
||||
}
|
||||
|
||||
void
|
||||
gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
|
||||
{
|
||||
void **slot;
|
||||
const char *name;
|
||||
|
||||
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);
|
||||
name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
|
||||
}
|
||||
slot = htab_find_slot_with_hash (entry->decls, name,
|
||||
htab_hash_string (name), INSERT);
|
||||
tree *slot
|
||||
= entry->decls->find_slot_with_hash (name, htab_hash_string (name),
|
||||
INSERT);
|
||||
if (*slot == NULL)
|
||||
*slot = (void *) decl;
|
||||
*slot = decl;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tree decl, local_name;
|
||||
void **slot;
|
||||
|
||||
if (rent->op != INTRINSIC_NONE)
|
||||
continue;
|
||||
|
||||
slot = htab_find_slot_with_hash (entry->decls, rent->use_name,
|
||||
htab_hash_string (rent->use_name),
|
||||
INSERT);
|
||||
hashval_t hash = htab_hash_string (rent->use_name);
|
||||
tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
|
||||
INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
gfc_symtree *st;
|
||||
@ -4547,7 +4537,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
|
||||
else
|
||||
{
|
||||
*slot = error_mark_node;
|
||||
htab_clear_slot (entry->decls, slot);
|
||||
entry->decls->clear_slot (slot);
|
||||
continue;
|
||||
}
|
||||
*slot = decl;
|
||||
|
@ -1963,7 +1963,7 @@ gfc_generate_module_code (gfc_namespace * ns)
|
||||
entry = gfc_find_module (ns->proc_name->name);
|
||||
if (entry->namespace_decl)
|
||||
/* Buggy sourcecode, using a module before defining it? */
|
||||
htab_empty (entry->decls);
|
||||
entry->decls->empty ();
|
||||
entry->namespace_decl = ns->proc_name->backend_decl;
|
||||
|
||||
gfc_generate_module_vars (ns);
|
||||
|
@ -575,10 +575,18 @@ void gfc_generate_module_vars (gfc_namespace *);
|
||||
/* Get the appropriate return statement for a procedure. */
|
||||
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;
|
||||
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 *);
|
||||
|
@ -108,7 +108,7 @@ static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
|
||||
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;
|
||||
|
||||
/* Forward declarations. */
|
||||
@ -540,18 +540,24 @@ struct GTY(()) temp_slot {
|
||||
HOST_WIDE_INT full_size;
|
||||
};
|
||||
|
||||
/* A table of addresses that represent a stack slot. The table is a mapping
|
||||
from address RTXen to a temp slot. */
|
||||
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 {
|
||||
/* Entry for the below hash table. */
|
||||
struct GTY((for_user)) temp_slot_address_entry {
|
||||
hashval_t hash;
|
||||
rtx address;
|
||||
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. */
|
||||
|
||||
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. */
|
||||
static hashval_t
|
||||
temp_slot_address_hash (const void *p)
|
||||
hashval_t
|
||||
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;
|
||||
}
|
||||
|
||||
/* Compare two address -> temp slot mapping entries. */
|
||||
static int
|
||||
temp_slot_address_eq (const void *p1, const void *p2)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
@ -656,24 +658,21 @@ temp_slot_address_eq (const void *p1, const void *p2)
|
||||
static void
|
||||
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> ();
|
||||
t->address = address;
|
||||
t->temp_slot = temp_slot;
|
||||
t->hash = temp_slot_address_compute_hash (t);
|
||||
slot = htab_find_slot_with_hash (temp_slot_address_table, t, t->hash, INSERT);
|
||||
*slot = t;
|
||||
*temp_slot_address_table->find_slot_with_hash (t, t->hash, INSERT) = t;
|
||||
}
|
||||
|
||||
/* Remove an address -> temp slot mapping entry if the temp slot is
|
||||
not in use anymore. Callback for remove_unused_temp_slot_addresses. */
|
||||
static int
|
||||
remove_unused_temp_slot_addresses_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
remove_unused_temp_slot_addresses_1 (temp_slot_address_entry **slot, void *)
|
||||
{
|
||||
const struct temp_slot_address_entry *t;
|
||||
t = (const struct temp_slot_address_entry *) *slot;
|
||||
const struct temp_slot_address_entry *t = *slot;
|
||||
if (! t->temp_slot->in_use)
|
||||
htab_clear_slot (temp_slot_address_table, slot);
|
||||
temp_slot_address_table->clear_slot (slot);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -683,11 +682,10 @@ remove_unused_temp_slot_addresses (void)
|
||||
{
|
||||
/* Use quicker clearing if there aren't any active temp slots. */
|
||||
if (n_temp_slots_in_use)
|
||||
htab_traverse (temp_slot_address_table,
|
||||
remove_unused_temp_slot_addresses_1,
|
||||
NULL);
|
||||
temp_slot_address_table->traverse
|
||||
<void *, remove_unused_temp_slot_addresses_1> (NULL);
|
||||
else
|
||||
htab_empty (temp_slot_address_table);
|
||||
temp_slot_address_table->empty ();
|
||||
}
|
||||
|
||||
/* 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.temp_slot = NULL;
|
||||
tmp.hash = temp_slot_address_compute_hash (&tmp);
|
||||
t = (struct temp_slot_address_entry *)
|
||||
htab_find_with_hash (temp_slot_address_table, &tmp, tmp.hash);
|
||||
t = temp_slot_address_table->find_with_hash (&tmp, tmp.hash);
|
||||
if (t)
|
||||
return t->temp_slot;
|
||||
|
||||
@ -1195,12 +1192,9 @@ init_temp_slots (void)
|
||||
|
||||
/* Set up the table to map addresses to temp slots. */
|
||||
if (! temp_slot_address_table)
|
||||
temp_slot_address_table = htab_create_ggc (32,
|
||||
temp_slot_address_hash,
|
||||
temp_slot_address_eq,
|
||||
NULL);
|
||||
temp_slot_address_table = hash_table<temp_address_hasher>::create_ggc (32);
|
||||
else
|
||||
htab_empty (temp_slot_address_table);
|
||||
temp_slot_address_table->empty ();
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*Equality function of the types_used_by_vars_entry hash table. */
|
||||
|
||||
int
|
||||
types_used_by_vars_eq (const void *x1, const void *x2)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
@ -6173,16 +6160,15 @@ types_used_by_var_decl_insert (tree type, tree var_decl)
|
||||
{
|
||||
if (type != NULL && var_decl != NULL)
|
||||
{
|
||||
void **slot;
|
||||
types_used_by_vars_entry **slot;
|
||||
struct types_used_by_vars_entry e;
|
||||
e.var_decl = var_decl;
|
||||
e.type = type;
|
||||
if (types_used_by_vars_hash == NULL)
|
||||
types_used_by_vars_hash =
|
||||
htab_create_ggc (37, types_used_by_vars_do_hash,
|
||||
types_used_by_vars_eq, NULL);
|
||||
slot = htab_find_slot_with_hash (types_used_by_vars_hash, &e,
|
||||
hash_types_used_by_vars_entry (&e), INSERT);
|
||||
types_used_by_vars_hash
|
||||
= hash_table<used_type_hasher>::create_ggc (37);
|
||||
|
||||
slot = types_used_by_vars_hash->find_slot (&e, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
struct types_used_by_vars_entry *entry;
|
||||
|
@ -703,21 +703,24 @@ extern int virtuals_instantiated;
|
||||
/* Nonzero if at least one trampoline has been created. */
|
||||
extern int trampolines_created;
|
||||
|
||||
struct GTY(()) types_used_by_vars_entry {
|
||||
struct GTY((for_user)) types_used_by_vars_entry {
|
||||
tree type;
|
||||
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
|
||||
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
|
||||
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. */
|
||||
extern GTY((param_is (struct types_used_by_vars_entry))) htab_t
|
||||
types_used_by_vars_hash;
|
||||
extern GTY(()) hash_table<used_type_hasher> *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);
|
||||
|
||||
/* During parsing of a global variable, this vector contains the types
|
||||
|
@ -648,6 +648,12 @@ create_user_defined_type (const char *type_name, struct fileloc *pos)
|
||||
if (is_ptr)
|
||||
offset_to_star = star - type_id;
|
||||
|
||||
if (strstr (type_id, "char*"))
|
||||
{
|
||||
type_id = strtoken (0, ",>", &next);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *field_name = xstrdup (type_id);
|
||||
|
||||
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, "for_user") == 0)
|
||||
;
|
||||
else
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
/* Emit the user-callable functions needed to mark all the types used
|
||||
by the user structure S. PREFIX is the prefix to use 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));
|
||||
d.of = get_output_file_for_structure (s, param);
|
||||
|
||||
bool for_user = false;
|
||||
for (opt = s->u.s.opt; opt; opt = opt->next)
|
||||
if (strcmp (opt->name, "chain_next") == 0
|
||||
&& 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
|
||||
&& opt->kind == OPTION_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)
|
||||
error_at_line (&s->u.s.line, "chain_prev without chain_next");
|
||||
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)
|
||||
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. */
|
||||
if (orig_s->kind == TYPE_USER_STRUCT)
|
||||
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. */
|
||||
@ -5690,6 +5714,19 @@ main (int argc, char **argv)
|
||||
hence enlarge the param_structs list of types. */
|
||||
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
|
||||
parsing source files and optionally augmented by parsing plugin
|
||||
source files. Write it now. */
|
||||
|
@ -358,4 +358,9 @@ gt_pch_nx (int)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
gt_pch_nx (unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define GCC_GIMPLE_SSA_H
|
||||
|
||||
#include "hash-map.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "tree-ssa-operands.h"
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
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_ accessor defined, all publicly modifiable fields should have
|
||||
gimple_set accessor. */
|
||||
@ -63,7 +83,7 @@ struct GTY(()) gimple_df {
|
||||
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
|
||||
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. */
|
||||
unsigned int ssa_renaming_needed : 1;
|
||||
|
@ -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>
|
||||
static void
|
||||
pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie)
|
||||
|
@ -198,6 +198,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
#include "ggc.h"
|
||||
#include "hashtab.h"
|
||||
#include <new>
|
||||
|
||||
template<typename, typename, typename> class hash_map;
|
||||
template<typename, typename> class hash_set;
|
||||
@ -301,6 +302,38 @@ pointer_hash <Type>::equal (const value_type &existing,
|
||||
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. */
|
||||
|
||||
@ -1004,6 +1037,16 @@ public:
|
||||
explicit hash_table (size_t, bool ggc = false);
|
||||
~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. */
|
||||
size_t size () const { return m_size; }
|
||||
|
||||
@ -1110,9 +1153,15 @@ public:
|
||||
private:
|
||||
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 hashtab_entry_note_pointers (void *, void *, 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
|
||||
hashtab_entry_note_pointers (void *, void *, 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);
|
||||
void expand ();
|
||||
@ -1598,7 +1647,7 @@ template<typename D>
|
||||
static void
|
||||
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>);
|
||||
gcc_checking_assert (success);
|
||||
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 */
|
||||
|
@ -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>
|
||||
|
||||
* jvgenmain.c (main): Provide declarations for JvRunMain{,Name}.
|
||||
|
@ -774,7 +774,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
|
||||
/* Initialize the initialized (static) class table. */
|
||||
if (access_flags & ACC_STATIC)
|
||||
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);
|
||||
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
|
||||
traversal. */
|
||||
|
||||
static int
|
||||
add_assertion_table_entry (void **htab_entry, void *ptr)
|
||||
int
|
||||
add_assertion_table_entry (type_assertion **slot, vec<constructor_elt, va_gc> **v)
|
||||
{
|
||||
tree entry;
|
||||
tree code_val, op1_utf8, op2_utf8;
|
||||
vec<constructor_elt, va_gc> **v
|
||||
= ((vec<constructor_elt, va_gc> **) ptr);
|
||||
type_assertion *as = (type_assertion *) *htab_entry;
|
||||
type_assertion *as = *slot;
|
||||
|
||||
code_val = build_int_cst (NULL_TREE, as->assertion_code);
|
||||
|
||||
@ -3103,11 +3101,12 @@ static tree
|
||||
emit_assertion_table (tree klass)
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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. */
|
||||
null_entry = build_assertion_table_entry (integer_zero_node,
|
||||
@ -3146,36 +3145,28 @@ init_class_processing (void)
|
||||
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. */
|
||||
|
||||
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
|
||||
|
||||
static hashval_t
|
||||
java_treetreehash_hash (const void *k_p)
|
||||
hashval_t
|
||||
treetreehasher::hash (treetreehash_entry *k)
|
||||
{
|
||||
const struct treetreehash_entry *const k
|
||||
= (const struct treetreehash_entry *) k_p;
|
||||
return JAVA_TREEHASHHASH_H (k->key);
|
||||
}
|
||||
|
||||
static int
|
||||
java_treetreehash_compare (const void * k1_p, const void * k2_p)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
tree
|
||||
java_treetreehash_find (htab_t ht, tree t)
|
||||
java_treetreehash_find (hash_table<treetreehasher> *ht, tree t)
|
||||
{
|
||||
struct treetreehash_entry *e;
|
||||
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)
|
||||
return NULL;
|
||||
else
|
||||
@ -3183,13 +3174,12 @@ java_treetreehash_find (htab_t ht, tree t)
|
||||
}
|
||||
|
||||
tree *
|
||||
java_treetreehash_new (htab_t ht, tree t)
|
||||
java_treetreehash_new (hash_table<treetreehasher> *ht, tree t)
|
||||
{
|
||||
void **e;
|
||||
struct treetreehash_entry *tthe;
|
||||
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)
|
||||
{
|
||||
tthe = ggc_cleared_alloc<treetreehash_entry> ();
|
||||
@ -3197,15 +3187,14 @@ java_treetreehash_new (htab_t ht, tree t)
|
||||
*e = tthe;
|
||||
}
|
||||
else
|
||||
tthe = (struct treetreehash_entry *) *e;
|
||||
tthe = *e;
|
||||
return &tthe->value;
|
||||
}
|
||||
|
||||
htab_t
|
||||
hash_table<treetreehasher> *
|
||||
java_treetreehash_create (size_t size)
|
||||
{
|
||||
return htab_create_ggc (size, java_treetreehash_hash,
|
||||
java_treetreehash_compare, NULL);
|
||||
return hash_table<treetreehasher>::create_ggc (size);
|
||||
}
|
||||
|
||||
/* Break down qualified IDENTIFIER into package and class-name components.
|
||||
|
@ -1846,8 +1846,8 @@ end_java_method (void)
|
||||
variable to the block_body */
|
||||
fbody = DECL_SAVED_TREE (fndecl);
|
||||
block_body = BIND_EXPR_BODY (fbody);
|
||||
htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
|
||||
attach_init_test_initialization_flags, block_body);
|
||||
hash_table<treetreehasher> *ht = DECL_FUNCTION_INIT_TEST_TABLE (fndecl);
|
||||
ht->traverse<tree, attach_init_test_initialization_flags> (block_body);
|
||||
}
|
||||
|
||||
finish_method (fndecl);
|
||||
|
@ -433,10 +433,10 @@ prepare_eh_table_type (tree type)
|
||||
return exp;
|
||||
}
|
||||
|
||||
static int
|
||||
expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED)
|
||||
int
|
||||
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 decl;
|
||||
STRIP_NOPS (addr);
|
||||
@ -452,9 +452,7 @@ void
|
||||
java_expand_catch_classes (tree this_class)
|
||||
{
|
||||
if (TYPE_TO_RUNTIME_MAP (this_class))
|
||||
htab_traverse
|
||||
(TYPE_TO_RUNTIME_MAP (this_class),
|
||||
expand_catch_class, NULL);
|
||||
TYPE_TO_RUNTIME_MAP (this_class)->traverse<int, expand_catch_class> (0);
|
||||
}
|
||||
|
||||
/* Build and push the variable that will hold the exception object
|
||||
|
@ -398,22 +398,19 @@ pop_type (tree type)
|
||||
|
||||
/* Return true if two type assertions are equal. */
|
||||
|
||||
static int
|
||||
type_assertion_eq (const void * k1_p, const void * k2_p)
|
||||
bool
|
||||
type_assertion_hasher::equal (type_assertion *k1, type_assertion *k2)
|
||||
{
|
||||
const type_assertion k1 = *(const type_assertion *)k1_p;
|
||||
const type_assertion k2 = *(const type_assertion *)k2_p;
|
||||
return (k1.assertion_code == k2.assertion_code
|
||||
&& k1.op1 == k2.op1
|
||||
&& k1.op2 == k2.op2);
|
||||
return (k1->assertion_code == k2->assertion_code
|
||||
&& k1->op1 == k2->op1
|
||||
&& k1->op2 == k2->op2);
|
||||
}
|
||||
|
||||
/* Hash a type assertion. */
|
||||
|
||||
static hashval_t
|
||||
type_assertion_hash (const void *p)
|
||||
hashval_t
|
||||
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
|
||||
k_p->assertion_code, 0);
|
||||
|
||||
@ -449,15 +446,14 @@ type_assertion_hash (const void *p)
|
||||
void
|
||||
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;
|
||||
void **as_pp;
|
||||
type_assertion **as_pp;
|
||||
|
||||
assertions_htab = TYPE_ASSERTIONS (klass);
|
||||
if (assertions_htab == NULL)
|
||||
{
|
||||
assertions_htab = htab_create_ggc (7, type_assertion_hash,
|
||||
type_assertion_eq, NULL);
|
||||
assertions_htab = hash_table<type_assertion_hasher>::create_ggc (7);
|
||||
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.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. */
|
||||
if (*as_pp)
|
||||
return;
|
||||
|
||||
*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. */
|
||||
|
||||
int
|
||||
attach_init_test_initialization_flags (void **entry, void *ptr)
|
||||
attach_init_test_initialization_flags (treetreehash_entry **slot, tree block)
|
||||
{
|
||||
tree block = (tree)ptr;
|
||||
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
|
||||
treetreehash_entry *ite = *slot;
|
||||
|
||||
if (block != error_mark_node)
|
||||
{
|
||||
|
@ -710,6 +710,25 @@ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) != POINTER_TYPE) \
|
||||
|| 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. */
|
||||
struct GTY(()) lang_decl_func {
|
||||
/* tree chain; not yet used. */
|
||||
@ -726,10 +745,10 @@ struct GTY(()) lang_decl_func {
|
||||
tree exc_obj; /* Decl holding the exception object. */
|
||||
|
||||
/* 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 */
|
||||
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 strictfp : 1;
|
||||
@ -742,11 +761,6 @@ struct GTY(()) lang_decl_func {
|
||||
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
|
||||
type assertion table. */
|
||||
enum
|
||||
@ -778,15 +792,21 @@ typedef enum
|
||||
JV_ANNOTATION_DEFAULT_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. */
|
||||
tree op1; /* First operand. */
|
||||
tree op2; /* Second operand. */
|
||||
} type_assertion;
|
||||
|
||||
extern tree java_treetreehash_find (htab_t, tree);
|
||||
extern tree * java_treetreehash_new (htab_t, tree);
|
||||
extern htab_t java_treetreehash_create (size_t size);
|
||||
struct type_assertion_hasher : ggc_hasher<type_assertion *>
|
||||
{
|
||||
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
|
||||
(access methods on outer class fields) and final fields. */
|
||||
@ -893,11 +913,11 @@ struct GTY(()) lang_type {
|
||||
type matcher. */
|
||||
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
|
||||
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
|
||||
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> *,
|
||||
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_invokeinterface (tree, tree);
|
||||
extern tree build_jni_stub (tree);
|
||||
|
@ -57,8 +57,6 @@ static void put_decl_string (const char *, int);
|
||||
static void put_decl_node (tree, int);
|
||||
static void java_print_error_function (diagnostic_context *, const char *,
|
||||
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 void dump_compound_expr (dump_info_p, 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
|
||||
to one in the scope of the method being inlined into. */
|
||||
|
||||
static int
|
||||
merge_init_test_initialization (void **entry, void *x)
|
||||
int
|
||||
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_node n;
|
||||
tree *init_test_decl;
|
||||
@ -761,9 +759,8 @@ merge_init_test_initialization (void **entry, void *x)
|
||||
void
|
||||
java_inlining_merge_static_initializers (tree fn, void *decl_map)
|
||||
{
|
||||
htab_traverse
|
||||
(DECL_FUNCTION_INIT_TEST_TABLE (fn),
|
||||
merge_init_test_initialization, decl_map);
|
||||
DECL_FUNCTION_INIT_TEST_TABLE (fn)
|
||||
->traverse<void *, merge_init_test_initialization> (decl_map);
|
||||
}
|
||||
|
||||
/* 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
|
||||
pre-existing one. */
|
||||
|
||||
static int
|
||||
inline_init_test_initialization (void **entry, void *x)
|
||||
int
|
||||
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;
|
||||
|
||||
tree h = java_treetreehash_find
|
||||
@ -796,9 +793,8 @@ inline_init_test_initialization (void **entry, void *x)
|
||||
void
|
||||
java_inlining_map_static_initializers (tree fn, void *decl_map)
|
||||
{
|
||||
htab_traverse
|
||||
(DECL_FUNCTION_INIT_TEST_TABLE (fn),
|
||||
inline_init_test_initialization, decl_map);
|
||||
DECL_FUNCTION_INIT_TEST_TABLE (fn)
|
||||
->traverse<void *, inline_init_test_initialization> (decl_map);
|
||||
}
|
||||
|
||||
/* Avoid voluminous output for deep recursion of compound exprs. */
|
||||
|
@ -55,11 +55,19 @@ enum libfunc_index
|
||||
We use the same hashtable for normal optabs and conversion optabs. In
|
||||
the first case mode2 is forced to VOIDmode. */
|
||||
|
||||
struct GTY(()) libfunc_entry {
|
||||
struct GTY((for_user)) libfunc_entry {
|
||||
int op, mode1, mode2;
|
||||
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. */
|
||||
struct GTY(()) target_libfuncs {
|
||||
/* 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];
|
||||
|
||||
/* 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;
|
||||
|
@ -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>
|
||||
|
||||
* Make-lang.in (check_objc_parallelize): Change to just an upper
|
||||
|
@ -253,7 +253,7 @@ vec<tree, va_gc> *local_variables_to_volatilize = NULL;
|
||||
/* Store all constructed constant strings in a hash table so that
|
||||
they get uniqued properly. */
|
||||
|
||||
struct GTY(()) string_descriptor {
|
||||
struct GTY((for_user)) string_descriptor {
|
||||
/* The literal argument . */
|
||||
tree literal;
|
||||
|
||||
@ -261,7 +261,13 @@ struct GTY(()) string_descriptor {
|
||||
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;
|
||||
|
||||
@ -3107,10 +3113,10 @@ my_build_string_pointer (int len, const char *str)
|
||||
return build1 (ADDR_EXPR, ptrtype, string);
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
string_hash (const void *ptr)
|
||||
hashval_t
|
||||
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);
|
||||
int i, len = TREE_STRING_LENGTH (str);
|
||||
hashval_t h = len;
|
||||
@ -3121,11 +3127,11 @@ string_hash (const void *ptr)
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
string_eq (const void *ptr1, const void *ptr2)
|
||||
bool
|
||||
objc_string_hasher::equal (string_descriptor *ptr1, string_descriptor *ptr2)
|
||||
{
|
||||
const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
|
||||
const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
|
||||
const_tree const str1 = ptr1->literal;
|
||||
const_tree const str2 = ptr2->literal;
|
||||
int len1 = TREE_STRING_LENGTH (str1);
|
||||
|
||||
return (len1 == TREE_STRING_LENGTH (str2)
|
||||
@ -3147,7 +3153,6 @@ objc_build_string_object (tree string)
|
||||
int length;
|
||||
tree addr;
|
||||
struct string_descriptor *desc, key;
|
||||
void **loc;
|
||||
|
||||
/* We should be passed a 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? */
|
||||
key.literal = string;
|
||||
loc = htab_find_slot (string_htab, &key, INSERT);
|
||||
desc = (struct string_descriptor *) *loc;
|
||||
string_descriptor **loc = string_htab->find_slot (&key, INSERT);
|
||||
desc = *loc;
|
||||
|
||||
if (!desc)
|
||||
{
|
||||
@ -5776,8 +5781,7 @@ hash_init (void)
|
||||
alias_name_map = objc_map_alloc_ggc (200);
|
||||
|
||||
/* Initialize the hash table used to hold the constant string objects. */
|
||||
string_htab = htab_create_ggc (31, string_hash,
|
||||
string_eq, NULL);
|
||||
string_htab = hash_table<objc_string_hasher>::create_ggc (31);
|
||||
}
|
||||
|
||||
/* Use the following to add a method to class_method_map or
|
||||
|
70
gcc/optabs.c
70
gcc/optabs.c
@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "insn-config.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "tree-hasher.h"
|
||||
#include "stor-layout.h"
|
||||
#include "stringpool.h"
|
||||
#include "varasm.h"
|
||||
@ -73,20 +74,17 @@ void debug_optab_libfuncs (void);
|
||||
|
||||
/* Used for libfunc_hash. */
|
||||
|
||||
static hashval_t
|
||||
hash_libfunc (const void *p)
|
||||
hashval_t
|
||||
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);
|
||||
}
|
||||
|
||||
/* Used for libfunc_hash. */
|
||||
|
||||
static int
|
||||
eq_libfunc (const void *p, const void *q)
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
@ -109,8 +107,7 @@ convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
|
||||
e.op = optab;
|
||||
e.mode1 = mode1;
|
||||
e.mode2 = mode2;
|
||||
slot = (struct libfunc_entry **)
|
||||
htab_find_slot (libfunc_hash, &e, NO_INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, NO_INSERT);
|
||||
if (!slot)
|
||||
{
|
||||
const struct convert_optab_libcall_d *d
|
||||
@ -120,8 +117,7 @@ convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
|
||||
return NULL;
|
||||
|
||||
d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
|
||||
slot = (struct libfunc_entry **)
|
||||
htab_find_slot (libfunc_hash, &e, NO_INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, NO_INSERT);
|
||||
if (!slot)
|
||||
return NULL;
|
||||
}
|
||||
@ -146,8 +142,7 @@ optab_libfunc (optab optab, enum machine_mode mode)
|
||||
e.op = optab;
|
||||
e.mode1 = mode;
|
||||
e.mode2 = VOIDmode;
|
||||
slot = (struct libfunc_entry **)
|
||||
htab_find_slot (libfunc_hash, &e, NO_INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, NO_INSERT);
|
||||
if (!slot)
|
||||
{
|
||||
const struct optab_libcall_d *d
|
||||
@ -157,8 +152,7 @@ optab_libfunc (optab optab, enum machine_mode mode)
|
||||
return NULL;
|
||||
|
||||
d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
|
||||
slot = (struct libfunc_entry **)
|
||||
htab_find_slot (libfunc_hash, &e, NO_INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, NO_INSERT);
|
||||
if (!slot)
|
||||
return NULL;
|
||||
}
|
||||
@ -6100,22 +6094,25 @@ gen_satfractuns_conv_libfunc (convert_optab tab,
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
libfunc_decl_hash (const void *entry)
|
||||
struct libfunc_decl_hasher : ggc_hasher<tree>
|
||||
{
|
||||
return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry));
|
||||
}
|
||||
static hashval_t
|
||||
hash (tree entry)
|
||||
{
|
||||
return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
|
||||
}
|
||||
|
||||
static int
|
||||
libfunc_decl_eq (const void *entry1, const void *entry2)
|
||||
{
|
||||
return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
|
||||
}
|
||||
static bool
|
||||
equal (tree decl, tree name)
|
||||
{
|
||||
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. */
|
||||
|
||||
@ -6143,18 +6140,16 @@ rtx
|
||||
init_one_libfunc (const char *name)
|
||||
{
|
||||
tree id, decl;
|
||||
void **slot;
|
||||
hashval_t hash;
|
||||
|
||||
if (libfunc_decls == NULL)
|
||||
libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
|
||||
libfunc_decl_eq, NULL);
|
||||
libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
|
||||
|
||||
/* See if we have already created a libfunc decl for this function. */
|
||||
id = get_identifier (name);
|
||||
hash = IDENTIFIER_HASH_VALUE (id);
|
||||
slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
|
||||
decl = (tree) *slot;
|
||||
tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
|
||||
decl = *slot;
|
||||
if (decl == NULL)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
tree id, decl;
|
||||
void **slot;
|
||||
hashval_t hash;
|
||||
|
||||
id = get_identifier (name);
|
||||
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);
|
||||
decl = (tree) *slot;
|
||||
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);
|
||||
else
|
||||
val = 0;
|
||||
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, INSERT);
|
||||
if (*slot == NULL)
|
||||
*slot = ggc_alloc<libfunc_entry> ();
|
||||
(*slot)->op = op;
|
||||
@ -6228,7 +6222,7 @@ set_conv_libfunc (convert_optab optab, enum machine_mode tmode,
|
||||
val = init_one_libfunc (name);
|
||||
else
|
||||
val = 0;
|
||||
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
|
||||
slot = libfunc_hash->find_slot (&e, INSERT);
|
||||
if (*slot == NULL)
|
||||
*slot = ggc_alloc<libfunc_entry> ();
|
||||
(*slot)->op = optab;
|
||||
@ -6244,9 +6238,9 @@ void
|
||||
init_optabs (void)
|
||||
{
|
||||
if (libfunc_hash)
|
||||
htab_empty (libfunc_hash);
|
||||
libfunc_hash->empty ();
|
||||
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. */
|
||||
init_all_optabs (this_fn_optabs);
|
||||
|
@ -486,7 +486,7 @@ struct GTY(()) noswitch_section {
|
||||
};
|
||||
|
||||
/* 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 named_section GTY ((tag ("SECTION_NAMED"))) named;
|
||||
struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed;
|
||||
|
@ -224,7 +224,7 @@ struct GTY(()) block_symbol {
|
||||
|
||||
/* Describes a group of objects that are to be placed together in such
|
||||
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. */
|
||||
section *sect;
|
||||
|
||||
|
14
gcc/sese.c
14
gcc/sese.c
@ -618,9 +618,9 @@ if_region_set_false_region (ifsese if_region, sese region)
|
||||
edge exit_region = SESE_EXIT (region);
|
||||
basic_block before_region = entry_region->src;
|
||||
basic_block last_in_region = exit_region->src;
|
||||
void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region,
|
||||
htab_hash_pointer (exit_region),
|
||||
NO_INSERT);
|
||||
hashval_t hash = htab_hash_pointer (exit_region);
|
||||
loop_exit **slot
|
||||
= current_loops->exits->find_slot_with_hash (exit_region, hash, NO_INSERT);
|
||||
|
||||
entry_region->flags = false_edge->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> ();
|
||||
|
||||
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,
|
||||
htab_hash_pointer (false_edge),
|
||||
INSERT);
|
||||
hashval_t hash = htab_hash_pointer (false_edge);
|
||||
slot = current_loops->exits->find_slot_with_hash (false_edge, hash,
|
||||
INSERT);
|
||||
loop_exit->e = false_edge;
|
||||
*slot = loop_exit;
|
||||
false_edge->src->loop_father->exits->next = loop_exit;
|
||||
|
80
gcc/symtab.c
80
gcc/symtab.c
@ -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. */
|
||||
|
||||
bool
|
||||
@ -150,14 +141,6 @@ symbol_table::decl_assembler_name_equal (tree decl, const_tree asmname)
|
||||
|
||||
/* 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. */
|
||||
|
||||
void
|
||||
@ -170,19 +153,18 @@ symbol_table::insert_to_assembler_name_hash (symtab_node *node,
|
||||
&& !node->next_sharing_asm_name);
|
||||
if (assembler_name_hash)
|
||||
{
|
||||
void **aslot;
|
||||
symtab_node **aslot;
|
||||
cgraph_node *cnode;
|
||||
tree decl = node->decl;
|
||||
|
||||
tree name = DECL_ASSEMBLER_NAME (node->decl);
|
||||
|
||||
aslot = htab_find_slot_with_hash (assembler_name_hash, name,
|
||||
decl_assembler_name_hash (name),
|
||||
INSERT);
|
||||
hashval_t hash = decl_assembler_name_hash (name);
|
||||
aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
|
||||
gcc_assert (*aslot != node);
|
||||
node->next_sharing_asm_name = (symtab_node *)*aslot;
|
||||
if (*aslot != NULL)
|
||||
((symtab_node *)*aslot)->previous_sharing_asm_name = node;
|
||||
(*aslot)->previous_sharing_asm_name = node;
|
||||
*aslot = node;
|
||||
|
||||
/* Update also possible inline clones sharing a decl. */
|
||||
@ -217,13 +199,13 @@ symbol_table::unlink_from_assembler_name_hash (symtab_node *node,
|
||||
else
|
||||
{
|
||||
tree name = DECL_ASSEMBLER_NAME (node->decl);
|
||||
void **slot;
|
||||
slot = htab_find_slot_with_hash (assembler_name_hash, name,
|
||||
decl_assembler_name_hash (name),
|
||||
NO_INSERT);
|
||||
symtab_node **slot;
|
||||
hashval_t hash = decl_assembler_name_hash (name);
|
||||
slot = assembler_name_hash->find_slot_with_hash (name, hash,
|
||||
NO_INSERT);
|
||||
gcc_assert (*slot == node);
|
||||
if (!node->next_sharing_asm_name)
|
||||
htab_clear_slot (assembler_name_hash, slot);
|
||||
assembler_name_hash->clear_slot (slot);
|
||||
else
|
||||
*slot = node->next_sharing_asm_name;
|
||||
}
|
||||
@ -256,9 +238,7 @@ symbol_table::symtab_initialize_asm_name_hash (void)
|
||||
symtab_node *node;
|
||||
if (!assembler_name_hash)
|
||||
{
|
||||
assembler_name_hash =
|
||||
htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
|
||||
NULL);
|
||||
assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
|
||||
FOR_EACH_SYMBOL (node)
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
hash_section_hash_entry (const void *p)
|
||||
hashval_t
|
||||
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 true if section P1 name equals to P2. */
|
||||
|
||||
static int
|
||||
eq_sections (const void *p1, const void *p2)
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
||||
@ -936,16 +913,16 @@ symtab_node *
|
||||
symtab_node::get_for_asmname (const_tree asmname)
|
||||
{
|
||||
symtab_node *node;
|
||||
void **slot;
|
||||
|
||||
symtab->symtab_initialize_asm_name_hash ();
|
||||
slot = htab_find_slot_with_hash (symtab->assembler_name_hash, asmname,
|
||||
symtab->decl_assembler_name_hash (asmname),
|
||||
NO_INSERT);
|
||||
hashval_t hash = symtab->decl_assembler_name_hash (asmname);
|
||||
symtab_node **slot
|
||||
= symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
|
||||
NO_INSERT);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
node = (symtab_node *) *slot;
|
||||
node = *slot;
|
||||
return node;
|
||||
}
|
||||
return NULL;
|
||||
@ -1382,7 +1359,7 @@ void
|
||||
symtab_node::set_section_for_node (const char *section)
|
||||
{
|
||||
const char *current = get_section ();
|
||||
void **slot;
|
||||
section_hash_entry **slot;
|
||||
|
||||
if (current == section
|
||||
|| (current && section
|
||||
@ -1394,11 +1371,11 @@ symtab_node::set_section_for_node (const char *section)
|
||||
x_section->ref_count--;
|
||||
if (!x_section->ref_count)
|
||||
{
|
||||
slot = htab_find_slot_with_hash (symtab->section_hash, x_section->name,
|
||||
htab_hash_string (x_section->name),
|
||||
INSERT);
|
||||
hashval_t hash = htab_hash_string (x_section->name);
|
||||
slot = symtab->section_hash->find_slot_with_hash (x_section->name,
|
||||
hash, INSERT);
|
||||
ggc_free (x_section);
|
||||
htab_clear_slot (symtab->section_hash, slot);
|
||||
symtab->section_hash->clear_slot (slot);
|
||||
}
|
||||
x_section = NULL;
|
||||
}
|
||||
@ -1408,11 +1385,10 @@ symtab_node::set_section_for_node (const char *section)
|
||||
return;
|
||||
}
|
||||
if (!symtab->section_hash)
|
||||
symtab->section_hash = htab_create_ggc (10, hash_section_hash_entry,
|
||||
eq_sections, NULL);
|
||||
slot = htab_find_slot_with_hash (symtab->section_hash, section,
|
||||
htab_hash_string (section),
|
||||
INSERT);
|
||||
symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
|
||||
slot = symtab->section_hash->find_slot_with_hash (section,
|
||||
htab_hash_string (section),
|
||||
INSERT);
|
||||
if (*slot)
|
||||
x_section = (section_hash_entry *)*slot;
|
||||
else
|
||||
|
@ -6980,11 +6980,12 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
|
||||
if (loops_for_fn (saved_cfun)->exits)
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
{
|
||||
void **slot = htab_find_slot_with_hash
|
||||
(loops_for_fn (saved_cfun)->exits, e,
|
||||
htab_hash_pointer (e), NO_INSERT);
|
||||
struct loops *l = loops_for_fn (saved_cfun);
|
||||
loop_exit **slot
|
||||
= l->exits->find_slot_with_hash (e, htab_hash_pointer (e),
|
||||
NO_INSERT);
|
||||
if (slot)
|
||||
htab_clear_slot (loops_for_fn (saved_cfun)->exits, slot);
|
||||
l->exits->clear_slot (slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ ssa_default_def (struct function *fn, tree var)
|
||||
|| TREE_CODE (var) == RESULT_DECL);
|
||||
in.var = (tree)&ind;
|
||||
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
|
||||
@ -333,7 +333,6 @@ set_ssa_default_def (struct function *fn, tree var, tree def)
|
||||
{
|
||||
struct tree_decl_minimal ind;
|
||||
struct tree_ssa_name in;
|
||||
void **loc;
|
||||
|
||||
gcc_assert (TREE_CODE (var) == VAR_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);
|
||||
if (!def)
|
||||
{
|
||||
loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in,
|
||||
DECL_UID (var), NO_INSERT);
|
||||
tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
|
||||
DECL_UID (var),
|
||||
NO_INSERT);
|
||||
if (loc)
|
||||
{
|
||||
SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false;
|
||||
htab_clear_slot (DEFAULT_DEFS (fn), loc);
|
||||
DEFAULT_DEFS (fn)->clear_slot (loc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var);
|
||||
loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in,
|
||||
DECL_UID (var), INSERT);
|
||||
tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
|
||||
DECL_UID (var), INSERT);
|
||||
|
||||
/* Default definition might be changed by tail call optimization. */
|
||||
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. */
|
||||
*(tree *) loc = def;
|
||||
*loc = def;
|
||||
SSA_NAME_IS_DEFAULT_DEF (def) = true;
|
||||
}
|
||||
|
||||
|
@ -1055,24 +1055,6 @@ err:
|
||||
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. */
|
||||
|
||||
@ -1080,8 +1062,7 @@ void
|
||||
init_tree_ssa (struct function *fn)
|
||||
{
|
||||
fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
|
||||
fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash,
|
||||
uid_ssaname_map_eq, NULL);
|
||||
fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
|
||||
pt_solution_reset (&fn->gimple_df->escaped);
|
||||
init_ssanames (fn, 0);
|
||||
}
|
||||
@ -1153,7 +1134,7 @@ delete_tree_ssa (void)
|
||||
if (ssa_operands_active (cfun))
|
||||
fini_ssa_operands (cfun);
|
||||
|
||||
htab_delete (cfun->gimple_df->default_defs);
|
||||
cfun->gimple_df->default_defs->empty ();
|
||||
cfun->gimple_df->default_defs = NULL;
|
||||
pt_solution_reset (&cfun->gimple_df->escaped);
|
||||
if (cfun->gimple_df->decls_to_pointers != NULL)
|
||||
|
173
gcc/varasm.c
173
gcc/varasm.c
@ -110,8 +110,6 @@ static int contains_pointers_p (tree);
|
||||
static bool incorporeal_function_p (tree);
|
||||
#endif
|
||||
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 int compare_constant (const tree, const tree);
|
||||
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) \
|
||||
&& 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. */
|
||||
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. */
|
||||
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. */
|
||||
static GTY(()) int anchor_labelno;
|
||||
@ -189,19 +203,15 @@ static GTY(()) struct rtx_constant_pool *shared_constant_pool;
|
||||
|
||||
/* Helper routines for maintaining section_htab. */
|
||||
|
||||
static int
|
||||
section_entry_eq (const void *p1, const void *p2)
|
||||
bool
|
||||
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;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
section_entry_hash (const void *p)
|
||||
hashval_t
|
||||
section_hasher::hash (section *old)
|
||||
{
|
||||
const section *old = (const section *) p;
|
||||
return htab_hash_string (old->named.name);
|
||||
}
|
||||
|
||||
@ -217,19 +227,15 @@ hash_section (section *sect)
|
||||
|
||||
/* Helper routines for maintaining object_block_htab. */
|
||||
|
||||
static int
|
||||
object_block_entry_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
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;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
object_block_entry_hash (const void *p)
|
||||
hashval_t
|
||||
object_block_hasher::hash (object_block *old)
|
||||
{
|
||||
const struct object_block *old = (const struct object_block *) p;
|
||||
return hash_section (old->sect);
|
||||
}
|
||||
|
||||
@ -273,9 +279,8 @@ get_section (const char *name, unsigned int flags, tree decl)
|
||||
{
|
||||
section *sect, **slot;
|
||||
|
||||
slot = (section **)
|
||||
htab_find_slot_with_hash (section_htab, name,
|
||||
htab_hash_string (name), INSERT);
|
||||
slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
|
||||
INSERT);
|
||||
flags |= SECTION_NAMED;
|
||||
if (*slot == NULL)
|
||||
{
|
||||
@ -350,14 +355,14 @@ static struct object_block *
|
||||
get_block_for_section (section *sect)
|
||||
{
|
||||
struct object_block *block;
|
||||
void **slot;
|
||||
|
||||
if (sect == NULL)
|
||||
return NULL;
|
||||
|
||||
slot = htab_find_slot_with_hash (object_block_htab, sect,
|
||||
hash_section (sect), INSERT);
|
||||
block = (struct object_block *) *slot;
|
||||
object_block **slot
|
||||
= object_block_htab->find_slot_with_hash (sect, hash_section (sect),
|
||||
INSERT);
|
||||
block = *slot;
|
||||
if (block == NULL)
|
||||
{
|
||||
block = ggc_cleared_alloc<object_block> ();
|
||||
@ -2824,15 +2829,13 @@ decode_addr_const (tree exp, struct addr_const *value)
|
||||
value->offset = offset;
|
||||
}
|
||||
|
||||
|
||||
static GTY((param_is (struct constant_descriptor_tree)))
|
||||
htab_t const_desc_htab;
|
||||
static GTY(()) hash_table<tree_descriptor_hasher> *const_desc_htab;
|
||||
|
||||
static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
|
||||
|
||||
/* Constant pool accessor function. */
|
||||
|
||||
htab_t
|
||||
hash_table<tree_descriptor_hasher> *
|
||||
constant_pool_htab (void)
|
||||
{
|
||||
return const_desc_htab;
|
||||
@ -2840,10 +2843,10 @@ constant_pool_htab (void)
|
||||
|
||||
/* Compute a hash code for a constant expression. */
|
||||
|
||||
static hashval_t
|
||||
const_desc_hash (const void *ptr)
|
||||
hashval_t
|
||||
tree_descriptor_hasher::hash (constant_descriptor_tree *ptr)
|
||||
{
|
||||
return ((const struct constant_descriptor_tree *)ptr)->hash;
|
||||
return ptr->hash;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
@ -2956,13 +2959,10 @@ const_hash_1 (const tree exp)
|
||||
}
|
||||
|
||||
/* Wrapper of compare_constant, for the htab interface. */
|
||||
static int
|
||||
const_desc_eq (const void *p1, const void *p2)
|
||||
bool
|
||||
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)
|
||||
return 0;
|
||||
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 key;
|
||||
void **loc;
|
||||
|
||||
/* Look up EXP in the table of constant descriptors. If we didn't find
|
||||
it, create a new one. */
|
||||
key.value = 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)
|
||||
{
|
||||
desc = build_constant_desc (exp);
|
||||
@ -3387,13 +3387,12 @@ output_constant_def_contents (rtx symbol)
|
||||
rtx
|
||||
lookup_constant_def (tree exp)
|
||||
{
|
||||
struct constant_descriptor_tree *desc;
|
||||
struct constant_descriptor_tree key;
|
||||
|
||||
key.value = exp;
|
||||
key.hash = const_hash_1 (exp);
|
||||
desc = (struct constant_descriptor_tree *)
|
||||
htab_find_with_hash (const_desc_htab, &key, key.hash);
|
||||
constant_descriptor_tree *desc
|
||||
= const_desc_htab->find_with_hash (&key, key.hash);
|
||||
|
||||
return (desc ? desc->rtl : NULL_RTX);
|
||||
}
|
||||
@ -3407,16 +3406,16 @@ tree
|
||||
tree_output_constant_def (tree exp)
|
||||
{
|
||||
struct constant_descriptor_tree *desc, key;
|
||||
void **loc;
|
||||
tree decl;
|
||||
|
||||
/* Look up EXP in the table of constant descriptors. If we didn't find
|
||||
it, create a new one. */
|
||||
key.value = 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)
|
||||
{
|
||||
desc = build_constant_desc (exp);
|
||||
@ -3429,6 +3428,25 @@ tree_output_constant_def (tree exp)
|
||||
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
|
||||
twice. Unlike 'struct constant_descriptor_tree', RTX constants
|
||||
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
|
||||
constant addresses are restricted so that such constants must be stored
|
||||
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
|
||||
machine-specific header). */
|
||||
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. */
|
||||
|
||||
static hashval_t
|
||||
const_desc_rtx_hash (const void *ptr)
|
||||
hashval_t
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
const_desc_rtx_eq (const void *a, const void *b)
|
||||
bool
|
||||
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)
|
||||
return 0;
|
||||
return rtx_equal_p (x->constant, y->constant);
|
||||
@ -3585,8 +3584,7 @@ create_constant_pool (void)
|
||||
struct rtx_constant_pool *pool;
|
||||
|
||||
pool = ggc_alloc<rtx_constant_pool> ();
|
||||
pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash,
|
||||
const_desc_rtx_eq, NULL);
|
||||
pool->const_rtx_htab = hash_table<const_rtx_desc_hasher>::create_ggc (31);
|
||||
pool->first = NULL;
|
||||
pool->last = NULL;
|
||||
pool->offset = 0;
|
||||
@ -3624,7 +3622,7 @@ force_const_mem (enum machine_mode mode, rtx x)
|
||||
rtx def, symbol;
|
||||
hashval_t hash;
|
||||
unsigned int align;
|
||||
void **slot;
|
||||
constant_descriptor_rtx **slot;
|
||||
|
||||
/* If we're not allowed to drop X into the constant pool, don't. */
|
||||
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.mode = mode;
|
||||
hash = const_rtx_hash (x);
|
||||
slot = htab_find_slot_with_hash (pool->const_rtx_htab, &tmp, hash, INSERT);
|
||||
desc = (struct constant_descriptor_rtx *) *slot;
|
||||
slot = pool->const_rtx_htab->find_slot_with_hash (&tmp, hash, INSERT);
|
||||
desc = *slot;
|
||||
|
||||
/* If the constant was already present, return its memory. */
|
||||
if (desc)
|
||||
@ -5923,12 +5921,9 @@ make_decl_one_only (tree decl, tree comdat_group)
|
||||
void
|
||||
init_varasm_once (void)
|
||||
{
|
||||
section_htab = htab_create_ggc (31, section_entry_hash,
|
||||
section_entry_eq, NULL);
|
||||
object_block_htab = htab_create_ggc (31, object_block_entry_hash,
|
||||
object_block_entry_eq, NULL);
|
||||
const_desc_htab = htab_create_ggc (1009, const_desc_hash,
|
||||
const_desc_eq, NULL);
|
||||
section_htab = hash_table<section_hasher>::create_ggc (31);
|
||||
object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
|
||||
const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
|
||||
|
||||
const_alias_set = new_alias_set ();
|
||||
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
|
||||
each member of object_block_htab. */
|
||||
|
||||
static int
|
||||
output_object_block_htab (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
output_object_block_htab (object_block **slot, void *)
|
||||
{
|
||||
output_object_block ((struct object_block *) (*slot));
|
||||
output_object_block (*slot);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -7267,7 +7262,7 @@ output_object_block_htab (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user