]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/34969 (ICE with -fipa-cp -ffast-math)
authorJakub Jelinek <jakub@redhat.com>
Tue, 29 Jan 2008 23:21:24 +0000 (00:21 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 29 Jan 2008 23:21:24 +0000 (00:21 +0100)
PR middle-end/34969
* cgraph.h (cgraph_update_edges_for_call_stmt): New prototype.
* cgraph.c (cgraph_update_edges_for_call_stmt): New function.
* tree-inline.c (fold_marked_statements): Call
cgraph_update_edges_for_call_stmt if folding a call statement.
* cgraphunit.c (verify_cgraph_node): Set cfun to this_cfun for
debug_generic_stmt calls, reset it back afterwards.

* gcc.dg/pr34969.c: New test.

From-SVN: r131946

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr34969.c [new file with mode: 0644]
gcc/tree-inline.c

index 5c5c8848e43b9c4c3c20693a08eeaa9975d91cbd..450214646c1ab84fa46eda5111f30307b3180ea5 100644 (file)
@@ -1,5 +1,13 @@
 2008-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/34969
+       * cgraph.h (cgraph_update_edges_for_call_stmt): New prototype.
+       * cgraph.c (cgraph_update_edges_for_call_stmt): New function.
+       * tree-inline.c (fold_marked_statements): Call
+       cgraph_update_edges_for_call_stmt if folding a call statement.
+       * cgraphunit.c (verify_cgraph_node): Set cfun to this_cfun for
+       debug_generic_stmt calls, reset it back afterwards.
+
        PR c/35017
        * c-decl.c (start_decl): Don't pedwarn about TREE_READONLY
        static decls.
index 8c7bc5da44221c7f73650e135918e1450997f347..649915e46181d1e3df72e55b7dea752a4597e202 100644 (file)
@@ -1,5 +1,6 @@
 /* Callgraph handling code.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Contributed by Jan Hubicka
 
 This file is part of GCC.
@@ -440,6 +441,51 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
   e->callee = n;
 }
 
+/* Update or remove corresponding cgraph edge if a call OLD_CALL
+   in OLD_STMT changed into NEW_STMT.  */
+
+void
+cgraph_update_edges_for_call_stmt (tree old_stmt, tree old_call,
+                                  tree new_stmt)
+{
+  tree new_call = get_call_expr_in (new_stmt);
+  struct cgraph_node *node = cgraph_node (cfun->decl);
+
+  if (old_call != new_call)
+    {
+      struct cgraph_edge *e = cgraph_edge (node, old_stmt);
+      struct cgraph_edge *ne = NULL;
+      tree new_decl;
+
+      if (e)
+       {
+         gcov_type count = e->count;
+         int frequency = e->frequency;
+         int loop_nest = e->loop_nest;
+
+         cgraph_remove_edge (e);
+         if (new_call)
+           {
+             new_decl = get_callee_fndecl (new_call);
+             if (new_decl)
+               {
+                 ne = cgraph_create_edge (node, cgraph_node (new_decl),
+                                          new_stmt, count, frequency,
+                                          loop_nest);
+                 gcc_assert (ne->inline_failed);
+               }
+           }
+       }
+    }
+  else if (old_stmt != new_stmt)
+    {
+      struct cgraph_edge *e = cgraph_edge (node, old_stmt);
+
+      if (e)
+       cgraph_set_call_stmt (e, new_stmt);
+    }
+}
+
 /* Remove all callees from the node.  */
 
 void
index baed1a6fef36487880ab6f1189d349c12b91712f..89ffeb6c45c0baf423914732cab8ae82af9b7036 100644 (file)
@@ -1,5 +1,6 @@
 /* Callgraph handling code.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Contributed by Jan Hubicka
 
 This file is part of GCC.
@@ -303,6 +304,7 @@ struct cgraph_node *cgraph_node (tree);
 struct cgraph_node *cgraph_node_for_asm (tree asmname);
 struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree);
 void cgraph_set_call_stmt (struct cgraph_edge *, tree);
+void cgraph_update_edges_for_call_stmt (tree, tree, tree);
 struct cgraph_local_info *cgraph_local_info (tree);
 struct cgraph_global_info *cgraph_global_info (tree);
 struct cgraph_rtl_info *cgraph_rtl_info (tree);
index 07b597f7bca626ce5da6c5826e9e0cf2c680582e..0d6a9fed9fcd5424ff6dc9a997d8392b52b1fa2c 100644 (file)
@@ -658,6 +658,7 @@ verify_cgraph_node (struct cgraph_node *node)
   struct cgraph_edge *e;
   struct cgraph_node *main_clone;
   struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
+  struct function *saved_cfun = cfun;
   basic_block this_block;
   block_stmt_iterator bsi;
   bool error_found = false;
@@ -666,6 +667,8 @@ verify_cgraph_node (struct cgraph_node *node)
     return;
 
   timevar_push (TV_CGRAPH_VERIFY);
+  /* debug_generic_stmt needs correct cfun */
+  set_cfun (this_cfun);
   for (e = node->callees; e; e = e->next_callee)
     if (e->aux)
       {
@@ -808,6 +811,7 @@ verify_cgraph_node (struct cgraph_node *node)
       dump_cgraph_node (stderr, node);
       internal_error ("verify_cgraph_node failed");
     }
+  set_cfun (saved_cfun);
   timevar_pop (TV_CGRAPH_VERIFY);
 }
 
index 11239a5e9cc694725a8ab864308944853d4853a6..5369f58ec08cedadfb65b1cb23003198da6d7d77 100644 (file)
@@ -1,5 +1,8 @@
 2008-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/34969
+       * gcc.dg/pr34969.c: New test.
+
        PR c/35017
        * gcc.dg/inline-25.c: New test.
        * gcc.dg/inline-26.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr34969.c b/gcc/testsuite/gcc.dg/pr34969.c
new file mode 100644 (file)
index 0000000..02f7dd1
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR middle-end/34969 */
+/* { dg-do compile } */
+/* { dg-options "-O -fipa-cp -ffast-math" } */
+
+double
+foo (double x)
+{
+  return x * x;
+}
+
+double
+bar (void)
+{
+  return foo (0);
+}
index d2ef9619eb2d8069e43ae0637e996dcc5afc2913..b683f20a70ea99b858b7107400d409c4ea4bac39 100644 (file)
@@ -2942,11 +2942,17 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
          if (pointer_set_contains (statements, bsi_stmt (bsi)))
            {
              tree old_stmt = bsi_stmt (bsi);
+             tree old_call = get_call_expr_in (old_stmt);
+
              if (fold_stmt (bsi_stmt_ptr (bsi)))
                {
                  update_stmt (bsi_stmt (bsi));
-                 if (maybe_clean_or_replace_eh_stmt (old_stmt, bsi_stmt (bsi)))
-                    tree_purge_dead_eh_edges (BASIC_BLOCK (first));
+                 if (old_call)
+                   cgraph_update_edges_for_call_stmt (old_stmt, old_call,
+                                                      bsi_stmt (bsi));
+                 if (maybe_clean_or_replace_eh_stmt (old_stmt,
+                                                     bsi_stmt (bsi)))
+                   tree_purge_dead_eh_edges (BASIC_BLOCK (first));
                }
            }
       }