diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-15 01:20:55 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-15 01:20:55 +0000 |
commit | b9ffeffbda2ebaa239bbec69abe2097f10fc94ae (patch) | |
tree | 02fe16310bd09fdf1d3c23fde7236a1aa760fb1b | |
parent | 7ba5025ccf30bc2924867e7a8889f2a8c2cc231c (diff) | |
download | gcc-b9ffeffbda2ebaa239bbec69abe2097f10fc94ae.tar.gz |
PR middle-end/45621
* g++.dg/lto/pr45621.h : New.
* g++.dg/lto/pr45621_0.C: New.
* g++.dg/lto/pr45621_1.C: New.
* cgraph.c (cgraph_update_edges_for_call_stmt_node): When new call is
redirected to clone, be happy.
* cgraph.h (cgraph node): Enable former_clone_of unconditinally.
* cgraphunit.c (verify_cgraph_node, cgraph_materialize_clone): Handle
former_clone_of unconditinally.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165492 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cgraph.c | 15 | ||||
-rw-r--r-- | gcc/cgraph.h | 7 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45621.h | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45621_0.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45621_1.C | 13 |
8 files changed, 61 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 262a377d108..5c0d576f402 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-10-14 Jan Hubicka <jh@suse.cz> + + PR middle-end/45621 + * cgraph.c (cgraph_update_edges_for_call_stmt_node): When new call is + redirected to clone, be happy. + * cgraph.h (cgraph node): Enable former_clone_of unconditinally. + * cgraphunit.c (verify_cgraph_node, cgraph_materialize_clone): Handle + former_clone_of unconditinally. + 2010-10-14 Iain Sandoe <iains@gcc.gnu.org> merge from FSF apple 'trunk' branch. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7293b6dee03..465e9afbf79 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1241,9 +1241,18 @@ cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node, { /* See if the edge is already there and has the correct callee. It might be so because of indirect inlining has already updated - it. */ - if (new_call && e->callee && e->callee->decl == new_call) - return; + it. We also might've cloned and redirected the edge. */ + if (new_call && e->callee) + { + struct cgraph_node *callee = e->callee; + while (callee) + { + if (callee->decl == new_call + || callee->former_clone_of == new_call) + return; + callee = callee->clone_of; + } + } /* Otherwise remove edge and create new one; we can't simply redirect since function has changed, so inline plan and other information diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 330c8839636..d7ca67c692f 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -227,11 +227,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { /* For functions with many calls sites it holds map from call expression to the edge to speed up cgraph_edge function. */ htab_t GTY((param_is (struct cgraph_edge))) call_site_hash; -#ifdef ENABLE_CHECKING - /* Declaration node used to be clone of. Used for checking only. - We must skip it or we get references from release checking GGC files. */ - tree GTY ((skip)) former_clone_of; -#endif + /* Declaration node used to be clone of. */ + tree former_clone_of; PTR GTY ((skip)) aux; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 95b30074037..7d4349a8b6d 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -656,7 +656,6 @@ verify_cgraph_node (struct cgraph_node *node) debug_tree (e->callee->decl); error_found = true; } -#ifdef ENABLE_CHECKING else if (!e->callee->global.inlined_to && decl && cgraph_get_node (decl) @@ -671,7 +670,6 @@ verify_cgraph_node (struct cgraph_node *node) debug_tree (decl); error_found = true; } -#endif } else if (decl) { @@ -2079,11 +2077,9 @@ static void cgraph_materialize_clone (struct cgraph_node *node) { bitmap_obstack_initialize (NULL); -#ifdef ENABLE_CHECKING node->former_clone_of = node->clone_of->decl; if (node->clone_of->former_clone_of) node->former_clone_of = node->clone_of->former_clone_of; -#endif /* Copy the OLD_VERSION_NODE function tree to the new version. */ tree_function_versioning (node->clone_of->decl, node->decl, node->clone.tree_map, true, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f722e3747dc..6f8e1fdf9da 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-10-14 Jan Hubicka <jh@suse.cz> + + PR middle-end/45621 + * g++.dg/lto/pr45621.h : New. + * g++.dg/lto/pr45621_0.C: New. + * g++.dg/lto/pr45621_1.C: New. + 2010-10-14 Iain Sandoe <iains@gcc.gnu.org> * objc.dg/property: New. diff --git a/gcc/testsuite/g++.dg/lto/pr45621.h b/gcc/testsuite/g++.dg/lto/pr45621.h new file mode 100644 index 00000000000..81a764225c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45621.h @@ -0,0 +1,8 @@ +struct S +{ + void m (); + virtual void v1 (); + virtual void v2 (); +}; + +extern S s; diff --git a/gcc/testsuite/g++.dg/lto/pr45621_0.C b/gcc/testsuite/g++.dg/lto/pr45621_0.C new file mode 100644 index 00000000000..746079cdceb --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45621_0.C @@ -0,0 +1,10 @@ +// { dg-lto-do assemble } +// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -nostdlib -r" } +#include "pr45621.h" + +void +foo () +{ + s.v1 (); + s.m (); +} diff --git a/gcc/testsuite/g++.dg/lto/pr45621_1.C b/gcc/testsuite/g++.dg/lto/pr45621_1.C new file mode 100644 index 00000000000..2ada6a8798e --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45621_1.C @@ -0,0 +1,13 @@ +#include "pr45621.h" + +void +S::v1 () +{ + v2 (); +} + +void +S::m () +{ + v1 (); +} |