Hi,
while playing around with devirtualization I tried to make it to always produce
builtin_unreachable ().  This makes early inliner to ICE, since the callgraph 
edges
are not properly updated after folding. This is because 
cgraph_update_edges_for_call_stmt
is called on a wrong statement.

Does something like this look resonable?

Honza

        * tree-inline.c (fold_marked_statements): Correctly handle cases where
        folding produes extra statement.
Index: tree-inline.c
===================================================================
--- tree-inline.c       (revision 207438)
+++ tree-inline.c       (working copy)
@@ -4480,8 +4480,14 @@ fold_marked_statements (int first, struc
          if (pointer_set_contains (statements, gsi_stmt (gsi)))
            {
              gimple old_stmt = gsi_stmt (gsi);
+             gimple_stmt_iterator prev = gsi;
+             gimple prev_stmt = NULL;
              tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl 
(old_stmt) : 0;
 
+             gsi_prev (&prev);
+             if (!gsi_end_p (prev))
+               prev_stmt = gsi_stmt (prev);
+
              if (old_decl && DECL_BUILT_IN (old_decl))
                {
                  /* Folding builtins can create multiple instructions,
@@ -4541,8 +4547,31 @@ fold_marked_statements (int first, struc
 
                  if (is_gimple_call (old_stmt)
                      || is_gimple_call (new_stmt))
-                   cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
-                                                      new_stmt);
+                   {
+                     if (!is_gimple_call (new_stmt))
+                       {
+                         prev = gsi;
+                         gsi_prev (&prev);
+
+                         /* Fold stmt may turn
+
+                            retval = call ();
+
+                            statement into
+
+                            __builtin_unreachable ();
+                            retval = dummy.
+
+                            Be sure to look up the call.  */
+                            
+                         if (!gsi_end_p (prev)
+                             && gsi_stmt (prev) != prev_stmt
+                             && is_gimple_call (gsi_stmt (prev)))
+                            new_stmt = gsi_stmt (prev);
+                       }
+                     cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
+                                                        new_stmt);
+                   }
 
                  if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt))
                    gimple_purge_dead_eh_edges (BASIC_BLOCK_FOR_FN (cfun,

Reply via email to