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
This commit is contained in:
Jakub Jelinek 2008-01-30 00:21:24 +01:00 committed by Jakub Jelinek
parent 1033ffa8b3
commit 2bafad93f7
7 changed files with 88 additions and 4 deletions

View File

@ -1,5 +1,13 @@
2008-01-30 Jakub Jelinek <jakub@redhat.com> 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 PR c/35017
* c-decl.c (start_decl): Don't pedwarn about TREE_READONLY * c-decl.c (start_decl): Don't pedwarn about TREE_READONLY
static decls. static decls.

View File

@ -1,5 +1,6 @@
/* Callgraph handling code. /* 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 Contributed by Jan Hubicka
This file is part of GCC. 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; 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. */ /* Remove all callees from the node. */
void void

View File

@ -1,5 +1,6 @@
/* Callgraph handling code. /* 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 Contributed by Jan Hubicka
This file is part of GCC. 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_node *cgraph_node_for_asm (tree asmname);
struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree); struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree);
void cgraph_set_call_stmt (struct cgraph_edge *, 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_local_info *cgraph_local_info (tree);
struct cgraph_global_info *cgraph_global_info (tree); struct cgraph_global_info *cgraph_global_info (tree);
struct cgraph_rtl_info *cgraph_rtl_info (tree); struct cgraph_rtl_info *cgraph_rtl_info (tree);

View File

@ -658,6 +658,7 @@ verify_cgraph_node (struct cgraph_node *node)
struct cgraph_edge *e; struct cgraph_edge *e;
struct cgraph_node *main_clone; struct cgraph_node *main_clone;
struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
struct function *saved_cfun = cfun;
basic_block this_block; basic_block this_block;
block_stmt_iterator bsi; block_stmt_iterator bsi;
bool error_found = false; bool error_found = false;
@ -666,6 +667,8 @@ verify_cgraph_node (struct cgraph_node *node)
return; return;
timevar_push (TV_CGRAPH_VERIFY); timevar_push (TV_CGRAPH_VERIFY);
/* debug_generic_stmt needs correct cfun */
set_cfun (this_cfun);
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
if (e->aux) if (e->aux)
{ {
@ -808,6 +811,7 @@ verify_cgraph_node (struct cgraph_node *node)
dump_cgraph_node (stderr, node); dump_cgraph_node (stderr, node);
internal_error ("verify_cgraph_node failed"); internal_error ("verify_cgraph_node failed");
} }
set_cfun (saved_cfun);
timevar_pop (TV_CGRAPH_VERIFY); timevar_pop (TV_CGRAPH_VERIFY);
} }

View File

@ -1,5 +1,8 @@
2008-01-30 Jakub Jelinek <jakub@redhat.com> 2008-01-30 Jakub Jelinek <jakub@redhat.com>
PR middle-end/34969
* gcc.dg/pr34969.c: New test.
PR c/35017 PR c/35017
* gcc.dg/inline-25.c: New test. * gcc.dg/inline-25.c: New test.
* gcc.dg/inline-26.c: New test. * gcc.dg/inline-26.c: New test.

View File

@ -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);
}

View File

@ -2942,10 +2942,16 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
if (pointer_set_contains (statements, bsi_stmt (bsi))) if (pointer_set_contains (statements, bsi_stmt (bsi)))
{ {
tree old_stmt = 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))) if (fold_stmt (bsi_stmt_ptr (bsi)))
{ {
update_stmt (bsi_stmt (bsi)); update_stmt (bsi_stmt (bsi));
if (maybe_clean_or_replace_eh_stmt (old_stmt, bsi_stmt (bsi))) 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)); tree_purge_dead_eh_edges (BASIC_BLOCK (first));
} }
} }