diff options
author | Jan Hubicka <jh@suse.cz> | 2008-07-13 12:06:19 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2008-07-13 10:06:19 +0000 |
commit | 266ad5c82612749d080ab25f67a677c89b344567 (patch) | |
tree | 1ee8898b82ca9a88353189796c35234da2da21d2 /gcc/cgraph.c | |
parent | 52ca125521c3e1d5b9fff7e3710ccbfdd3b2d797 (diff) | |
download | gcc-266ad5c82612749d080ab25f67a677c89b344567.zip gcc-266ad5c82612749d080ab25f67a677c89b344567.tar.gz gcc-266ad5c82612749d080ab25f67a677c89b344567.tar.bz2 |
cgraph.c (assembler_name_hash): New static var.
* cgraph.c (assembler_name_hash): New static var.
(hash_node_by_assembler_name, eq_assembler_name): New.
(cgraph_node_for_asm): Use hashtable.
(cgraph_remove_node): Maintain hashtable.
(change_decl_assembler_name): Sanity check that names are not changing
after aliasing was processed.
* cgraph.h (varpoon_node): Add next GGC marker.
* tree.c (decl_assembler_name_equal): Constify.
(decl_assembler_name_hash): New.
* tree.h (decl_assembler_name_equal): Constify.
(decl_assembler_name_hash): Update.
From-SVN: r137753
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 6a80bbe..881bc42 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -91,6 +91,8 @@ static inline void cgraph_edge_remove_callee (struct cgraph_edge *e); /* Hash table used to convert declarations into nodes. */ static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; +/* Hash table used to convert assembler names into nodes. */ +static GTY((param_is (struct cgraph_node))) htab_t assembler_name_hash; /* The linked list of cgraph nodes. */ struct cgraph_node *cgraph_nodes; @@ -409,6 +411,18 @@ cgraph_node (tree decl) node->origin->nested = node; node->master_clone = node; } + + /* This code can go away once flag_unit_at_a_mode is removed. */ + if (assembler_name_hash) + { + tree name = DECL_ASSEMBLER_NAME (node->decl); + slot = ((struct cgraph_node **) + htab_find_slot_with_hash (assembler_name_hash, name, + decl_assembler_name_hash (name), + INSERT)); + if (!*slot) + *slot = node; + } return node; } @@ -425,6 +439,24 @@ cgraph_insert_node_to_hashtable (struct cgraph_node *node) *slot = node; } +/* Returns a hash code for P. */ + +static hashval_t +hash_node_by_assembler_name (const void *p) +{ + const struct cgraph_node *n = (const struct cgraph_node *) p; + return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl)); +} + +/* Returns nonzero if P1 and P2 are equal. */ + +static int +eq_assembler_name (const void *p1, const void *p2) +{ + const struct cgraph_node *n1 = (const struct cgraph_node *) p1; + const_tree name = (const_tree)p2; + return (decl_assembler_name_equal (n1->decl, name)); +} /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME. Return NULL if there's no such node. */ @@ -433,11 +465,36 @@ struct cgraph_node * cgraph_node_for_asm (tree asmname) { struct cgraph_node *node; + void **slot; - for (node = cgraph_nodes; node ; node = node->next) - if (decl_assembler_name_equal (node->decl, asmname)) - return node; + if (!assembler_name_hash) + { + assembler_name_hash = + htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name, + NULL); + for (node = cgraph_nodes; node; node = node->next) + if (!node->global.inlined_to) + { + tree name = DECL_ASSEMBLER_NAME (node->decl); + slot = htab_find_slot_with_hash (assembler_name_hash, name, + decl_assembler_name_hash (name), + INSERT); + /* We can have multiple declarations with same assembler name. For C++ + it is __builtin_strlen and strlen, for instance. Do we need to + record them all? Original implementation marked just first one + so lets hope for the best. */ + if (*slot) + continue; + *slot = node; + } + } + + slot = htab_find_slot_with_hash (assembler_name_hash, asmname, + decl_assembler_name_hash (asmname), + NO_INSERT); + if (slot) + return (struct cgraph_node *) *slot; return NULL; } @@ -763,6 +820,7 @@ cgraph_remove_node (struct cgraph_node *node) cgraph_call_node_removal_hooks (node); cgraph_node_remove_callers (node); cgraph_node_remove_callees (node); + /* Incremental inlining access removed nodes stored in the postorder list. */ node->needed = node->reachable = false; @@ -824,6 +882,16 @@ cgraph_remove_node (struct cgraph_node *node) && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))) kill_body = true; } + if (assembler_name_hash) + { + tree name = DECL_ASSEMBLER_NAME (node->decl); + slot = htab_find_slot_with_hash (assembler_name_hash, name, + decl_assembler_name_hash (name), + NO_INSERT); + /* Inline clones are not hashed. */ + if (slot && *slot == node) + htab_clear_slot (assembler_name_hash, slot); + } if (kill_body && flag_unit_at_a_time) cgraph_release_function_body (node); @@ -1038,6 +1106,7 @@ debug_cgraph (void) void change_decl_assembler_name (tree decl, tree name) { + gcc_assert (!assembler_name_hash); if (!DECL_ASSEMBLER_NAME_SET_P (decl)) { SET_DECL_ASSEMBLER_NAME (decl, name); |