From 266ad5c82612749d080ab25f67a677c89b344567 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 13 Jul 2008 12:06:19 +0200 Subject: 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 --- gcc/ChangeLog | 14 +++++++++++ gcc/cgraph.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- gcc/cgraph.h | 2 +- gcc/tree.c | 23 +++++++++++++++++- gcc/tree.h | 3 ++- gcc/varasm.c | 5 +++- 6 files changed, 115 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f9971d..d38611b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2008-07-12 Jan Hubicka + + * 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 * config/mips/driver-native.c (host_detect_local_cpu): Handle 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); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index ee79c92..070bd77 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -224,7 +224,7 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap); /* The varpool data structure. Each static variable decl has assigned varpool_node. */ -struct varpool_node GTY(()) +struct varpool_node GTY((chain_next ("%h.next"))) { tree decl; /* Pointer to the next function in varpool_nodes. */ diff --git a/gcc/tree.c b/gcc/tree.c index 14ecf38..81c471b 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -347,7 +347,7 @@ decl_assembler_name (tree decl) /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */ 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); @@ -378,6 +378,27 @@ decl_assembler_name_equal (tree decl, tree asmname) 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. This function cannot be used for nodes that have variable sizes, including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR. */ diff --git a/gcc/tree.h b/gcc/tree.h index f5b2f66..103f802 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3923,7 +3923,8 @@ enum ptrmemfunc_vbit_where_t #define NULL_TREE (tree) NULL 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 looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index d8c6114..49cdda4 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5380,7 +5380,10 @@ assemble_alias (tree decl, tree target) /* If the target has already been emitted, we don't have to queue the 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)) do_assemble_alias (decl, target); else -- cgit v1.1