Commit a0a7b611 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/56265 (ICE in ipa_make_edge_direct_to_target)


	PR tree-optimization/56265
	* ipa-prop.c (ipa_make_edge_direct_to_target): Fixup callgraph when target is
	referenced for firs ttime.
	* testsuite/g++.dg/ipa/devirt-11.C: New testcase.

From-SVN: r196177
parent c0e50f72
2013-02-20 Jan Hubicka <jh@suse.cz>
PR tree-optimization/56265
* ipa-prop.c (ipa_make_edge_direct_to_target): Fixup callgraph when target is
referenced for firs ttime.
2013-02-20 Richard Biener <rguenther@suse.de>
* tree-call-cdce.c (tree_call_cdce): Do not remove unused locals.
......
......@@ -2100,10 +2100,65 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
if (TREE_CODE (target) == ADDR_EXPR)
target = TREE_OPERAND (target, 0);
if (TREE_CODE (target) != FUNCTION_DECL)
return NULL;
{
target = canonicalize_constructor_val (target, NULL);
if (!target || TREE_CODE (target) != FUNCTION_DECL)
{
if (dump_file)
fprintf (dump_file, "ipa-prop: Discovered direct call to non-function"
" in (%s/%i).\n",
cgraph_node_name (ie->caller), ie->caller->uid);
return NULL;
}
}
callee = cgraph_get_node (target);
if (!callee)
return NULL;
/* Because may-edges are not explicitely represented and vtable may be external,
we may create the first reference to the object in the unit. */
if (!callee || callee->global.inlined_to)
{
struct cgraph_node *first_clone = callee;
/* We are better to ensure we can refer to it.
In the case of static functions we are out of luck, since we already
removed its body. In the case of public functions we may or may
not introduce the reference. */
if (!canonicalize_constructor_val (target, NULL)
|| !TREE_PUBLIC (target))
{
if (dump_file)
fprintf (dump_file, "ipa-prop: Discovered call to a known target "
"(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
xstrdup (cgraph_node_name (ie->caller)), ie->caller->uid,
xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid);
return NULL;
}
/* Create symbol table node. Even if inline clone exists, we can not take
it as a target of non-inlined call. */
callee = cgraph_create_node (target);
/* OK, we previously inlined the function, then removed the offline copy and
now we want it back for external call. This can happen when devirtualizing
while inlining function called once that happens after extern inlined and
virtuals are already removed. In this case introduce the external node
and make it available for call. */
if (first_clone)
{
first_clone->clone_of = callee;
callee->clones = first_clone;
symtab_prevail_in_asm_name_hash ((symtab_node)callee);
symtab_insert_node_to_hashtable ((symtab_node)callee);
if (dump_file)
fprintf (dump_file, "ipa-prop: Introduced new external node "
"(%s/%i) and turned into root of the clone tree.\n",
xstrdup (cgraph_node_name (callee)), callee->uid);
}
else if (dump_file)
fprintf (dump_file, "ipa-prop: Introduced new external node "
"(%s/%i).\n",
xstrdup (cgraph_node_name (callee)), callee->uid);
}
ipa_check_create_node_params ();
/* We can not make edges to inline clones. It is bug that someone removed
......
2013-02-20 Jan Hubicka <jh@suse.cz>
PR tree-optimization/56265
* testsuite/g++.dg/ipa/devirt-11.C: New testcase.
2013-02-20 Richard Biener <rguenther@suse.de>
* gcc.dg/tree-ssa/forwprop-8.c: Adjust.
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-ipa-inline" } */
int baz ();
struct A
{
virtual int fn2 () = 0;
virtual int *fn3 ();
double *fn4 ();
int fn5 (int);
template <class T>
void fn1 (A &, T) { fn3 (); fn4 (); fn2 (); }
};
struct B : A
{
int fn2 () { return 6; }
void fn3 (int, double);
B (bool = true);
B (int, int);
};
template <typename T>
void
foo (B &x, A &y, A &z)
{
y.fn2 ();
z.fn2 ();
int i = baz ();
int j = (y.fn3 ())[i];
x.fn3 (j, (y.fn4 ())[i] + (z.fn4 ())[z.fn5 (j)]);
}
inline B
operator+ (A &y, A &z)
{
B x;
foo<int> (x, y, z);
return x;
}
void
bar ()
{
B a, b, c (4, 0), d;
a.fn1 (b, .6);
baz ();
c + d;
}
/* While inlining function called once we should devirtualize a new call to fn2
and two to fn3. While doing so the new symbol for fn2 needs to be
introduced. */
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */
/* { dg-final { scan-ipa-dump-times "and turned into root of the clone tree" 1 "inline" } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */
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