--- 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