Message ID | 20180813182537.GA1874@delia |
---|---|
State | New |
Headers | show |
Series | [debug] Add debug and earlydebug dumps | expand |
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 <tdevries@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); > >
On 08/20/2018 02:24 PM, Richard Biener wrote: > 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? Done. > I suppose -fdump-tree-earlydebug and -fdump-tree-debug? No, they're -fdump-earlydebug and -fdump-debug, but they're members of the tree family, so they're enabled with fdump-tree-all, which is the same behaviour as we have for -fdump-statistics. Apart from adding docs, I've: - improved the workaround in unsorted/dump-noaddr.x, after learning about -grecord-gcc-switches - fixed 2 formatting issues (line longer than 80, leading whitespace inconsistent with adjacent lines) - added comments to new functions and global variables - split off "[debug] Respect fdump-noaddr and fdump-unnumbered in print_die" as separate patch, and committed (not reposting). Committed as attached. Thanks, - Tom [debug] Add debug and earlydebug dumps 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, enabled by -fdump-earlydebug and -fdumpdebug, 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. 2018-08-13 Tom de Vries <tdevries@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 (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. * doc/invoke.texi (@gccoptlist): Add -fdump-debug and -fdump-early-debug. (@item -fdump-debug, @item -fdump-earlydebug): Add. * lto.c (lto_main): Call debuginfo_early_start and debuginfo_early_stop. * gcc.c-torture/unsorted/dump-noaddr.x: Use -gno-record-gcc-switches to avoid mismatch in .debug and .earlydebug dump files. --- gcc/cgraph.h | 8 ++ gcc/cgraphunit.c | 85 ++++++++++++++++++++++ gcc/doc/invoke.texi | 11 +++ gcc/dwarf2out.c | 18 ++++- gcc/lto/lto.c | 2 + gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x | 4 +- gcc/toplev.c | 5 ++ 7 files changed, 130 insertions(+), 3 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..e43c96a4043 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2636,6 +2636,89 @@ symbol_table::compile (void) } } +/* Earlydebug dump file, flags, and number. */ + +static int debuginfo_early_dump_nr; +static FILE *debuginfo_early_dump_file; +static dump_flags_t debuginfo_early_dump_flags; + +/* Debug dump file, flags, and number. */ + +static int debuginfo_dump_nr; +static FILE *debuginfo_dump_file; +static dump_flags_t debuginfo_dump_flags; + +/* Register the debug and earlydebug dump files. */ + +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); +} + +/* Initialize the debug and earlydebug dump files. */ + +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; +} + +/* Finalize the debug and earlydebug dump files. */ + +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); +} + +/* Set dump_file to the debug dump file. */ + +void +debuginfo_start (void) +{ + set_dump_file (debuginfo_dump_file); +} + +/* Undo setting dump_file to the debug dump file. */ + +void +debuginfo_stop (void) +{ + set_dump_file (NULL); +} + +/* Set dump_file to the earlydebug dump file. */ + +void +debuginfo_early_start (void) +{ + set_dump_file (debuginfo_early_dump_file); +} + +/* Undo setting dump_file to the earlydebug dump file. */ + +void +debuginfo_early_stop (void) +{ + set_dump_file (NULL); +} /* Analyze the whole compilation unit once it is parsed completely. */ @@ -2691,7 +2774,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/doc/invoke.texi b/gcc/doc/invoke.texi index f8287153be1..99849ec6467 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -566,6 +566,7 @@ Objective-C and Objective-C++ Dialects}. -fdisable-rtl-@var{pass-name}=@var{range-list} @gol -fdisable-tree-@var{pass_name} @gol -fdisable-tree-@var{pass-name}=@var{range-list} @gol +-fdump-debug -fdump-earlydebug @gol -fdump-noaddr -fdump-unnumbered -fdump-unnumbered-links @gol -fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol -fdump-final-insns@r{[}=@var{file}@r{]} @gol @@ -13777,6 +13778,16 @@ Just generate RTL for a function instead of compiling it. Usually used with @option{-fdump-rtl-expand}. @end table +@item -fdump-debug +@opindex fdump-debug +Dump debugging information generated during the debug +generation phase. + +@item -fdump-earlydebug +@opindex fdump-earlydebug +Dump debugging information generated during the early debug +generation phase. + @item -fdump-noaddr @opindex fdump-noaddr When doing debugging dumps, suppress address output. This makes it more diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index ffb332a358d..fb71ff349fa 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -31112,7 +31112,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; @@ -31193,6 +31193,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); @@ -31888,6 +31894,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; } @@ -31965,6 +31976,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..0e4298ad3d7 100644 --- a/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x +++ b/gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x @@ -11,10 +11,10 @@ proc dump_compare { src options } { foreach option $option_list { file delete -force $tmpdir/dump1 file mkdir $tmpdir/dump1 - c-torture-compile $src "$option $options -dumpbase dump1/$dumpbase -DMASK=1 -x c --param ggc-min-heapsize=1 -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" + c-torture-compile $src "$option $options -dumpbase dump1/$dumpbase -DMASK=1 -x c --param ggc-min-heapsize=1 -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr -gno-record-gcc-switches" file delete -force $tmpdir/dump2 file mkdir $tmpdir/dump2 - c-torture-compile $src "$option $options -dumpbase dump2/$dumpbase -DMASK=2 -x c -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr" + c-torture-compile $src "$option $options -dumpbase dump2/$dumpbase -DMASK=2 -x c -fdump-ipa-all -fdump-rtl-all -fdump-tree-all -fdump-noaddr -gno-record-gcc-switches" foreach dump1 [lsort [glob -nocomplain $tmpdir/dump1/*]] { set dump2 "$tmpdir/dump2/[file tail $dump1]" set dumptail "gcc.c-torture/unsorted/[file tail $dump1]" diff --git a/gcc/toplev.c b/gcc/toplev.c index 2789d71b24f..9fb83d4e43f 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. */ @@ -1187,6 +1189,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 (); } @@ -2081,6 +2084,7 @@ finalize (bool no_backend) if (!no_backend) { statistics_fini (); + debuginfo_fini (); g->get_passes ()->finish_optimization_passes (); @@ -2158,6 +2162,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);
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);