> So... I've been getting my feet wet with LTO and debugging and I
> noticed a seemingly unrelated yet annoying problem.  On x86-64,
> gcc.dg/guality/pr48437.c fails when run in LTO mode.
> 
> I've compared the dwarf output with and without LTO, and I noticed
> that the DW_TAG_lexical_block is missing from the LTO case.
> 
> The relevant bit is that without LTO, we have a DW_TAG_lexical_block
> for lines 3-6, which is not present in the LTO case:
> 
> 1  volatile int i;
> 2  for (i = 3; i < 7; ++i)
> 3    {
> 4      extern int i;
> 5      asm volatile (NOP : : : "memory");
> 6    }
> 
> The reason this tag is not generated is because gen_block_die()
> unsets must_output_die because there are no BLOCK_VARS associated
> with the BLOCK.
> 
>       must_output_die = ((BLOCK_VARS (stmt) != NULL
>                           || BLOCK_NUM_NONLOCALIZED_VARS (stmt))
>                          && (TREE_USED (stmt)
>                              || TREE_ASM_WRITTEN (stmt)
>                              || BLOCK_ABSTRACT (stmt)));
> 
> And there is no block var because the streamer purposely avoided
> streaming an extern block var:
> 
>       /* We avoid outputting external vars or functions by reference
>        to the global decls section as we do not want to have them
>        enter decl merging.  This is, of course, only for the call
>        for streaming BLOCK_VARS, but other callers are safe.  */
>       /* ???  FIXME wrt SCC streaming.  Drop these for now.  */
>       if (VAR_OR_FUNCTION_DECL_P (t)
>         && DECL_EXTERNAL (t))
>       ; /* stream_write_tree_shallow_non_ref (ob, t, ref_p); */
>       else
>       stream_write_tree (ob, t, ref_p);
> 
> I naively tried to uncomment the offending line, but that brought
> about other problems in DFS assertions.

The code deciding what to output is duplicated in between lto-streamer
and tree-streamer.  I suppose you want to update DFS::DFS_write_tree_body
> 
> I wasn't on the hunt for this, but I'm now curious.  Can you (or
> anyone else) pontificate on this? Do we avoid streaming extern block
> variables by design?

I think the problem here is that blocks are hold together by DECL_CHAIN.
Becuase the declarations get merged across compilation units based on their
assembler names, they can sit in at most one block.  Merging them will
then probably accidentaly marge tails of BLOCK_VARs lists.

Honza
> 
> Thanks.
> Aldy

Reply via email to