re PR tree-optimization/57539 (ice in ipa_edge_duplication_hook)

2013-06-24  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/57539
	* cgraphclones.c (cgraph_clone_node): Add parameter new_inlined_to, set
	global.inlined_to of the new node to it.  All callers changed.
	* ipa-inline-transform.c (clone_inlined_nodes): New variable
	inlining_into, pass it to cgraph_clone_node.
	* ipa-prop.c (ipa_propagate_indirect_call_infos): Do not call
	ipa_free_edge_args_substructures.
	(ipa_edge_duplication_hook): Only add edges from inlined nodes to
	rdesc linked list.  Do not assert rdesc edges have inlined caller.
	Assert we have found an rdesc in the rdesc list.

From-SVN: r200368
This commit is contained in:
Martin Jambor 2013-06-24 14:40:17 +02:00 committed by Martin Jambor
parent 7c5848b899
commit 44a6024459
7 changed files with 45 additions and 24 deletions

View File

@ -1,3 +1,16 @@
2013-06-24 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/57539
* cgraphclones.c (cgraph_clone_node): Add parameter new_inlined_to, set
global.inlined_to of the new node to it. All callers changed.
* ipa-inline-transform.c (clone_inlined_nodes): New variable
inlining_into, pass it to cgraph_clone_node.
* ipa-prop.c (ipa_propagate_indirect_call_infos): Do not call
ipa_free_edge_args_substructures.
(ipa_edge_duplication_hook): Only add edges from inlined nodes to
rdesc linked list. Do not assert rdesc edges have inlined caller.
Assert we have found an rdesc in the rdesc list.
2013-06-24 Richard Biener <rguenther@suse.de> 2013-06-24 Richard Biener <rguenther@suse.de>
* pointer-set.h (struct pointer_set_t): Move here from * pointer-set.h (struct pointer_set_t): Move here from

View File

@ -715,7 +715,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
unsigned, gcov_type, int, bool); unsigned, gcov_type, int, bool);
struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type,
int, bool, vec<cgraph_edge_p>, int, bool, vec<cgraph_edge_p>,
bool); bool, struct cgraph_node *);
tree clone_function_name (tree decl, const char *); tree clone_function_name (tree decl, const char *);
struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node, struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node,
vec<cgraph_edge_p>, vec<cgraph_edge_p>,

View File

@ -167,13 +167,19 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
function's profile to reflect the fact that part of execution is handled function's profile to reflect the fact that part of execution is handled
by node. by node.
When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about
the new clone. Otherwise the caller is responsible for doing so later. */ the new clone. Otherwise the caller is responsible for doing so later.
If the new node is being inlined into another one, NEW_INLINED_TO should be
the outline function the new one is (even indirectly) inlined to. All hooks
will see this in node's global.inlined_to, when invoked. Can be NULL if the
node is not inlined. */
struct cgraph_node * struct cgraph_node *
cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
bool update_original, bool update_original,
vec<cgraph_edge_p> redirect_callers, vec<cgraph_edge_p> redirect_callers,
bool call_duplication_hook) bool call_duplication_hook,
struct cgraph_node *new_inlined_to)
{ {
struct cgraph_node *new_node = cgraph_create_empty_node (); struct cgraph_node *new_node = cgraph_create_empty_node ();
struct cgraph_edge *e; struct cgraph_edge *e;
@ -195,6 +201,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->symbol.externally_visible = false; new_node->symbol.externally_visible = false;
new_node->local.local = true; new_node->local.local = true;
new_node->global = n->global; new_node->global = n->global;
new_node->global.inlined_to = new_inlined_to;
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;
@ -307,7 +314,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
new_node = cgraph_clone_node (old_node, new_decl, old_node->count, new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
CGRAPH_FREQ_BASE, false, CGRAPH_FREQ_BASE, false,
redirect_callers, false); redirect_callers, false, NULL);
/* Update the properties. /* Update the properties.
Make clone visible only within this translation unit. Make sure Make clone visible only within this translation unit. Make sure
that is not weak also. that is not weak also.

View File

@ -132,6 +132,13 @@ void
clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
bool update_original, int *overall_size) bool update_original, int *overall_size)
{ {
struct cgraph_node *inlining_into;
if (e->caller->global.inlined_to)
inlining_into = e->caller->global.inlined_to;
else
inlining_into = e->caller;
if (duplicate) if (duplicate)
{ {
/* We may eliminate the need for out-of-line copy to be output. /* We may eliminate the need for out-of-line copy to be output.
@ -167,18 +174,15 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
{ {
struct cgraph_node *n; struct cgraph_node *n;
n = cgraph_clone_node (e->callee, e->callee->symbol.decl, n = cgraph_clone_node (e->callee, e->callee->symbol.decl,
e->count, e->frequency, e->count, e->frequency, update_original,
update_original, vNULL, true); vNULL, true, inlining_into);
cgraph_redirect_edge_callee (e, n); cgraph_redirect_edge_callee (e, n);
} }
} }
else else
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee); symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
if (e->caller->global.inlined_to) e->callee->global.inlined_to = inlining_into;
e->callee->global.inlined_to = e->caller->global.inlined_to;
else
e->callee->global.inlined_to = e->caller;
/* Recursively clone all bodies. */ /* Recursively clone all bodies. */
for (e = e->callee->callees; e; e = e->next_callee) for (e = e->callee->callees; e; e = e->next_callee)

View File

@ -1314,7 +1314,7 @@ recursive_inlining (struct cgraph_edge *edge,
/* We need original clone to copy around. */ /* We need original clone to copy around. */
master_clone = cgraph_clone_node (node, node->symbol.decl, master_clone = cgraph_clone_node (node, node->symbol.decl,
node->count, CGRAPH_FREQ_BASE, node->count, CGRAPH_FREQ_BASE,
false, vNULL, true); false, vNULL, true, NULL);
for (e = master_clone->callees; e; e = e->next_callee) for (e = master_clone->callees; e; e = e->next_callee)
if (!e->inline_failed) if (!e->inline_failed)
clone_inlined_nodes (e, true, false, NULL); clone_inlined_nodes (e, true, false, NULL);

View File

@ -2684,9 +2684,6 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
propagate_controlled_uses (cs); propagate_controlled_uses (cs);
changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges); changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
/* We do not keep jump functions of inlined edges up to date. Better to free
them so we do not access them accidentally. */
ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
return changed; return changed;
} }
@ -2816,9 +2813,12 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
dst_rdesc dst_rdesc
= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool); = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
dst_rdesc->cs = dst; dst_rdesc->cs = dst;
dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
src_rdesc->next_duplicate = dst_rdesc;
dst_rdesc->refcount = src_rdesc->refcount; dst_rdesc->refcount = src_rdesc->refcount;
if (dst->caller->global.inlined_to)
{
dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
src_rdesc->next_duplicate = dst_rdesc;
}
dst_jf->value.constant.rdesc = dst_rdesc; dst_jf->value.constant.rdesc = dst_rdesc;
} }
else else
@ -2833,13 +2833,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
for (dst_rdesc = src_rdesc->next_duplicate; for (dst_rdesc = src_rdesc->next_duplicate;
dst_rdesc; dst_rdesc;
dst_rdesc = dst_rdesc->next_duplicate) dst_rdesc = dst_rdesc->next_duplicate)
{ if (dst_rdesc->cs->caller->global.inlined_to
gcc_assert (dst_rdesc->cs->caller->global.inlined_to); == dst->caller->global.inlined_to)
if (dst_rdesc->cs->caller->global.inlined_to break;
== dst->caller->global.inlined_to) gcc_assert (dst_rdesc);
break;
}
dst_jf->value.constant.rdesc = dst_rdesc; dst_jf->value.constant.rdesc = dst_rdesc;
} }
} }

View File

@ -955,7 +955,7 @@ input_node (struct lto_file_decl_data *file_data,
{ {
node = cgraph_clone_node (cgraph (nodes[clone_ref]), fn_decl, node = cgraph_clone_node (cgraph (nodes[clone_ref]), fn_decl,
0, CGRAPH_FREQ_BASE, false, 0, CGRAPH_FREQ_BASE, false,
vNULL, false); vNULL, false, NULL);
} }
else else
{ {