aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-01-30 00:21:24 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-01-30 00:21:24 +0100
commit2bafad93f704c2909c8b5988a0b0e98b57993617 (patch)
treee67112931bc0870ff4c9d06efcb44ad08a4da4f2 /gcc
parent1033ffa8b312170efeeef1f3e4f58ced8075eaea (diff)
downloadgcc-2bafad93f704c2909c8b5988a0b0e98b57993617.zip
gcc-2bafad93f704c2909c8b5988a0b0e98b57993617.tar.gz
gcc-2bafad93f704c2909c8b5988a0b0e98b57993617.tar.bz2
re PR middle-end/34969 (ICE with -fipa-cp -ffast-math)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/cgraph.c48
-rw-r--r--gcc/cgraph.h4
-rw-r--r--gcc/cgraphunit.c4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/pr34969.c15
-rw-r--r--gcc/tree-inline.c10
7 files changed, 88 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5c5c884..45021464 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 8c7bc5d..649915e 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index baed1a6..89ffeb6 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 07b597f..0d6a9fe 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 11239a5..5369f58 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..02f7dd1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr34969.c
@@ -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);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index d2ef961..b683f20 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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));
}
}
}