summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-15 01:20:55 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-15 01:20:55 +0000
commitb9ffeffbda2ebaa239bbec69abe2097f10fc94ae (patch)
tree02fe16310bd09fdf1d3c23fde7236a1aa760fb1b
parent7ba5025ccf30bc2924867e7a8889f2a8c2cc231c (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cgraph.c15
-rw-r--r--gcc/cgraph.h7
-rw-r--r--gcc/cgraphunit.c4
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/lto/pr45621.h8
-rw-r--r--gcc/testsuite/g++.dg/lto/pr45621_0.C10
-rw-r--r--gcc/testsuite/g++.dg/lto/pr45621_1.C13
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 ();
+}