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 Mon, Aug 18, 2014 at 12:46 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> 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.

The following seems to fix it.  In testing now.

Richard.

> Richard.
>
>> Thanks.
>> Aldy

Attachment: p5
Description: Binary data


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