* [patch] Fix ICE during LTRANS on big Ada application
@ 2014-10-06 10:30 Eric Botcazou
2014-10-15 18:06 ` Eric Botcazou
0 siblings, 1 reply; 5+ messages in thread
From: Eric Botcazou @ 2014-10-06 10:30 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2517 bytes --]
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 <ebotcazou@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
[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 789 bytes --]
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c (revision 215843)
+++ ipa-inline-transform.c (working copy)
@@ -82,6 +82,13 @@ update_noncloned_frequencies (struct cgr
static bool
can_remove_node_now_p_1 (struct cgraph_node *node)
{
+ /* We cannot remove a master clone that has non-inline clones until after
+ these clones are materialized. */
+ if (!node->clone_of)
+ for (struct cgraph_node *n = node->clones; n; n = n->next_sibling_clone)
+ if (n->decl != node->decl)
+ return false;
+
/* FIXME: When address is taken of DECL_EXTERNAL function we still
can remove its offline copy, but we would need to keep unanalyzed node in
the callgraph so references can point to it. */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Fix ICE during LTRANS on big Ada application
2014-10-06 10:30 [patch] Fix ICE during LTRANS on big Ada application Eric Botcazou
@ 2014-10-15 18:06 ` Eric Botcazou
2014-10-15 20:06 ` Jan Hubicka
0 siblings, 1 reply; 5+ messages in thread
From: Eric Botcazou @ 2014-10-15 18:06 UTC (permalink / raw)
To: gcc-patches; +Cc: Jan Hubicka
Jan, any opinion on the following patch?
> 2014-10-06 Eric Botcazou <ebotcazou@adacore.com>
>
> * ipa-inline-transform.c (can_remove_node_now_p_1): Return false for a
> master clone that has non-inline clones.
https://gcc.gnu.org/ml/gcc-patches/2014-10/msg00436.html
Thanks in advance.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Fix ICE during LTRANS on big Ada application
2014-10-15 18:06 ` Eric Botcazou
@ 2014-10-15 20:06 ` Jan Hubicka
2014-10-16 15:15 ` Eric Botcazou
2014-10-17 20:02 ` Eric Botcazou
0 siblings, 2 replies; 5+ messages in thread
From: Jan Hubicka @ 2014-10-15 20:06 UTC (permalink / raw)
To: Eric Botcazou; +Cc: gcc-patches, Jan Hubicka
> Jan, any opinion on the following patch?
>
> > 2014-10-06 Eric Botcazou <ebotcazou@adacore.com>
> >
> > * ipa-inline-transform.c (can_remove_node_now_p_1): Return false for a
> > master clone that has non-inline clones.
>
> https://gcc.gnu.org/ml/gcc-patches/2014-10/msg00436.html
>
> Thanks in advance.
Yes, this looks OK. Inliner coul also take care to turn the master clone into unanalyzed
node as remove_unreachable_nodes would, but I do not think it is worth the effort.
Please put the loop later in the function so it does not slow things down unnecesarily
(there are often many inline clones)
Honza
>
> --
> Eric Botcazou
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Fix ICE during LTRANS on big Ada application
2014-10-15 20:06 ` Jan Hubicka
@ 2014-10-16 15:15 ` Eric Botcazou
2014-10-17 20:02 ` Eric Botcazou
1 sibling, 0 replies; 5+ messages in thread
From: Eric Botcazou @ 2014-10-16 15:15 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
> Yes, this looks OK. Inliner coul also take care to turn the master clone
> into unanalyzed node as remove_unreachable_nodes would, but I do not think
> it is worth the effort. Please put the loop later in the function so it
> does not slow things down unnecesarily (there are often many inline clones)
If you're concerned about efficiency, I can move it into clone_inlined_nodes
itself instead:
if (duplicate)
{
/* We may eliminate the need for out-of-line copy to be output.
In that case just go ahead and re-use it. This is not just an
memory optimization. Making offline copy of fuction disappear
from the program will improve future decisions on inlining. */
if (!e->callee->callers->next_caller
/* Recursive inlining never wants the master clone to
be overwritten. */
&& update_original
&& can_remove_node_now_p (e->callee, e))
i.e. I can set update_original to false just before the above test, that would
probably be sufficient to fix the bug.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch] Fix ICE during LTRANS on big Ada application
2014-10-15 20:06 ` Jan Hubicka
2014-10-16 15:15 ` Eric Botcazou
@ 2014-10-17 20:02 ` Eric Botcazou
1 sibling, 0 replies; 5+ messages in thread
From: Eric Botcazou @ 2014-10-17 20:02 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 641 bytes --]
> Yes, this looks OK. Inliner coul also take care to turn the master clone
> into unanalyzed node as remove_unreachable_nodes would, but I do not think
> it is worth the effort. Please put the loop later in the function so it
> does not slow things down unnecesarily (there are often many inline clones)
Here's what I have installed on the mainline after re-testing, this defers the
check as much as possible.
2014-10-17 Eric Botcazou <ebotcazou@adacore.com>
* ipa-inline-transform.c (master_clone_with_noninline_clones_p): New.
(clone_inlined_nodes): Do not overwrite the clone if above predicate
returns true.
--
Eric Botcazou
[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 1323 bytes --]
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c (revision 216252)
+++ ipa-inline-transform.c (working copy)
@@ -122,6 +122,20 @@ can_remove_node_now_p (struct cgraph_nod
return true;
}
+/* Return true if NODE is a master clone with non-inline clones. */
+
+static bool
+master_clone_with_noninline_clones_p (struct cgraph_node *node)
+{
+ if (node->clone_of)
+ return false;
+
+ for (struct cgraph_node *n = node->clones; n; n = n->next_sibling_clone)
+ if (n->decl != node->decl)
+ return true;
+
+ return false;
+}
/* E is expected to be an edge being inlined. Clone destination node of
the edge and redirect it to the new clone.
@@ -155,7 +169,10 @@ clone_inlined_nodes (struct cgraph_edge
/* Recursive inlining never wants the master clone to
be overwritten. */
&& update_original
- && can_remove_node_now_p (e->callee, e))
+ && can_remove_node_now_p (e->callee, e)
+ /* We cannot overwrite a master clone with non-inline clones
+ until after these clones are materialized. */
+ && !master_clone_with_noninline_clones_p (e->callee))
{
/* TODO: When callee is in a comdat group, we could remove all of it,
including all inline clones inlined into it. That would however
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-10-17 19:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-06 10:30 [patch] Fix ICE during LTRANS on big Ada application Eric Botcazou
2014-10-15 18:06 ` Eric Botcazou
2014-10-15 20:06 ` Jan Hubicka
2014-10-16 15:15 ` Eric Botcazou
2014-10-17 20:02 ` Eric Botcazou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).