Commit 97ba0040 by Jan Hubicka Committed by Jan Hubicka

re PR rtl-optimization/45621 (ICE: verify_cgraph_node failed: inlined_to pointer…

re PR rtl-optimization/45621 (ICE: verify_cgraph_node failed: inlined_to pointer is set but no predecessors found with -fipa-cp-clone -flto)


	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.

From-SVN: r165492
parent 23ac8b8d
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> 2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
merge from FSF apple 'trunk' branch. merge from FSF apple 'trunk' branch.
...@@ -1241,9 +1241,18 @@ cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node, ...@@ -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 /* See if the edge is already there and has the correct callee. It
might be so because of indirect inlining has already updated might be so because of indirect inlining has already updated
it. */ it. We also might've cloned and redirected the edge. */
if (new_call && e->callee && e->callee->decl == new_call) if (new_call && e->callee)
return; {
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 /* Otherwise remove edge and create new one; we can't simply redirect
since function has changed, so inline plan and other information since function has changed, so inline plan and other information
......
...@@ -227,11 +227,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { ...@@ -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 /* For functions with many calls sites it holds map from call expression
to the edge to speed up cgraph_edge function. */ to the edge to speed up cgraph_edge function. */
htab_t GTY((param_is (struct cgraph_edge))) call_site_hash; htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
#ifdef ENABLE_CHECKING /* Declaration node used to be clone of. */
/* Declaration node used to be clone of. Used for checking only. tree former_clone_of;
We must skip it or we get references from release checking GGC files. */
tree GTY ((skip)) former_clone_of;
#endif
PTR GTY ((skip)) aux; PTR GTY ((skip)) aux;
......
...@@ -656,7 +656,6 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -656,7 +656,6 @@ verify_cgraph_node (struct cgraph_node *node)
debug_tree (e->callee->decl); debug_tree (e->callee->decl);
error_found = true; error_found = true;
} }
#ifdef ENABLE_CHECKING
else if (!e->callee->global.inlined_to else if (!e->callee->global.inlined_to
&& decl && decl
&& cgraph_get_node (decl) && cgraph_get_node (decl)
...@@ -671,7 +670,6 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -671,7 +670,6 @@ verify_cgraph_node (struct cgraph_node *node)
debug_tree (decl); debug_tree (decl);
error_found = true; error_found = true;
} }
#endif
} }
else if (decl) else if (decl)
{ {
...@@ -2079,11 +2077,9 @@ static void ...@@ -2079,11 +2077,9 @@ static void
cgraph_materialize_clone (struct cgraph_node *node) cgraph_materialize_clone (struct cgraph_node *node)
{ {
bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (NULL);
#ifdef ENABLE_CHECKING
node->former_clone_of = node->clone_of->decl; node->former_clone_of = node->clone_of->decl;
if (node->clone_of->former_clone_of) if (node->clone_of->former_clone_of)
node->former_clone_of = 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. */ /* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (node->clone_of->decl, node->decl, tree_function_versioning (node->clone_of->decl, node->decl,
node->clone.tree_map, true, node->clone.tree_map, true,
......
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> 2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
* objc.dg/property: New. * objc.dg/property: New.
......
struct S
{
void m ();
virtual void v1 ();
virtual void v2 ();
};
extern S s;
// { dg-lto-do assemble }
// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -nostdlib -r" }
#include "pr45621.h"
void
foo ()
{
s.v1 ();
s.m ();
}
#include "pr45621.h"
void
S::v1 ()
{
v2 ();
}
void
S::m ()
{
v1 ();
}
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