diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-01-30 00:21:24 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-01-30 00:21:24 +0100 |
commit | 2bafad93f704c2909c8b5988a0b0e98b57993617 (patch) | |
tree | e67112931bc0870ff4c9d06efcb44ad08a4da4f2 /gcc/cgraph.c | |
parent | 1033ffa8b312170efeeef1f3e4f58ced8075eaea (diff) | |
download | gcc-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/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 48 |
1 files changed, 47 insertions, 1 deletions
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 |