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

Reply via email to