Eric Botcazou
2014-10-06 10:29:41 UTC
Hi,
we have run into an ICE in LTO mode on a big Ada application with our 4.9-
based compiler, whose error message is:
xxxxxxxxxxxxxx.constprop.15627/1865799 (xxxxxxxxxxxxxxxxxxxxxxx.constprop)
@0x7ffff6835bd0
Type: function definition analyzed
Visibility: used_from_other_partition public visibility_specified
visibility:hidden artificial
References: __gnat_personality_v0/19663 (addr)__gnat_others_value/19664
(addr)
Referring:
Read from file: xxxxxx.ltrans31.o
Availability: local
First run: 0
Function flags: local
Called by:
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.constprop.15352/1865524
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.constprop.15343/1865515
Calls:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.constprop.15628/1865800
(1.00 per call)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.part.62.lto_priv.21947/1557884
(can throw external) __gnat_end_handler/19660 (can throw external)
__builtin_eh_pointer/20253 __gnat_begin_handler/19662 __gnat_end_handler/19660
(can throw external)
lto1: fatal error: xxxxxx.ltrans31.o: section
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.constprop.15627 is missing
So LTRANS complains that a .constprop function is missing on disk, which
doesn't really make sense since it's a clone so it is not streamed.
The problem is that a clone function has it clone_of field zeroed during clone
materialization by cgraph_node::remove:
/* We are removing node with clones. This makes clones inconsistent,
but assume they will be removed subsequently and just keep clone
tree intact. This can happen in unreachable function removal since
we remove unreachable functions in random order, not by bottom-up
walk of clone trees. */
for (n = clones; n; n = next)
{
next = n->next_sibling_clone;
n->next_sibling_clone = NULL;
n->prev_sibling_clone = NULL;
n->clone_of = NULL;
}
because it's the clone of an inlined_to node that gets discarded because it's
inlined into another clone(!). So the first clone function cannot (and is
never) materialized and the compiler ICEs later when its body is requested.
It seems to be that the root cause is clone_inlined_nodes overriding a master
clone that has non-inline clones, hence the attached patch.
Tested on x86_64-suse-linux, OK for the mainline?
2014-10-06 Eric Botcazou <***@adacore.com>
* ipa-inline-transform.c (can_remove_node_now_p_1): Return false for a
master clone that has non-inline clones.
we have run into an ICE in LTO mode on a big Ada application with our 4.9-
based compiler, whose error message is:
xxxxxxxxxxxxxx.constprop.15627/1865799 (xxxxxxxxxxxxxxxxxxxxxxx.constprop)
@0x7ffff6835bd0
Type: function definition analyzed
Visibility: used_from_other_partition public visibility_specified
visibility:hidden artificial
References: __gnat_personality_v0/19663 (addr)__gnat_others_value/19664
(addr)
Referring:
Read from file: xxxxxx.ltrans31.o
Availability: local
First run: 0
Function flags: local
Called by:
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.constprop.15352/1865524
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.constprop.15343/1865515
Calls:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.constprop.15628/1865800
(1.00 per call)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.part.62.lto_priv.21947/1557884
(can throw external) __gnat_end_handler/19660 (can throw external)
__builtin_eh_pointer/20253 __gnat_begin_handler/19662 __gnat_end_handler/19660
(can throw external)
lto1: fatal error: xxxxxx.ltrans31.o: section
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.constprop.15627 is missing
So LTRANS complains that a .constprop function is missing on disk, which
doesn't really make sense since it's a clone so it is not streamed.
The problem is that a clone function has it clone_of field zeroed during clone
materialization by cgraph_node::remove:
/* We are removing node with clones. This makes clones inconsistent,
but assume they will be removed subsequently and just keep clone
tree intact. This can happen in unreachable function removal since
we remove unreachable functions in random order, not by bottom-up
walk of clone trees. */
for (n = clones; n; n = next)
{
next = n->next_sibling_clone;
n->next_sibling_clone = NULL;
n->prev_sibling_clone = NULL;
n->clone_of = NULL;
}
because it's the clone of an inlined_to node that gets discarded because it's
inlined into another clone(!). So the first clone function cannot (and is
never) materialized and the compiler ICEs later when its body is requested.
It seems to be that the root cause is clone_inlined_nodes overriding a master
clone that has non-inline clones, hence the attached patch.
Tested on x86_64-suse-linux, OK for the mainline?
2014-10-06 Eric Botcazou <***@adacore.com>
* ipa-inline-transform.c (can_remove_node_now_p_1): Return false for a
master clone that has non-inline clones.
--
Eric Botcazou
Eric Botcazou