Bug 48492 - [4.7 Regression] LTO bootstrap failure in copy_constant
Summary: [4.7 Regression] LTO bootstrap failure in copy_constant
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.7.0
Assignee: Eric Botcazou
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-07 13:00 UTC by Jakub Jelinek
Modified: 2011-06-27 14:37 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-04-10 15:58:58


Attachments
broken patch (1.11 KB, patch)
2011-04-07 13:00 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2011-04-07 13:00:38 UTC
Created attachment 23910 [details]
broken patch

../configure --enable-languages=all,obj-c++,ada,lto,go --enable-checking=yes,rtl --with-build-config=bootstrap-lto
make -j64
fails with:
../../gcc/ada/ali.ads:39:1: internal compiler error: in copy_constant, at varasm.c:3030
while linking gnatbind with -flto.
The problem is related to streaming out and in DECL_IN_CONSTANT_POOL var decls,
I guess in the original compilation it is streamed out normally, but when
it is streamed in, tree_output_constant_def isn't called on the DECL_INITIAL,
so it isn't registered with varpool and thus when streaming it out again,
varpool_get_node returns NULL and we stream the decl with DECL_IN_CONSTANT_POOL
set, but DECL_INITIAL being error_mark_node.  When it is streamed in again,
and expand_debug_expr calls mark_decl_rtl on it, it ICEs, because error_mark_node isn't a constant.

I believe we need to stream DECL_IN_CONSTANT_POOL vars specially, basically stream just the constants from its DECL_INITIAL and have the stream reader
call tree_output_constant_def for it.  Tried to do this in attached patch, but
probably it needs to be done slightly elsewhere, perhaps after after caching it or whatever.  Not too familiar with the streamer...
Comment 1 Eric Botcazou 2011-04-10 15:58:58 UTC
Same error on sem_prag.adb linking gnat1.
Comment 2 Eric Botcazou 2011-04-11 10:52:00 UTC
Looking into it.
Comment 3 Eric Botcazou 2011-04-15 22:52:08 UTC
The scenario is as follows:
  1. during LTO stage, copy-prop eliminates a DECL_IN_CONSTANT_POOL variable from the GIMPLE IR, except for a reference in a GIMPLE_DEBUG statement (ADDR_EXPR of the variable is the debug value),
  2. the variable is streamed out in the object file, as well as its associated varpool entry,
  3. during WPA stage, both are streamed in, then reachability analysis is run and computes that the variable is unreachable so removes the varpool entry.
As a consequence, when the variable is streamed out again, its initializer gets replaced with ERROR_MARK.
  4. during LTRANS stage, the variable is again streamed in, with ERROR_MARK as initializer and this blows up when the GIMPLE_DEBUG statement is processed.

So ISTM that the problem is in the reachability analysis during the WPA stage.
Comment 4 Jakub Jelinek 2011-04-16 07:59:24 UTC
Reachability analysis should never take into account DEBUG stmts, the bug is IMNSHO in that we shouldn't ever stream DECL_IN_CONSTANT_POOL with error_mark_node as DECL_INITIAL.  Even if we don't hit this problem, if DECL_IN_CONSTANT_POOL aren't actually handled specially by LTO streamer, the constants won't be merged across different CUs, whcih is undesirable.
Comment 5 Eric Botcazou 2011-04-16 08:50:35 UTC
> Reachability analysis should never take into account DEBUG stmts, the bug is
> IMNSHO in that we shouldn't ever stream DECL_IN_CONSTANT_POOL with
> error_mark_node as DECL_INITIAL.

The first bug is that we remove the varpool entry for the DECL_IN_CONSTANT_POOL.

> Even if we don't hit this problem, if DECL_IN_CONSTANT_POOL aren't actually
> handled specially by LTO streamer, the constants won't be merged across
> different CUs, whcih is undesirable.

That's somewhat orthogonal though.  The constants are merged across CUs, see gcc.dg/lto/const-uniq_[01].c, but the LTO handling of DECL_IN_CONSTANT_POOL is indeed suboptimal, as explained in lto_output_varpool_node:

  /* Constant pool initializers can be de-unified into individual ltrans units.
     FIXME: Alternatively at -Os we may want to avoid generating for them the
     local labels and share them across LTRANS partitions.  */
Comment 6 Eric Botcazou 2011-04-18 10:13:55 UTC
Author: ebotcazou
Date: Mon Apr 18 10:13:49 2011
New Revision: 172641

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172641
Log:
	PR lto/48492
	* cfgexpand.c (expand_debug_expr) <VAR_DECL>: Return NULL for a
	DECL_IN_CONSTANT_POOL without RTL.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cfgexpand.c
Comment 7 Eric Botcazou 2011-04-20 11:18:57 UTC
Author: ebotcazou
Date: Wed Apr 20 11:18:50 2011
New Revision: 172767

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172767
Log:
	Backport from mainline
	2011-04-19  Eric Botcazou  <ebotcazou@adacore.com>

	PR lto/48148
	* gimple.c (gimple_types_compatible_p_1) <ENUMERAL_TYPE>: Do not merge
	the types if they have different enumeration identifiers.

	2011-04-18  Eric Botcazou  <ebotcazou@adacore.com>

	PR lto/48492
	* cfgexpand.c (expand_debug_expr) <VAR_DECL>: Return NULL for a
	DECL_IN_CONSTANT_POOL without RTL.

Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/cfgexpand.c
    branches/gcc-4_6-branch/gcc/gimple.c
Comment 8 Jakub Jelinek 2011-04-21 12:57:16 UTC
Fixed now.
Comment 9 Eric Botcazou 2011-04-21 13:18:57 UTC
I still need http://gcc.gnu.org/ml/gcc-patches/2011-04/msg01461.html to do a LTO bootstrap with Ada enabled.
Comment 10 Eric Botcazou 2011-06-27 14:34:08 UTC
Author: ebotcazou
Date: Mon Jun 27 14:34:05 2011
New Revision: 175533

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175533
Log:
	PR lto/48492
	* dwarf2out.c (dwarf2out_finish): Do not attach a DIE on the limbo list
	to a NULL parent.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
Comment 11 Eric Botcazou 2011-06-27 14:37:00 UTC
Or rather worked around.