This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: LTO inhibiting dwarf lexical blocks output


On Fri, Aug 15, 2014 at 9:59 PM, Aldy Hernandez <aldyh@redhat.com> wrote:
> 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?

Apart from other comments about emitting DIEs early the commented
code above tried to "force" to not put 't' into the global decls table
but retain it as local tree to avoid (as Honza says) merging it with
other entities and thus screwing up DECL_CHAIN.

With the SCC way this didn't work out (you can't simply do
stream_write_tree_shallow_non_ref here for reasons I don't remember).
The ??? comment means I've wanted to come back to this... ;)
"shallow non-ref" means treat 't' as !ref but not the trees it references.

Note that the biggest "hack" wrt lexical scopes is that we don't stream
any abstract origins

/* Write all pointer fields in the TS_BLOCK structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
{
  streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);

  stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);

  /* Stream BLOCK_ABSTRACT_ORIGIN for the limited cases we can handle - those
     that represent inlined function scopes.
     For the rest them on the floor instead of ICEing in dwarf2out.c.  */
  if (inlined_function_outer_scope_p (expr))
    {
      tree ultimate_origin = block_ultimate_origin (expr);
      stream_write_tree (ob, ultimate_origin, ref_p);
    }
  else
    stream_write_tree (ob, NULL_TREE, ref_p);

which makes early inlined functions behave differently (?) in the
debugger with LTO than without (you still get blocks, but they
do not refer to the out-of-line copy by reference but get fully
re-created with DIEs for each inline instance).  But maybe the
abstract origins are only a dwarf-size optimization here.

Richard.

> Thanks.
> Aldy


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]