On Mon, 13 Aug 2018, Tom de Vries wrote: > Hi, > > With the introduction of early debug, we've added a phase in the compiler > which > produces information which is not visible, unless we run the compiler in the > debugger and call debug_dwarf from dwarf2out_early_finish or some such. > > This patch adds dumping of "early" and "final" debug info, into .earlydebug > and .debug dump files, such that we can follow f.i. the upper bound of a vla > type from early debug: > ... > DW_AT_upper_bound: location descriptor: > (0x7f0d645b7550) DW_OP_GNU_variable_value , 0 > ... > to final debug: > ... > DW_AT_upper_bound: location descriptor: > (0x7f0d645b7550) DW_OP_fbreg 18446744073709551592, 0 > (0x7f0d645b7a00) DW_OP_deref 8, 0 > ... > to -dA annotated assembly file: > ... > .uleb128 0x3 # DW_AT_upper_bound > .byte 0x91 # DW_OP_fbreg > .sleb128 -24 > .byte 0x6 # DW_OP_deref > ... > > The .debug file shows the same information as the annotated assembly, but in > the same format as the "early" debug info. > > Bootstrapped and reg-tested on x86_64. > > OK for trunk?
OK. Can you document the options to trigger those dumps? I suppose -fdump-tree-earlydebug and -fdump-tree-debug? Thanks, Richard. > Thanks, > - Tom > > [debug] Add debug and earlydebug dumps > > 2018-08-13 Tom de Vries <tdevr...@suse.de> > > * cgraph.h (debuginfo_early_init, debuginfo_init, debuginfo_fini) > (debuginfo_start, debuginfo_stop, debuginfo_early_start) > (debuginfo_early_stop): Declare. > * cgraphunit.c (debuginfo_early_init, debuginfo_init, debuginfo_fini) > (debuginfo_start, debuginfo_stop, debuginfo_early_start) > (debuginfo_early_stop): New function. > (symbol_table::finalize_compilation_unit): Call debuginfo_early_start > and debuginfo_early_stop. > * dwarf2out.c (print_dw_val, print_loc_descr, print_die): Handle > flag_dump_noaddr and flag_dump_unnumbered. > (dwarf2out_finish, dwarf2out_early_finish): Dump dwarf. > * toplev.c (compile_file): Call debuginfo_start and debuginfo_stop. > (general_init): Call debuginfo_early_init. > (finalize): Call debuginfo_fini. > (do_compile): Call debuginfo_init. > > * lto.c (lto_main): Call debuginfo_early_start and > debuginfo_early_stop. > > * gcc.c-torture/unsorted/dump-noaddr.x: Skip earlydebug and debug dumps. > > --- > gcc/cgraph.h | 8 +++ > gcc/cgraphunit.c | 66 > ++++++++++++++++++++++ > gcc/dwarf2out.c | 46 ++++++++++++--- > gcc/lto/lto.c | 2 + > gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x | 7 +++ > gcc/toplev.c | 5 ++ > 6 files changed, 126 insertions(+), 8 deletions(-) > > diff --git a/gcc/cgraph.h b/gcc/cgraph.h > index a8b1b4cb3c3..2b00f0165fa 100644 > --- a/gcc/cgraph.h > +++ b/gcc/cgraph.h > @@ -25,6 +25,14 @@ along with GCC; see the file COPYING3. If not see > #include "ipa-ref.h" > #include "plugin-api.h" > > +extern void debuginfo_early_init (void); > +extern void debuginfo_init (void); > +extern void debuginfo_fini (void); > +extern void debuginfo_start (void); > +extern void debuginfo_stop (void); > +extern void debuginfo_early_start (void); > +extern void debuginfo_early_stop (void); > + > class ipa_opt_pass_d; > typedef ipa_opt_pass_d *ipa_opt_pass; > > diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c > index 462e247328e..6649942c4fb 100644 > --- a/gcc/cgraphunit.c > +++ b/gcc/cgraphunit.c > @@ -2636,6 +2636,70 @@ symbol_table::compile (void) > } > } > > +static int debuginfo_early_dump_nr; > +static FILE *debuginfo_early_dump_file; > +static dump_flags_t debuginfo_early_dump_flags; > + > +static int debuginfo_dump_nr; > +static FILE *debuginfo_dump_file; > +static dump_flags_t debuginfo_dump_flags; > + > +void > +debuginfo_early_init (void) > +{ > + gcc::dump_manager *dumps = g->get_dumps (); > + debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", > "earlydebug", > + "earlydebug", DK_tree, > + OPTGROUP_NONE, > + false); > + debuginfo_dump_nr = dumps->dump_register (".debug", "debug", > + "debug", DK_tree, > + OPTGROUP_NONE, > + false); > +} > + > +void > +debuginfo_init (void) > +{ > + gcc::dump_manager *dumps = g->get_dumps (); > + debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL); > + debuginfo_dump_flags = dumps->get_dump_file_info > (debuginfo_dump_nr)->pflags; > + debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL); > + debuginfo_early_dump_flags = dumps->get_dump_file_info > (debuginfo_early_dump_nr)->pflags; > +} > + > +void > +debuginfo_fini (void) > +{ > + if (debuginfo_dump_file) > + dump_end (debuginfo_dump_nr, debuginfo_dump_file); > + if (debuginfo_early_dump_file) > + dump_end (debuginfo_early_dump_nr, debuginfo_early_dump_file); > +} > + > +void > +debuginfo_start (void) > +{ > + set_dump_file (debuginfo_dump_file); > +} > + > +void > +debuginfo_stop (void) > +{ > + set_dump_file (NULL); > +} > + > +void > +debuginfo_early_start (void) > +{ > + set_dump_file (debuginfo_early_dump_file); > +} > + > +void > +debuginfo_early_stop (void) > +{ > + set_dump_file (NULL); > +} > > /* Analyze the whole compilation unit once it is parsed completely. */ > > @@ -2691,7 +2755,9 @@ symbol_table::finalize_compilation_unit (void) > > /* Clean up anything that needs cleaning up after initial debug > generation. */ > + debuginfo_early_start (); > (*debug_hooks->early_finish) (main_input_filename); > + debuginfo_early_stop (); > } > > /* Finally drive the pass manager. */ > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > index 9ed473088e7..4b63cbd8a1e 100644 > --- a/gcc/dwarf2out.c > +++ b/gcc/dwarf2out.c > @@ -6455,7 +6455,12 @@ print_dw_val (dw_val_node *val, bool recurse, FILE > *outfile) > print_indent -= 4; > } > else > - fprintf (outfile, " (%p)\n", (void *) val->v.val_loc); > + { > + if (flag_dump_noaddr || flag_dump_unnumbered) > + fprintf (outfile, " #\n"); > + else > + fprintf (outfile, " (%p)\n", (void *) val->v.val_loc); > + } > break; > case dw_val_class_loc_list: > fprintf (outfile, "location list -> label:%s", > @@ -6524,7 +6529,10 @@ print_dw_val (dw_val_node *val, bool recurse, FILE > *outfile) > } > else > fprintf (outfile, "die -> %ld", die->die_offset); > - fprintf (outfile, " (%p)", (void *) die); > + if (flag_dump_noaddr || flag_dump_unnumbered) > + fprintf (outfile, " #"); > + else > + fprintf (outfile, " (%p)", (void *) die); > } > else > fprintf (outfile, "die -> <null>"); > @@ -6614,8 +6622,11 @@ print_loc_descr (dw_loc_descr_ref loc, FILE *outfile) > for (l = loc; l != NULL; l = l->dw_loc_next) > { > print_spaces (outfile); > - fprintf (outfile, "(%p) %s", > - (void *) l, > + if (flag_dump_noaddr || flag_dump_unnumbered) > + fprintf (outfile, "#"); > + else > + fprintf (outfile, "(%p)", (void *) l); > + fprintf (outfile, " %s", > dwarf_stack_op_name (l->dw_loc_opc)); > if (l->dw_loc_oprnd1.val_class != dw_val_class_none) > { > @@ -6642,9 +6653,12 @@ print_die (dw_die_ref die, FILE *outfile) > unsigned ix; > > print_spaces (outfile); > - fprintf (outfile, "DIE %4ld: %s (%p)\n", > - die->die_offset, dwarf_tag_name (die->die_tag), > - (void*) die); > + fprintf (outfile, "DIE %4ld: %s ", > + die->die_offset, dwarf_tag_name (die->die_tag)); > + if (flag_dump_noaddr || flag_dump_unnumbered) > + fprintf (outfile, "#\n"); > + else > + fprintf (outfile, "(%p)\n", (void*) die); > print_spaces (outfile); > fprintf (outfile, " abbrev id: %lu", die->die_abbrev); > fprintf (outfile, " offset: %ld", die->die_offset); > @@ -31088,7 +31102,7 @@ reset_dies (dw_die_ref die) > and generate the DWARF-2 debugging info. */ > > static void > -dwarf2out_finish (const char *) > +dwarf2out_finish (const char *filename) > { > comdat_type_node *ctnode; > dw_die_ref main_comp_unit_die; > @@ -31169,6 +31183,12 @@ dwarf2out_finish (const char *) > resolve_addr (comp_unit_die ()); > move_marked_base_types (); > > + if (dump_file) > + { > + fprintf (dump_file, "DWARF for %s\n", filename); > + print_die (comp_unit_die (), dump_file); > + } > + > /* Initialize sections and labels used for actual assembler output. */ > unsigned generation = init_sections_and_labels (false); > > @@ -31864,6 +31884,11 @@ dwarf2out_early_finish (const char *filename) > if (in_lto_p) > { > early_dwarf_finished = true; > + if (dump_file) > + { > + fprintf (dump_file, "LTO EARLY DWARF for %s\n", filename); > + print_die (comp_unit_die (), dump_file); > + } > return; > } > > @@ -31941,6 +31966,11 @@ dwarf2out_early_finish (const char *filename) > > /* The early debug phase is now finished. */ > early_dwarf_finished = true; > + if (dump_file) > + { > + fprintf (dump_file, "EARLY DWARF for %s\n", filename); > + print_die (comp_unit_die (), dump_file); > + } > > /* Do not generate DWARF assembler now when not producing LTO bytecode. */ > if ((!flag_generate_lto && !flag_generate_offload) > diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c > index 8db280ecefc..10618896022 100644 > --- a/gcc/lto/lto.c > +++ b/gcc/lto/lto.c > @@ -3419,7 +3419,9 @@ lto_main (void) > lto_promote_statics_nonwpa (); > > /* Annotate the CU DIE and mark the early debug phase as finished. */ > + debuginfo_early_start (); > debug_hooks->early_finish ("<artificial>"); > + debuginfo_early_stop (); > > /* Let the middle end know that we have read and merged all of > the input files. */ > diff --git a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x > b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x > index e86f36a1861..d2be9c001e0 100644 > --- a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x > +++ b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x > @@ -19,6 +19,13 @@ proc dump_compare { src options } { > set dump2 "$tmpdir/dump2/[file tail $dump1]" > set dumptail "gcc.c-torture/unsorted/[file tail $dump1]" > regsub {\.\d+((t|r|i)\.[^.]+)$} $dumptail {.*\1} dumptail > + if { "$dumptail" == > "gcc.c-torture/unsorted/dump-noaddr.c.*t.earlydebug" > + || "$dumptail" == > "gcc.c-torture/unsorted/dump-noaddr.c.*t.debug" } { > + # The DW_AT_producer line contains the command line options so, > this will > + # fail on dump1 having '--param ggc-min-heapsize=1', and dump2 > not. > + untested "$dumptail, $option comparison" > + continue > + } > set tmp [ diff "$dump1" "$dump2" ] > if { $tmp == 0 } { > untested "$dumptail, $option comparison" > diff --git a/gcc/toplev.c b/gcc/toplev.c > index aa943a8655e..d28bff01552 100644 > --- a/gcc/toplev.c > +++ b/gcc/toplev.c > @@ -529,7 +529,9 @@ compile_file (void) > dwarf2out_frame_finish (); > #endif > > + debuginfo_start (); > (*debug_hooks->finish) (main_input_filename); > + debuginfo_stop (); > timevar_pop (TV_SYMOUT); > > /* Output some stuff at end of file if nec. */ > @@ -1185,6 +1187,7 @@ general_init (const char *argv0, bool init_signals) > symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table (); > > statistics_early_init (); > + debuginfo_early_init (); > finish_params (); > } > > @@ -2079,6 +2082,7 @@ finalize (bool no_backend) > if (!no_backend) > { > statistics_fini (); > + debuginfo_fini (); > > g->get_passes ()->finish_optimization_passes (); > > @@ -2156,6 +2160,7 @@ do_compile () > init_final (main_input_filename); > coverage_init (aux_base_name); > statistics_init (); > + debuginfo_init (); > invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL); > > timevar_stop (TV_PHASE_SETUP); > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)