------- Comment #4 from hubicka at ucw dot cz 2009-05-09 21:06 ------- Subject: Re: [4.5 Regression] Revision 147294 failed 483.xalancbmk in SPEC CPU 2006 at -O3
Hi, I am testing the following patch thasolves the ICE. Problem here was that we cleated ipa-cp clone and clonning proces allowed devirtualization that however creates new dirrect call and callgraph is not properly updated. We should handle devirtualization when inlining or const propagating, this seems common case. We seem to miss here number of inlining oppurtunities. Honza Index: tree-inline.c =================================================================== --- tree-inline.c (revision 147320) +++ tree-inline.c (working copy) @@ -1522,7 +1522,8 @@ copy_bb (copy_body_data *id, basic_block gcc_assert (dest->needed || !dest->analyzed); if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) cgraph_create_edge_including_clones (id->dst_node, dest, stmt, - bb->count, CGRAPH_FREQ_BASE, + bb->count, + compute_call_stmt_bb_frequency (id->dst_node->decl, bb), bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL); else @@ -3535,8 +3536,9 @@ fold_marked_statements (int first, struc if (BASIC_BLOCK (first)) { gimple_stmt_iterator gsi; + basic_block bb = BASIC_BLOCK (first); - for (gsi = gsi_start_bb (BASIC_BLOCK (first)); + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) if (pointer_set_contains (statements, gsi_stmt (gsi))) @@ -3545,14 +3547,26 @@ fold_marked_statements (int first, struc if (fold_stmt (&gsi)) { + tree decl; + /* Re-read the statement from GSI as fold_stmt() may have changed it. */ gimple new_stmt = gsi_stmt (gsi); update_stmt (new_stmt); - if (is_gimple_call (old_stmt)) - cgraph_update_edges_for_call_stmt (old_stmt, new_stmt); + if (is_gimple_call (new_stmt) + && (decl = gimple_call_fndecl (new_stmt))) + { + struct cgraph_node *node = cgraph_node (current_function_decl); + if (cgraph_edge (node, old_stmt)) + cgraph_update_edges_for_call_stmt (old_stmt, new_stmt); + else + cgraph_create_edge_including_clones + (node, cgraph_node (decl), new_stmt, bb->count, + compute_call_stmt_bb_frequency (current_function_decl, bb), + bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL); + } if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) gimple_purge_dead_eh_edges (BASIC_BLOCK (first)); } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40084