https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44563

--- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #16)
> callgrind shows the cgraph_edge_hasher quite high in the profile (via
> redirect_all_calls).  I suppose as the large main is a single BB walking
> all stmts over-and-over is quite bad.  Also hash_pointer isn't inlined!?
> Ah - it's external in libiberty hashtab.c ... - it should transition to
> using/inheriting from pointer_hash.
> 
> cgraph_edge *
> cgraph_node::get_edge (gimple call_stmt)
> {
>   cgraph_edge *e, *e2;
>   int n = 0;
> 
>   if (call_site_hash)
>     return call_site_hash->find_with_hash (call_stmt,
>                                            htab_hash_pointer (call_stmt));
> 

Btw, for 10000 calls (smaller testcase) we get 100 000 000 calls to
cgraph_edge::redirect_call_stmt_to_callee () (that's from 40000
redirect_all_calls calls which is from 10000 optimize_inline_calls calls).

Ah - we do this also for the ENTRY/EXIT block!

Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c   (revision 221278)
+++ gcc/tree-inline.c   (working copy)
@@ -2802,11 +2802,13 @@ copy_cfg_body (copy_body_data * id, gcov
        if (need_debug_cleanup
            && bb->index != ENTRY_BLOCK
            && bb->index != EXIT_BLOCK)
-         maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux);
-       /* Update call edge destinations.  This can not be done before loop
-          info is updated, because we may split basic blocks.  */
-       if (id->transform_call_graph_edges == CB_CGE_DUPLICATE)
-         redirect_all_calls (id, (basic_block)bb->aux);
+         {
+           maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux);
+           /* Update call edge destinations.  This can not be done before loop
+              info is updated, because we may split basic blocks.  */
+           if (id->transform_call_graph_edges == CB_CGE_DUPLICATE)
+             redirect_all_calls (id, (basic_block)bb->aux);
+         }
        ((basic_block)bb->aux)->aux = NULL;
        bb->aux = NULL;
       }

makes sense?

> The estimate_calls_size_and_time portion is quite smaller.
> 
> cleanup-cfgs main portion is split_bb_on_noreturn_calls.

Reply via email to