Commit 266ad5c8 by Jan Hubicka Committed by Jan Hubicka

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
parent 52ca1255
2008-07-12 Jan Hubicka <jh@suse.cz>
* 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.
2008-07-12 David Daney <ddaney@avtrex.com> 2008-07-12 David Daney <ddaney@avtrex.com>
* config/mips/driver-native.c (host_detect_local_cpu): Handle * config/mips/driver-native.c (host_detect_local_cpu): Handle
......
...@@ -91,6 +91,8 @@ static inline void cgraph_edge_remove_callee (struct cgraph_edge *e); ...@@ -91,6 +91,8 @@ static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
/* Hash table used to convert declarations into nodes. */ /* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; 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. */ /* The linked list of cgraph nodes. */
struct cgraph_node *cgraph_nodes; struct cgraph_node *cgraph_nodes;
...@@ -409,6 +411,18 @@ cgraph_node (tree decl) ...@@ -409,6 +411,18 @@ cgraph_node (tree decl)
node->origin->nested = node; node->origin->nested = node;
node->master_clone = 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; return node;
} }
...@@ -425,6 +439,24 @@ cgraph_insert_node_to_hashtable (struct cgraph_node *node) ...@@ -425,6 +439,24 @@ cgraph_insert_node_to_hashtable (struct cgraph_node *node)
*slot = 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 the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
Return NULL if there's no such node. */ Return NULL if there's no such node. */
...@@ -433,11 +465,36 @@ struct cgraph_node * ...@@ -433,11 +465,36 @@ struct cgraph_node *
cgraph_node_for_asm (tree asmname) cgraph_node_for_asm (tree asmname)
{ {
struct cgraph_node *node; struct cgraph_node *node;
void **slot;
for (node = cgraph_nodes; node ; node = node->next) if (!assembler_name_hash)
if (decl_assembler_name_equal (node->decl, asmname)) {
return node; 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; return NULL;
} }
...@@ -763,6 +820,7 @@ cgraph_remove_node (struct cgraph_node *node) ...@@ -763,6 +820,7 @@ cgraph_remove_node (struct cgraph_node *node)
cgraph_call_node_removal_hooks (node); cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node); cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
/* Incremental inlining access removed nodes stored in the postorder list. /* Incremental inlining access removed nodes stored in the postorder list.
*/ */
node->needed = node->reachable = false; node->needed = node->reachable = false;
...@@ -824,6 +882,16 @@ cgraph_remove_node (struct cgraph_node *node) ...@@ -824,6 +882,16 @@ cgraph_remove_node (struct cgraph_node *node)
&& (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl)))) && (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl))))
kill_body = true; 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) if (kill_body && flag_unit_at_a_time)
cgraph_release_function_body (node); cgraph_release_function_body (node);
...@@ -1038,6 +1106,7 @@ debug_cgraph (void) ...@@ -1038,6 +1106,7 @@ debug_cgraph (void)
void void
change_decl_assembler_name (tree decl, tree name) change_decl_assembler_name (tree decl, tree name)
{ {
gcc_assert (!assembler_name_hash);
if (!DECL_ASSEMBLER_NAME_SET_P (decl)) if (!DECL_ASSEMBLER_NAME_SET_P (decl))
{ {
SET_DECL_ASSEMBLER_NAME (decl, name); SET_DECL_ASSEMBLER_NAME (decl, name);
......
...@@ -224,7 +224,7 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap); ...@@ -224,7 +224,7 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
/* The varpool data structure. /* The varpool data structure.
Each static variable decl has assigned varpool_node. */ Each static variable decl has assigned varpool_node. */
struct varpool_node GTY(()) struct varpool_node GTY((chain_next ("%h.next")))
{ {
tree decl; tree decl;
/* Pointer to the next function in varpool_nodes. */ /* Pointer to the next function in varpool_nodes. */
......
...@@ -347,7 +347,7 @@ decl_assembler_name (tree decl) ...@@ -347,7 +347,7 @@ decl_assembler_name (tree decl)
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */ /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
bool bool
decl_assembler_name_equal (tree decl, tree asmname) decl_assembler_name_equal (tree decl, const_tree asmname)
{ {
tree decl_asmname = DECL_ASSEMBLER_NAME (decl); tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
...@@ -378,6 +378,27 @@ decl_assembler_name_equal (tree decl, tree asmname) ...@@ -378,6 +378,27 @@ decl_assembler_name_equal (tree decl, tree asmname)
return false; return false;
} }
/* Hash asmnames ignoring the user specified marks. */
hashval_t
decl_assembler_name_hash (const_tree asmname)
{
if (IDENTIFIER_POINTER (asmname)[0] == '*')
{
const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
size_t ulp_len = strlen (user_label_prefix);
if (ulp_len == 0)
;
else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
decl_str += ulp_len;
return htab_hash_string (decl_str);
}
return htab_hash_string (IDENTIFIER_POINTER (asmname));
}
/* Compute the number of bytes occupied by a tree with code CODE. /* Compute the number of bytes occupied by a tree with code CODE.
This function cannot be used for nodes that have variable sizes, This function cannot be used for nodes that have variable sizes,
including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR. */ including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR. */
......
...@@ -3923,7 +3923,8 @@ enum ptrmemfunc_vbit_where_t ...@@ -3923,7 +3923,8 @@ enum ptrmemfunc_vbit_where_t
#define NULL_TREE (tree) NULL #define NULL_TREE (tree) NULL
extern tree decl_assembler_name (tree); extern tree decl_assembler_name (tree);
extern bool decl_assembler_name_equal (tree decl, tree asmname); extern bool decl_assembler_name_equal (tree decl, const_tree asmname);
extern hashval_t decl_assembler_name_hash (const_tree asmname);
/* Compute the number of bytes occupied by 'node'. This routine only /* Compute the number of bytes occupied by 'node'. This routine only
looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */ looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */
......
...@@ -5380,7 +5380,10 @@ assemble_alias (tree decl, tree target) ...@@ -5380,7 +5380,10 @@ assemble_alias (tree decl, tree target)
/* If the target has already been emitted, we don't have to queue the /* If the target has already been emitted, we don't have to queue the
alias. This saves a tad of memory. */ alias. This saves a tad of memory. */
target_decl = find_decl_and_mark_needed (decl, target); if (!flag_unit_at_a_time || cgraph_global_info_ready)
target_decl = find_decl_and_mark_needed (decl, target);
else
target_decl= NULL;
if (target_decl && TREE_ASM_WRITTEN (target_decl)) if (target_decl && TREE_ASM_WRITTEN (target_decl))
do_assemble_alias (decl, target); do_assemble_alias (decl, target);
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment