[PATCH] Fix LTO early-debug ICE wrt abstract origin node streaming

Richard Biener rguenther@suse.de
Fri Aug 28 09:40:00 GMT 2015


On Fri, 28 Aug 2015, Richard Biener wrote:

> 
> The following fixes
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000af8edd in lto_get_decl_name_mapping (decl_data=0x0, 
>     name=0x7ffff68dcbd0 "bar")
>     at /space/rguenther/src/svn/trunk/gcc/lto-section-in.c:349
> 349       htab_t renaming_hash_table = decl_data->renaming_hash_table;
> (gdb) bt
> #0  0x0000000000af8edd in lto_get_decl_name_mapping (decl_data=0x0, 
>     name=0x7ffff68dcbd0 "bar")
>     at /space/rguenther/src/svn/trunk/gcc/lto-section-in.c:349
> #1  0x0000000000af41b9 in copy_function_or_variable (node=0x7ffff6abfb80)
>     at /space/rguenther/src/svn/trunk/gcc/lto-streamer-out.c:2233
> #2  0x0000000000af4701 in lto_output ()
>     at /space/rguenther/src/svn/trunk/gcc/lto-streamer-out.c:2328
> #3  0x0000000000b6d909 in write_lto ()
>     at /space/rguenther/src/svn/trunk/gcc/passes.c:2411
> #4  0x0000000000b6e062 in ipa_write_optimization_summaries 
> (encoder=0x2100ab0)
>     at /space/rguenther/src/svn/trunk/gcc/passes.c:2615
> 
> I see quite often because I now stream DECL_ABSTRACT_ORIGIN from
> the early compile.  Often the abstract origins have their bodies
> removed as unreachable but LTRANS boundary compute happily
> re-creates the cgraph nodes and tries to stream the bodies.  Which
> obviously fails.
> 
> Below are two possible fixes (and in fact I believe that with
> early LTO debug we do _not_ need to put abstract origins into the
> LTRANS boundary at all - the abstract instance is available from
> the early debug via the abstract origin decl).
> 
> Any preference?  I'm LTO bootstrapping the first one because it
> looks bogus to use get_create here (did we add this for dwarf2out
> ICEs with LTO?)

Hum, indeed the first patch fails LTO bootstrap with

/space/rguenther/src/svn/trunk/gcc/genhooks.c:58:1: internal compiler 
error: in gen_inlined_subroutine_die, at dwarf2out.c:19946
 }
 ^
0x85464e gen_inlined_subroutine_die
        /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:19946
0x854bc5 gen_block_die
        /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:21002

  /* Make sure any inlined functions are known to be inlineable.  */
  gcc_checking_assert (DECL_ABSTRACT_P (decl)
                       || cgraph_function_possibly_inlined_p (decl));

eventually solved by the DECL_ABSTRACT_P setting below.  Trying...
(though I don't think we set used_as_abstract_origin when just
inlining).  With that it fails in check_die.

For early LTO debug I'm simply trying to kill
the code streaming abstract origins into the LTRANS boundary.
We're going to hit the above assert anyway though.  Hmm, actually
we dont.  For

int a;
int __attribute__((noinline)) baz (int y) { return y; }
static int foo (int x) { return baz (x + 1); }
int main () { return foo (a); }

we get with -O -flto -g and early LTO debug

(gdb) start
Temporary breakpoint 1, main () at t.c:4
4       int main () { return foo (a); }
(gdb) si
0x00000000004004ee in foo (x=<optimized out>, x=<optimized out>) at t.c:4
4       int main () { return foo (a); }
(gdb) si
baz (y=y@entry=1) at t.c:2
2       int __attribute__((noinline)) baz (int y) { return y; }
(gdb) fin
Run till exit from #0  baz (y=y@entry=1) at t.c:2
main (argc=<optimized out>, argv=<optimized out>) at t.c:4
4       int main (int argc, char **argv) { return foo (a); }
Value returned is $3 = 1

odd that gdb prints 'x' twice here.  We have

 <2><200>: Abbrev Number: 4 (DW_TAG_inlined_subroutine)
    <201>   DW_AT_abstract_origin: <0x235>
    <205>   DW_AT_low_pc      : 0x4004e9
    <20d>   DW_AT_high_pc     : 0xa
    <215>   DW_AT_call_file   : 1
    <216>   DW_AT_call_line   : 4
 <3><217>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <218>   DW_AT_abstract_origin: <0x23f>
    <21c>   DW_AT_location    : 0x0 (location list)

 <1><235>: Abbrev Number: 8 (DW_TAG_subprogram)
    <236>   DW_AT_abstract_origin: <0x18f>
    <23a>   DW_AT_inline      : 1       (inlined)
    <23b>   DW_AT_sibling     : <0x245>
 <2><23f>: Abbrev Number: 9 (DW_TAG_formal_parameter)
    <240>   DW_AT_abstract_origin: <0x19e>

 <1><18f>: Abbrev Number: 5 (DW_TAG_subprogram)
    <190>   DW_AT_name        : foo
    <194>   DW_AT_decl_file   : 1
    <195>   DW_AT_decl_line   : 3
    <196>   DW_AT_prototyped  : 1
    <196>   DW_AT_type        : <0x17d>
    <19a>   DW_AT_sibling     : <0x1a8>
 <2><19e>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <19f>   DW_AT_name        : x
    <1a1>   DW_AT_decl_file   : 1
    <1a2>   DW_AT_decl_line   : 3
    <1a3>   DW_AT_type        : <0x17d>

I would have expected either one or three 'x' ... (if the die
children of each abstract origin add up).  Maybe gdb just
doesn't expect the two level indirection (yeah - I can remove
that for the extra cost of refering to the early CU directly).

Well.  At least it doesn't seem to ICE on the assert even though
'foo' is gone.  Ah, cgraph_function_possibly_inlined_p simply
returns true...  for whatever reason it doesn't do so with trunk.

Anyway, not pursuing anything on trunk yet but only with
early-LTO-debug (removing the abstract origin boundary streaming).

Thanks,
Richard.

> Maybe we want the cgraph_node::remove hunk as well and assert
> in cgraph_node::create that we are not creating cgraph nodes
> for DECL_ABSTRACT_P decls...
> 
> Thanks,
> Richard.
> 
> 2015-08-28  Richard Biener  <rguenther@suse.de>
> 
> 	* lto-cgraph.c (compute_ltrans_boundary): Only put abstract
> 	origin nodes into the ltrans boundary if their body is still
> 	available.
> 
> Index: trunk/gcc/lto-cgraph.c
> ===================================================================
> --- trunk.orig/gcc/lto-cgraph.c	2015-08-13 13:14:09.116378573 +0200
> +++ trunk/gcc/lto-cgraph.c	2015-08-28 10:24:05.130397851 +0200
> @@ -899,9 +899,12 @@ compute_ltrans_boundary (lto_symtab_enco
>        if (DECL_ABSTRACT_ORIGIN (node->decl))
>  	{
>  	  struct cgraph_node *origin_node
> -	  = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (node->decl));
> -	  origin_node->used_as_abstract_origin = true;
> -	  add_node_to (encoder, origin_node, true);
> +	    = cgraph_node::get (DECL_ABSTRACT_ORIGIN (node->decl));
> +	  if (origin_node)
> +	    {
> +	      origin_node->used_as_abstract_origin = true;
> +	      add_node_to (encoder, origin_node, true);
> +	    }
>  	}
>      }
>    for (lsei = lsei_start_variable_in_partition (in_encoder);
> 
> 
> 2015-08-28  Richard Biener  <rguenther@suse.de>
> 
> 	* cgraph.c (cgraph_node::remove): If the node was used as
> 	abstract origin mark the decl as abstract.
> 	* lto-cgraph.c (compute_ltrans_boundary): Do not put abstract
> 	nodes in the ltrans boundary.
> 
> Index: trunk/gcc/cgraph.c
> ===================================================================
> --- trunk.orig/gcc/cgraph.c	2015-08-13 13:13:56.942263721 +0200
> +++ trunk/gcc/cgraph.c	2015-08-28 10:03:06.841844184 +0200
> @@ -1840,6 +1840,9 @@ cgraph_node::remove (void)
>        lto_file_data = NULL;
>      }
>  
> +  if (used_as_abstract_origin)
> +    DECL_ABSTRACT_P (decl) = 1;
> +
>    decl = NULL;
>    if (call_site_hash)
>      {
> Index: trunk/gcc/lto-cgraph.c
> ===================================================================
> --- trunk.orig/gcc/lto-cgraph.c	2015-08-13 13:14:09.116378573 +0200
> +++ trunk/gcc/lto-cgraph.c	2015-08-28 10:12:13.944867635 +0200
> @@ -896,10 +896,12 @@ compute_ltrans_boundary (lto_symtab_enco
>        lto_set_symtab_encoder_in_partition (encoder, node);
>        create_references (encoder, node);
>        /* For proper debug info, we need to ship the origins, too.  */
> -      if (DECL_ABSTRACT_ORIGIN (node->decl))
> +      if (DECL_ABSTRACT_ORIGIN (node->decl)
> +	  /* ???  But we might have removed it!  */
> +	  && ! DECL_ABSTRACT_P (DECL_ABSTRACT_ORIGIN (node->decl)))
>  	{
>  	  struct cgraph_node *origin_node
> -	  = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (node->decl));
> +	    = cgraph_node::get (DECL_ABSTRACT_ORIGIN (node->decl));
>  	  origin_node->used_as_abstract_origin = true;
>  	  add_node_to (encoder, origin_node, true);
>  	}
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)



More information about the Gcc-patches mailing list