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.

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?

Thanks.
Aldy

Reply via email to