This reduces the time spent in cgraph call-site hash by providing inline version of htab_hash_pointer.
Bootstrap / regtest on x86_64-unknown-linux-gnu in progress. Ok? Thanks, Richard. 2015-03-09 Richard Biener <rguent...@suse.de> PR middle-end/44563 * cgraph.h (struct cgraph_edge_hasher): Add hash overload for compare_type. * cgraph.c (cgraph_edge_hasher::hash): Inline htab_hash_pointer. (cgraph_update_edge_in_call_site_hash): Use cgraph_edge_hasher::hash. (cgraph_add_edge_to_call_site_hash): Likewise. (cgraph_node::get_edge): Likewise. (cgraph_edge::set_call_stmt): Likewise. (cgraph_edge::remove_caller): Likewise. Index: gcc/cgraph.c =================================================================== *** gcc/cgraph.c (revision 221277) --- gcc/cgraph.c (working copy) *************** cgraph_node::get_for_asmname (tree asmna *** 663,669 **** hashval_t cgraph_edge_hasher::hash (cgraph_edge *e) { ! return htab_hash_pointer (e->call_stmt); } /* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y. */ --- 663,681 ---- hashval_t cgraph_edge_hasher::hash (cgraph_edge *e) { ! /* This is a really poor hash function, but it is what the current code uses, ! so I am reusing it to avoid an additional axis in testing. */ ! return (hashval_t) ((intptr_t)e->call_stmt >> 3); ! } ! ! /* Returns a hash value for X (which really is a cgraph_edge). */ ! ! hashval_t ! cgraph_edge_hasher::hash (gimple call_stmt) ! { ! /* This is a really poor hash function, but it is what the current code uses, ! so I am reusing it to avoid an additional axis in testing. */ ! return (hashval_t) ((intptr_t)call_stmt >> 3); } /* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y. */ *************** static inline void *** 680,688 **** cgraph_update_edge_in_call_site_hash (cgraph_edge *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. */ --- 692,699 ---- cgraph_update_edge_in_call_site_hash (cgraph_edge *e) { gimple call = e->call_stmt; ! *e->caller->call_site_hash->find_slot_with_hash ! (call, cgraph_edge_hasher::hash (call), INSERT) = e; } /* Add call graph edge E to call site hash of its caller. */ *************** cgraph_add_edge_to_call_site_hash (cgrap *** 695,702 **** if (e->speculative && e->indirect_unknown_callee) return; 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); --- 706,712 ---- if (e->speculative && e->indirect_unknown_callee) return; cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash ! (e->call_stmt, cgraph_edge_hasher::hash (e->call_stmt), INSERT); if (*slot) { gcc_assert (((cgraph_edge *)*slot)->speculative); *************** cgraph_node::get_edge (gimple call_stmt) *** 718,725 **** int n = 0; if (call_site_hash) ! 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 --- 728,735 ---- int n = 0; if (call_site_hash) ! return call_site_hash->find_with_hash ! (call_stmt, cgraph_edge_hasher::hash (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 *************** cgraph_edge::set_call_stmt (gcall *new_s *** 782,788 **** && (!speculative || !indirect_unknown_callee)) { caller->call_site_hash->remove_elt_with_hash ! (call_stmt, htab_hash_pointer (call_stmt)); } cgraph_edge *e = this; --- 792,798 ---- && (!speculative || !indirect_unknown_callee)) { caller->call_site_hash->remove_elt_with_hash ! (call_stmt, cgraph_edge_hasher::hash (call_stmt)); } cgraph_edge *e = this; *************** cgraph_edge::remove_caller (void) *** 987,994 **** caller->callees = next_callee; } if (caller->call_site_hash) ! caller->call_site_hash->remove_elt_with_hash (call_stmt, ! htab_hash_pointer (call_stmt)); } /* Put the edge onto the free list. */ --- 997,1004 ---- caller->callees = next_callee; } if (caller->call_site_hash) ! caller->call_site_hash->remove_elt_with_hash ! (call_stmt, cgraph_edge_hasher::hash (call_stmt)); } /* Put the edge onto the free list. */ Index: gcc/cgraph.h =================================================================== *** gcc/cgraph.h (revision 221277) --- gcc/cgraph.h (working copy) *************** struct cgraph_edge_hasher : ggc_hasher<c *** 788,793 **** --- 788,794 ---- typedef gimple compare_type; static hashval_t hash (cgraph_edge *); + static hashval_t hash (gimple); static bool equal (cgraph_edge *, gimple); };