Commit d284e1b8 by Martin Jambor Committed by Martin Jambor

re PR ipa/61160 (wrong code with -O3 (or ICE: verify_cgraph_node failed: edge…

re PR ipa/61160 (wrong code with -O3 (or ICE: verify_cgraph_node failed: edge points to wrong declaration))

2014-06-27  Martin Jambor  <mjambor@suse.cz>

	PR ipa/61160
	* cgraphclones.c (duplicate_thunk_for_node): Removed parameter
	args_to_skip, use those from node instead.  Copy args_to_skip and
	combined_args_to_skip from node to the new thunk.
	(redirect_edge_duplicating_thunks): Removed parameter args_to_skip.
	(cgraph_create_virtual_clone): Moved computation of
	combined_args_to_skip...
	(cgraph_clone_node): ...here, simplify it to bitmap_ior..

testsuite/
	* g++.dg/ipa/pr61160-2.C: New test.
	* g++.dg/ipa/pr61160-3.C: Likewise.

From-SVN: r212071
parent f012c1ab
2014-06-27 Martin Jambor <mjambor@suse.cz>
PR ipa/61160
* cgraphclones.c (duplicate_thunk_for_node): Removed parameter
args_to_skip, use those from node instead. Copy args_to_skip and
combined_args_to_skip from node to the new thunk.
(redirect_edge_duplicating_thunks): Removed parameter args_to_skip.
(cgraph_create_virtual_clone): Moved computation of
combined_args_to_skip...
(cgraph_clone_node): ...here, simplify it to bitmap_ior..
2014-06-27 trevor Saunders <tsaunders@mozilla.com> 2014-06-27 trevor Saunders <tsaunders@mozilla.com>
* config/i386/winnt.c (i386_pe_section_type_flags): Remove * config/i386/winnt.c (i386_pe_section_type_flags): Remove
......
...@@ -301,14 +301,13 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node) ...@@ -301,14 +301,13 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
thunk is this_adjusting but we are removing this parameter. */ thunk is this_adjusting but we are removing this parameter. */
static cgraph_node * static cgraph_node *
duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
bitmap args_to_skip)
{ {
cgraph_node *new_thunk, *thunk_of; cgraph_node *new_thunk, *thunk_of;
thunk_of = cgraph_function_or_thunk_node (thunk->callees->callee); thunk_of = cgraph_function_or_thunk_node (thunk->callees->callee);
if (thunk_of->thunk.thunk_p) if (thunk_of->thunk.thunk_p)
node = duplicate_thunk_for_node (thunk_of, node, args_to_skip); node = duplicate_thunk_for_node (thunk_of, node);
struct cgraph_edge *cs; struct cgraph_edge *cs;
for (cs = node->callers; cs; cs = cs->next_caller) for (cs = node->callers; cs; cs = cs->next_caller)
...@@ -320,17 +319,18 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, ...@@ -320,17 +319,18 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
return cs->caller; return cs->caller;
tree new_decl; tree new_decl;
if (!args_to_skip) if (!node->clone.args_to_skip)
new_decl = copy_node (thunk->decl); new_decl = copy_node (thunk->decl);
else else
{ {
/* We do not need to duplicate this_adjusting thunks if we have removed /* We do not need to duplicate this_adjusting thunks if we have removed
this. */ this. */
if (thunk->thunk.this_adjusting if (thunk->thunk.this_adjusting
&& bitmap_bit_p (args_to_skip, 0)) && bitmap_bit_p (node->clone.args_to_skip, 0))
return node; return node;
new_decl = build_function_decl_skip_args (thunk->decl, args_to_skip, new_decl = build_function_decl_skip_args (thunk->decl,
node->clone.args_to_skip,
false); false);
} }
gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl)); gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl));
...@@ -347,6 +347,8 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, ...@@ -347,6 +347,8 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
new_thunk->thunk = thunk->thunk; new_thunk->thunk = thunk->thunk;
new_thunk->unique_name = in_lto_p; new_thunk->unique_name = in_lto_p;
new_thunk->former_clone_of = thunk->decl; new_thunk->former_clone_of = thunk->decl;
new_thunk->clone.args_to_skip = node->clone.args_to_skip;
new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip;
struct cgraph_edge *e = cgraph_create_edge (new_thunk, node, NULL, 0, struct cgraph_edge *e = cgraph_create_edge (new_thunk, node, NULL, 0,
CGRAPH_FREQ_BASE); CGRAPH_FREQ_BASE);
...@@ -363,12 +365,11 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, ...@@ -363,12 +365,11 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node,
chain. */ chain. */
void void
redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n, redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n)
bitmap args_to_skip)
{ {
cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee); cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee);
if (orig_to->thunk.thunk_p) if (orig_to->thunk.thunk_p)
n = duplicate_thunk_for_node (orig_to, n, args_to_skip); n = duplicate_thunk_for_node (orig_to, n);
cgraph_redirect_edge_callee (e, n); cgraph_redirect_edge_callee (e, n);
} }
...@@ -421,9 +422,21 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, ...@@ -421,9 +422,21 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->rtl = n->rtl; new_node->rtl = n->rtl;
new_node->count = count; new_node->count = count;
new_node->frequency = n->frequency; new_node->frequency = n->frequency;
new_node->clone = n->clone;
new_node->clone.tree_map = NULL;
new_node->tp_first_run = n->tp_first_run; new_node->tp_first_run = n->tp_first_run;
new_node->clone.tree_map = NULL;
new_node->clone.args_to_skip = args_to_skip;
if (!args_to_skip)
new_node->clone.combined_args_to_skip = n->clone.combined_args_to_skip;
else if (n->clone.combined_args_to_skip)
{
new_node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC ();
bitmap_ior (new_node->clone.combined_args_to_skip,
n->clone.combined_args_to_skip, args_to_skip);
}
else
new_node->clone.combined_args_to_skip = args_to_skip;
if (n->count) if (n->count)
{ {
if (new_node->count > n->count) if (new_node->count > n->count)
...@@ -448,10 +461,9 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, ...@@ -448,10 +461,9 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
if (!e->callee if (!e->callee
|| DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE) || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE)
redirect_edge_duplicating_thunks (e, new_node, args_to_skip); redirect_edge_duplicating_thunks (e, new_node);
} }
for (e = n->callees;e; e=e->next_callee) for (e = n->callees;e; e=e->next_callee)
cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid, cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
count_scale, freq, update_original); count_scale, freq, update_original);
...@@ -558,7 +570,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, ...@@ -558,7 +570,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
ABI support for this. */ ABI support for this. */
set_new_clone_decl_and_node_flags (new_node); set_new_clone_decl_and_node_flags (new_node);
new_node->clone.tree_map = tree_map; new_node->clone.tree_map = tree_map;
new_node->clone.args_to_skip = args_to_skip;
/* Clones of global symbols or symbols with unique names are unique. */ /* Clones of global symbols or symbols with unique names are unique. */
if ((TREE_PUBLIC (old_decl) if ((TREE_PUBLIC (old_decl)
...@@ -569,32 +580,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, ...@@ -569,32 +580,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
new_node->unique_name = true; new_node->unique_name = true;
FOR_EACH_VEC_SAFE_ELT (tree_map, i, map) FOR_EACH_VEC_SAFE_ELT (tree_map, i, map)
new_node->maybe_add_reference (map->new_tree, IPA_REF_ADDR, NULL); new_node->maybe_add_reference (map->new_tree, IPA_REF_ADDR, NULL);
if (!args_to_skip)
new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip;
else if (old_node->clone.combined_args_to_skip)
{
int newi = 0, oldi = 0;
tree arg;
bitmap new_args_to_skip = BITMAP_GGC_ALLOC ();
struct cgraph_node *orig_node;
for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of)
;
for (arg = DECL_ARGUMENTS (orig_node->decl);
arg; arg = DECL_CHAIN (arg), oldi++)
{
if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi))
{
bitmap_set_bit (new_args_to_skip, oldi);
continue;
}
if (bitmap_bit_p (args_to_skip, newi))
bitmap_set_bit (new_args_to_skip, oldi);
newi++;
}
new_node->clone.combined_args_to_skip = new_args_to_skip;
}
else
new_node->clone.combined_args_to_skip = args_to_skip;
if (old_node->ipa_transforms_to_apply.exists ()) if (old_node->ipa_transforms_to_apply.exists ())
new_node->ipa_transforms_to_apply new_node->ipa_transforms_to_apply
= old_node->ipa_transforms_to_apply.copy (); = old_node->ipa_transforms_to_apply.copy ();
......
2014-06-27 Martin Jambor <mjambor@suse.cz>
PR ipa/61160
* g++.dg/ipa/pr61160-2.C: New test.
* g++.dg/ipa/pr61160-3.C: Likewise.
2014-06-27 Jakub Jelinek <jakub@redhat.com> 2014-06-27 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/57233 PR tree-optimization/57233
......
/* { dg-do run } */
/* { dg-options "-O3 --param ipa-cp-eval-threshold=1" } */
extern "C" void abort (void);
struct CBase {
virtual void BaseFunc () {}
};
struct MMixin {
virtual void * MixinFunc (int, void *) = 0;
};
struct CExample: CBase, public MMixin
{
int stuff, magic, more_stuff;
CExample ()
{
stuff = 0;
magic = 0xbeef;
more_stuff = 0;
}
void *MixinFunc (int arg, void *arg2)
{
if (arg != 1 || arg2)
return 0;
if (magic != 0xbeef)
abort();
return this;
}
};
void *test (MMixin & anExample)
{
return anExample.MixinFunc (1, 0);
}
int main ()
{
CExample c;
return (test (c) != &c);
}
/* { dg-do run } */
/* { dg-options "-O3" } */
struct A {
void *p;
A (void *q) : p (q) {}
A (const A &) : p () {}
};
struct CBase {
virtual void BaseFunc () {}
};
struct MMixin {
virtual A MixinFunc (int, A) = 0;
};
struct CExample: CBase, public MMixin
{
A MixinFunc (int arg, A arg2)
{
if (arg != 1 || arg2.p)
return 0;
return this;
}
};
void *test (MMixin & anExample)
{
return anExample.MixinFunc (1, (0)).p;
}
int main ()
{
CExample c;
return (test (c) != &c);
}
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