diff mbox

Fix LTO regression in Ada

Message ID 201205092238.29781.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou May 9, 2012, 8:38 p.m. UTC
Hi,

this is a regression present on mainline and 4.7 branch.  On the attached 
testcase, the compiler aborts in LTO mode with:

eric@atlantis:~/build/gcc/native32> gcc/xgcc -Bgcc -S lto11.adb -O -flto
+===========================GNAT BUG DETECTED==============================+
| 4.8.0 20120506 (experimental) [trunk revision 187216] (i586-suse-linux)
| tree code 'call_expr' is not supported in LTO streams           

The problem is that the Ada compiler started to use DECL_ORIGINAL_TYPE in 4.7.x 
and the type in this field can have arbitrary expressions as TYPE_SIZE, for 
example expressions with CALL_EXPRs.  Now the type is both not gimplified and 
streamed in LTO mode, so the CALL_EXPRs are sent to the streamer as-is.

The immediate solution would be not to stream DECL_ORIGINAL_TYPE (and clear it 
in free_lang_data_in_decl), but this yields a regression in C++ with -flto -g 
(ICE in splice_child_die).  Therefore, the patch implements the alternate 
solution of gimplifying DECL_ORIGINAL_TYPE.

Bootstrapped/regtested on x86_64-suse-linux, OK for mainline and 4.7 branch?


2012-05-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gimplify.c (gimplify_decl_expr): For a TYPE_DECL, gimplify the
	DECL_ORIGINAL_TYPE if it is present.


2012-05-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/lto11.ad[sb]: New test.

Comments

Richard Biener May 10, 2012, 7:53 a.m. UTC | #1
On Wed, May 9, 2012 at 10:38 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> this is a regression present on mainline and 4.7 branch.  On the attached
> testcase, the compiler aborts in LTO mode with:
>
> eric@atlantis:~/build/gcc/native32> gcc/xgcc -Bgcc -S lto11.adb -O -flto
> +===========================GNAT BUG DETECTED==============================+
> | 4.8.0 20120506 (experimental) [trunk revision 187216] (i586-suse-linux)
> | tree code 'call_expr' is not supported in LTO streams
>
> The problem is that the Ada compiler started to use DECL_ORIGINAL_TYPE in 4.7.x
> and the type in this field can have arbitrary expressions as TYPE_SIZE, for
> example expressions with CALL_EXPRs.  Now the type is both not gimplified and
> streamed in LTO mode, so the CALL_EXPRs are sent to the streamer as-is.
>
> The immediate solution would be not to stream DECL_ORIGINAL_TYPE (and clear it
> in free_lang_data_in_decl), but this yields a regression in C++ with -flto -g
> (ICE in splice_child_die).  Therefore, the patch implements the alternate
> solution of gimplifying DECL_ORIGINAL_TYPE.
>
> Bootstrapped/regtested on x86_64-suse-linux, OK for mainline and 4.7 branch?

Hmm, but we will not possibly refer to the sizes therein, so emitting
stmts for them
looks pointless ... (and in fact the debug information would be odd,
too ... what
does dwarf2out.c do with these CALL_EXPRs when generating debug information
without LTO?)

Anyway, the idea is reasonable, but I'm not sure ending up with calls in those
sizes makes sense (don't we make sure to "inline" them all at some point?)

Thanks,
Richard.

>
> 2012-05-09  Eric Botcazou  <ebotcazou@adacore.com>
>
>        * gimplify.c (gimplify_decl_expr): For a TYPE_DECL, gimplify the
>        DECL_ORIGINAL_TYPE if it is present.
>
>
> 2012-05-09  Eric Botcazou  <ebotcazou@adacore.com>
>
>        * gnat.dg/lto11.ad[sb]: New test.
>
>
> --
> Eric Botcazou
Eric Botcazou May 10, 2012, 10:12 a.m. UTC | #2
> Hmm, but we will not possibly refer to the sizes therein, so emitting
> stmts for them
> looks pointless ... (and in fact the debug information would be odd,
> too ... what
> does dwarf2out.c do with these CALL_EXPRs when generating debug information
> without LTO?)

All variable-sized types currently get size -1, but this would change with:
  http://gcc.gnu.org/ml/gcc-patches/2012-04/msg00422.html

> Anyway, the idea is reasonable, but I'm not sure ending up with calls in
> those sizes makes sense (don't we make sure to "inline" them all at some
> point?)

These types are like any other types in Ada.  Either DECL_ORIGINAL_TYPE is 
purely for debug info and then we shouldn't stream it for LTO or it isn't and 
it needs to be gimplified.  My personal inclination would be for the former, 
but this is apparently problematic for C++.  I can add a ??? comment though.
Richard Biener May 10, 2012, 10:29 a.m. UTC | #3
On Thu, May 10, 2012 at 12:12 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> Hmm, but we will not possibly refer to the sizes therein, so emitting
>> stmts for them
>> looks pointless ... (and in fact the debug information would be odd,
>> too ... what
>> does dwarf2out.c do with these CALL_EXPRs when generating debug information
>> without LTO?)
>
> All variable-sized types currently get size -1, but this would change with:
>  http://gcc.gnu.org/ml/gcc-patches/2012-04/msg00422.html
>
>> Anyway, the idea is reasonable, but I'm not sure ending up with calls in
>> those sizes makes sense (don't we make sure to "inline" them all at some
>> point?)
>
> These types are like any other types in Ada.  Either DECL_ORIGINAL_TYPE is
> purely for debug info and then we shouldn't stream it for LTO or it isn't and
> it needs to be gimplified.  My personal inclination would be for the former,
> but this is apparently problematic for C++.  I can add a ??? comment though.

Well, we need to stream it for LTO because at the moment LTO is still
responsible
for emitting debug information ... (that would change with the "early
debug info" plan).

Ok with a ??? comment.

Thanks,
Richard.

> --
> Eric Botcazou
diff mbox

Patch

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c4792e6..f69e773 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1448,6 +1448,11 @@  gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
     gimplify_type_sizes (TREE_TYPE (decl), seq_p);
 
+  if (TREE_CODE (decl) == TYPE_DECL
+      && DECL_ORIGINAL_TYPE (decl)
+      && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
+    gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
       tree init = DECL_INITIAL (decl);