Commit 2bafad93 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 1033ffa8
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.
......
/* 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
......
/* 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);
......
......@@ -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);
}
......
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.
/* 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);
}
......@@ -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));
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment