On Wed, Sep 26, 2018 at 9:35 AM, Richard Biener <rguent...@suse.de> wrote:
>
> We do not create a DW_AT_lexical_block for the outermost block in
> functions but we do for DW_AT_inlined_subroutines.  That makes
> debuginfo look like if there were two of each local, the outer
> one (from the abstract instance) optimized out (visible via
> info locals in gdb).
>
> The following elides the outermost block also from inline instances.
> It's a bit tricky to reliably track that block given we remove unused
> blocks here and there.  The trick is to have the block in the abstract
> instance _not_ point to itself (given we do not output it it isn't
> the abstract origin for itself).
>
> Bootstrapped on x86_64-unkown-linux-gnu, testing in progress.
>
> Again with some scan-assembler testcase, guality cannot do 'info locals'.
>
> OK?
>
> Thanks,
> Richard.
>
> 2018-09-26  Richard Biener  <rguent...@suse.de>
>
>         PR debug/87440
>         * dwarf2out.c (set_block_origin_self): Do not mark outermost
>         block as we do not output that.
>         (gen_inlined_subroutine_die): Elide the originally outermost
>         block, matching what we do for concrete instances.
>         (decls_for_scope): Add parameter specifying whether to recurse
>         to subblocks.
>
>         * gcc.dg/debug/dwarf2/inline4.c: New testcase.
>
> Index: gcc/testsuite/gcc.dg/debug/dwarf2/inline4.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/debug/dwarf2/inline4.c (nonexistent)
> +++ gcc/testsuite/gcc.dg/debug/dwarf2/inline4.c (working copy)
> @@ -0,0 +1,17 @@
> +/* Verify that the inline instance has no extra DW_TAG_lexical_block between
> +   the DW_TAG_inlined_subroutine and the DW_TAG_variable for the local.  */
> +/* { dg-options "-O -gdwarf -dA" } */
> +/* { dg-do compile } */
> +/* { dg-final { scan-assembler 
> "DW_TAG_inlined_subroutine\[^\\(\]*\\(\[^\\)\]*\\)\[^\\(\]*\\(DIE 
> \\(0x\[0-9a-f\]*\\) DW_TAG_formal_parameter\[^\\(\]*\\(DIE 
> \\(0x\[0-9a-f\]*\\) DW_TAG_variable" } } */
> +/* { dg-final { scan-assembler-times "DW_TAG_inlined_subroutine" 2 } } */
> +
> +static int foo (int i)
> +{
> +  volatile int j = i + 3;
> +  return j - 2;
> +}
> +int main()
> +{
> +  volatile int z = foo (-1);
> +  return z;
> +}
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c     (revision 264640)
> +++ gcc/dwarf2out.c     (working copy)
> @@ -3867,7 +3867,7 @@ static void gen_subroutine_type_die (tre
>  static void gen_typedef_die (tree, dw_die_ref);
>  static void gen_type_die (tree, dw_die_ref);
>  static void gen_block_die (tree, dw_die_ref);
> -static void decls_for_scope (tree, dw_die_ref);
> +static void decls_for_scope (tree, dw_die_ref, bool = true);
>  static bool is_naming_typedef_decl (const_tree);
>  static inline dw_die_ref get_context_die (tree);
>  static void gen_namespace_die (tree, dw_die_ref);
> @@ -22389,7 +22389,13 @@ set_block_origin_self (tree stmt)
>  {
>    if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
>      {
> -      BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;
> +      /* We do not mark the outermost block as we are not outputting it.
> +        This is then a reliable way of determining whether we should
> +        do the same for an inline instance.  */
> +      if (TREE_CODE (BLOCK_SUPERCONTEXT (stmt)) != FUNCTION_DECL)
> +       BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;
> +      else
> +       gcc_assert (DECL_INITIAL (BLOCK_SUPERCONTEXT (stmt)) == stmt);
>
>        {
>         tree local_decl;
> @@ -24149,7 +24155,24 @@ gen_inlined_subroutine_die (tree stmt, d
>          add_high_low_attributes (stmt, subr_die);
>        add_call_src_coords_attributes (stmt, subr_die);
>
> -      decls_for_scope (stmt, subr_die);
> +      /* The inliner creates an extra BLOCK for the parameter setup,
> +         we want to merge that with the actual outermost BLOCK of the
> +        inlined function to avoid duplicate locals in consumers.  Note
> +        we specially mark that not as origin-self.
> +        Do that by doing the recursion to subblocks on the single subblock
> +        of STMT.  */
> +      bool unwrap_one = false;
> +      if (BLOCK_SUBBLOCKS (stmt) && !BLOCK_CHAIN (BLOCK_SUBBLOCKS (stmt)))
> +       {
> +         tree origin = block_ultimate_origin (BLOCK_SUBBLOCKS (stmt));
> +         if (origin
> +             && TREE_CODE (origin) == BLOCK
> +             && !BLOCK_ABSTRACT_ORIGIN (origin))

Can we look at BLOCK_SUPERCONTEXT here rather than above?

Jason

Reply via email to