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