[debug] Add debug and earlydebug dumps
authorTom de Vries <tdevries@suse.de>
Tue, 21 Aug 2018 07:39:29 +0000 (07:39 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Tue, 21 Aug 2018 07:39:29 +0000 (07:39 +0000)
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-21  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.

From-SVN: r263687

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphunit.c
gcc/doc/invoke.texi
gcc/dwarf2out.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x
gcc/toplev.c

index eb9c151806299eb54b7567db6d99af9a4671c7ea..47dd9eaa4cae2ebee61b54d2c7d584717e594ecd 100644 (file)
@@ -1,3 +1,22 @@
+2018-08-21  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.
+
 2018-08-21  Tom de Vries  <tdevries@suse.de>
 
        * dwarf2out.c (print_dw_val, print_loc_descr, print_die): Handle
index a8b1b4cb3c38f5d8fe1160366fff26388c376dc9..2b00f0165faeb706374a945dd8c99561f1db34ff 100644 (file)
@@ -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;
 
index 208798f0dc7a8e636e91ff7bb70a1f5cff4c97cc..ec490d75bd1162cf691708c366ab0e86f4eb5a67 100644 (file)
@@ -2641,6 +2641,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.  */
 
@@ -2696,7 +2779,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.  */
index f8287153be14cf9ca9f76b60a245963958be3fc1..99849ec6467b607dd637469cc4d453a30361077f 100644 (file)
@@ -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
index ffb332a358d3f14cf6e684dacf6b8df2a015f523..fb71ff349fac0af8ede3f68c356a92aaaa7f190f 100644 (file)
@@ -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)
index eb239972d9e72cc7a5e4901b5d22640a3ddad8b7..a92317cb77412c360e9a2b3c9155562cffe256a9 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-21  Tom de Vries  <tdevries@suse.de>
+
+       * lto.c (lto_main):  Call debuginfo_early_start and
+       debuginfo_early_stop.
+
 2018-07-20  Martin Sebor  <msebor@redhat.com>
 
        PR middle-end/82063
index 8db280ecefc7ba7e894d5f43fd3b789f6eea5f74..10618896022c8af4e18a9fb7fde7a157901dd569 100644 (file)
@@ -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.  */ 
index af8615607fbebdc0f69605d37677380e36740835..0a420304716a0f82f47efe9548d01131f95eb0a9 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-21  Tom de Vries  <tdevries@suse.de>
+
+       * gcc.c-torture/unsorted/dump-noaddr.x: Use -gno-record-gcc-switches
+       to avoid mismatch in .debug and .earlydebug dump files.
+
 2018-08-20  Michael Meissner  <meissner@linux.ibm.com>
 
        PR target/87033
index e86f36a1861fc4dc46bd449d78403f510ec4b920..0e4298ad3d7dc4a5c873e501520dbd4609289ccf 100644 (file)
@@ -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]"
index 2789d71b24f5f695d1415cbdbc51f2dc9332b25e..9fb83d4e43f2ce19ad511a7d54e37c7ecbf00b2b 100644 (file)
@@ -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);