* [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
@ 2015-08-18 14:42 Richard Biener
2015-08-18 19:48 ` Aldy Hernandez
0 siblings, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-08-18 14:42 UTC (permalink / raw)
To: gcc-patches; +Cc: jason, aldyh
This starts a series of patches (still in development) to refactor
dwarf2out.c to better cope with early debug (and LTO debug).
The first part (and some followups) will move stuff from dwarf2out_finish
to dwarf2out_early_finish to get the early DIE tree "complete" as
LTO early debug will assemble it in the dwarf2out_early_finish hook.
So first avoid calling dwarf2out_early_finish again from
dwarf2out_finish by factoring out the limbo list flush.
Second, add a filename parameter so we can move some attribute
setting code to dwarf2out_early_finish.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Ok?
Aldyh, what other testing did you usually do for changes? Run
the gdb testsuite against the new compiler? Anything else?
Thanks,
Richard.
2015-08-18 Richard Biener <rguenther@suse.de>
* debug.h (gcc_debug_hooks::early_finish): Add filename argument.
* dbxout.c (dbx_debug_hooks): Adjust.
* debug.c (do_nothing_hooks): Likewise.
* sdbout.c (sdb_debug_hooks): Likewise.
* vmsdbgout.c (vmsdbgout_early_finish): New function dispatching
to dwarf2out variant if needed.
(vmsdbg_debug_hooks): Adjust.
* dwarf2out.c (dwarf2_line_hooks): Adjust.
(flush_limbo_die_list): New function.
(dwarf2out_finish): Call flush_limbo_die_list instead of
dwarf2out_early_finish. Assert there are no deferred asm-names.
Move early stuff ...
(dwarf2out_early_finish): ... here.
* cgraphunit.c (symbol_table::finalize_compilation_unit):
Call early_finish with main_input_filename argument.
Index: gcc/debug.h
===================================================================
--- gcc/debug.h (revision 226966)
+++ gcc/debug.h (working copy)
@@ -31,7 +31,7 @@ struct gcc_debug_hooks
void (* finish) (const char *main_filename);
/* Run cleanups necessary after early debug generation. */
- void (* early_finish) (void);
+ void (* early_finish) (const char *main_filename);
/* Called from cgraph_optimize before starting to assemble
functions/variables/toplevel asms. */
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c (revision 226966)
+++ gcc/dbxout.c (working copy)
@@ -354,7 +354,7 @@ const struct gcc_debug_hooks dbx_debug_h
{
dbxout_init,
dbxout_finish,
- debug_nothing_void,
+ debug_nothing_charstar,
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
Index: gcc/debug.c
===================================================================
--- gcc/debug.c (revision 226966)
+++ gcc/debug.c (working copy)
@@ -28,7 +28,7 @@ const struct gcc_debug_hooks do_nothing_
{
debug_nothing_charstar,
debug_nothing_charstar,
- debug_nothing_void, /* early_finish */
+ debug_nothing_charstar, /* early_finish */
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
Index: gcc/sdbout.c
===================================================================
--- gcc/sdbout.c (revision 226966)
+++ gcc/sdbout.c (working copy)
@@ -278,7 +278,7 @@ const struct gcc_debug_hooks sdb_debug_h
{
sdbout_init, /* init */
sdbout_finish, /* finish */
- debug_nothing_void, /* early_finish */
+ debug_nothing_charstar, /* early_finish */
debug_nothing_void, /* assembly_start */
debug_nothing_int_charstar, /* define */
debug_nothing_int_charstar, /* undef */
Index: gcc/vmsdbgout.c
===================================================================
--- gcc/vmsdbgout.c (revision 226966)
+++ gcc/vmsdbgout.c (working copy)
@@ -147,6 +147,7 @@ static int write_srccorrs (int);
static void vmsdbgout_init (const char *);
static void vmsdbgout_finish (const char *);
+static void vmsdbgout_early_finish (const char *);
static void vmsdbgout_assembly_start (void);
static void vmsdbgout_define (unsigned int, const char *);
static void vmsdbgout_undef (unsigned int, const char *);
@@ -174,7 +175,7 @@ static void vmsdbgout_abstract_function
const struct gcc_debug_hooks vmsdbg_debug_hooks
= {vmsdbgout_init,
vmsdbgout_finish,
- debug_nothing_void,
+ vmsdbgout_early_finish,
vmsdbgout_assembly_start,
vmsdbgout_define,
vmsdbgout_undef,
@@ -1549,6 +1550,16 @@ vmsdbgout_abstract_function (tree decl)
}
/* Output stuff that Debug requires at the end of every file and generate the
+ VMS Debug debugging info. */
+
+static void
+vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
+{
+ if (write_symbols == VMS_AND_DWARF2_DEBUG)
+ (*dwarf2_debug_hooks.early_finish) (filename);
+}
+
+/* Output stuff that Debug requires at the end of every file and generate the
VMS Debug debugging info. */
static void
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 226966)
+++ gcc/dwarf2out.c (working copy)
@@ -2420,7 +2420,7 @@ build_cfa_aligned_loc (dw_cfa_location *
static void dwarf2out_init (const char *);
static void dwarf2out_finish (const char *);
-static void dwarf2out_early_finish (void);
+static void dwarf2out_early_finish (const char *);
static void dwarf2out_assembly_start (void);
static void dwarf2out_define (unsigned int, const char *);
static void dwarf2out_undef (unsigned int, const char *);
@@ -2494,7 +2494,7 @@ const struct gcc_debug_hooks dwarf2_line
{
dwarf2out_init,
debug_nothing_charstar,
- debug_nothing_void,
+ debug_nothing_charstar,
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
@@ -25128,46 +25128,77 @@ optimize_location_lists (dw_die_ref die)
optimize_location_lists_1 (die, &htab);
}
\f
+/* Traverse the limbo die list, and add parent/child links. The only
+ dies without parents that should be here are concrete instances of
+ inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
+ For concrete instances, we can get the parent die from the abstract
+ instance. */
+
+static void
+flush_limbo_die_list (void)
+{
+ limbo_die_node *node, *next_node;
+
+ for (node = limbo_die_list; node; node = next_node)
+ {
+ dw_die_ref die = node->die;
+ next_node = node->next;
+
+ if (die->die_parent == NULL)
+ {
+ dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
+
+ if (origin && origin->die_parent)
+ add_child_die (origin->die_parent, die);
+ else if (is_cu_die (die))
+ ;
+ else if (seen_error ())
+ /* It's OK to be confused by errors in the input. */
+ add_child_die (comp_unit_die (), die);
+ else
+ {
+ /* In certain situations, the lexical block containing a
+ nested function can be optimized away, which results
+ in the nested function die being orphaned. Likewise
+ with the return type of that nested function. Force
+ this to be a child of the containing function.
+
+ It may happen that even the containing function got fully
+ inlined and optimized out. In that case we are lost and
+ assign the empty child. This should not be big issue as
+ the function is likely unreachable too. */
+ gcc_assert (node->created_for);
+
+ if (DECL_P (node->created_for))
+ origin = get_context_die (DECL_CONTEXT (node->created_for));
+ else if (TYPE_P (node->created_for))
+ origin = scope_die_for (node->created_for, comp_unit_die ());
+ else
+ origin = comp_unit_die ();
+
+ add_child_die (origin, die);
+ }
+ }
+ }
+
+ limbo_die_list = NULL;
+}
+
/* Output stuff that dwarf requires at the end of every file,
and generate the DWARF-2 debugging info. */
static void
-dwarf2out_finish (const char *filename)
+dwarf2out_finish (const char *)
{
comdat_type_node *ctnode;
dw_die_ref main_comp_unit_die;
/* Flush out any latecomers to the limbo party. */
- dwarf2out_early_finish ();
+ flush_limbo_die_list ();
- /* PCH might result in DW_AT_producer string being restored from the
- header compilation, so always fill it with empty string initially
- and overwrite only here. */
- dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
- producer_string = gen_producer_string ();
- producer->dw_attr_val.v.val_str->refcount--;
- producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
-
- gen_scheduled_generic_parms_dies ();
- gen_remaining_tmpl_value_param_die_attribute ();
-
- /* Add the name for the main input file now. We delayed this from
- dwarf2out_init to avoid complications with PCH.
- For LTO produced units use a fixed artificial name to avoid
- leaking tempfile names into the dwarf. */
- if (!in_lto_p)
- add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
- else
- add_name_attribute (comp_unit_die (), "<artificial>");
- if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
- add_comp_dir_attribute (comp_unit_die ());
- else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
- {
- bool p = false;
- file_table->traverse<bool *, file_table_relative_p> (&p);
- if (p)
- add_comp_dir_attribute (comp_unit_die ());
- }
+ /* We shouldn't have any symbols with delayed asm names for
+ DIEs generated after early finish. */
+ gcc_assert (deferred_asm_name == NULL);
#if ENABLE_ASSERT_CHECKING
{
@@ -25482,9 +25513,9 @@ dwarf2out_finish (const char *filename)
has run. */
static void
-dwarf2out_early_finish (void)
+dwarf2out_early_finish (const char *filename)
{
- limbo_die_node *node, *next_node;
+ limbo_die_node *node;
/* Add DW_AT_linkage_name for all deferred DIEs. */
for (node = deferred_asm_name; node; node = node->next)
@@ -25502,57 +25533,38 @@ dwarf2out_early_finish (void)
}
deferred_asm_name = NULL;
- /* Traverse the limbo die list, and add parent/child links. The only
- dies without parents that should be here are concrete instances of
- inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
- For concrete instances, we can get the parent die from the abstract
- instance.
-
- The point here is to flush out the limbo list so that it is empty
+ /* The point here is to flush out the limbo list so that it is empty
and we don't need to stream it for LTO. */
- for (node = limbo_die_list; node; node = next_node)
- {
- dw_die_ref die = node->die;
- next_node = node->next;
+ flush_limbo_die_list ();
- if (die->die_parent == NULL)
- {
- dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
-
- if (origin && origin->die_parent)
- add_child_die (origin->die_parent, die);
- else if (is_cu_die (die))
- ;
- else if (seen_error ())
- /* It's OK to be confused by errors in the input. */
- add_child_die (comp_unit_die (), die);
- else
- {
- /* In certain situations, the lexical block containing a
- nested function can be optimized away, which results
- in the nested function die being orphaned. Likewise
- with the return type of that nested function. Force
- this to be a child of the containing function.
-
- It may happen that even the containing function got fully
- inlined and optimized out. In that case we are lost and
- assign the empty child. This should not be big issue as
- the function is likely unreachable too. */
- gcc_assert (node->created_for);
+ /* PCH might result in DW_AT_producer string being restored from the
+ header compilation, so always fill it with empty string initially
+ and overwrite only here. */
+ dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
+ producer_string = gen_producer_string ();
+ producer->dw_attr_val.v.val_str->refcount--;
+ producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
- if (DECL_P (node->created_for))
- origin = get_context_die (DECL_CONTEXT (node->created_for));
- else if (TYPE_P (node->created_for))
- origin = scope_die_for (node->created_for, comp_unit_die ());
- else
- origin = comp_unit_die ();
+ gen_scheduled_generic_parms_dies ();
+ gen_remaining_tmpl_value_param_die_attribute ();
- add_child_die (origin, die);
- }
- }
+ /* Add the name for the main input file now. We delayed this from
+ dwarf2out_init to avoid complications with PCH.
+ For LTO produced units use a fixed artificial name to avoid
+ leaking tempfile names into the dwarf. */
+ if (!in_lto_p)
+ add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+ else
+ add_name_attribute (comp_unit_die (), "<artificial>");
+ if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
+ add_comp_dir_attribute (comp_unit_die ());
+ else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
+ {
+ bool p = false;
+ file_table->traverse<bool *, file_table_relative_p> (&p);
+ if (p)
+ add_comp_dir_attribute (comp_unit_die ());
}
-
- limbo_die_list = NULL;
}
/* Reset all state within dwarf2out.c so that we can rerun the compiler
Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c (revision 226966)
+++ gcc/cgraphunit.c (working copy)
@@ -2490,7 +2490,7 @@ symbol_table::finalize_compilation_unit
/* Clean up anything that needs cleaning up after initial debug
generation. */
- (*debug_hooks->early_finish) ();
+ (*debug_hooks->early_finish) (main_input_filename);
/* Finally drive the pass manager. */
compile ();
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-18 14:42 [PATCH][1/n] dwarf2out refactoring for early (LTO) debug Richard Biener
@ 2015-08-18 19:48 ` Aldy Hernandez
2015-08-19 9:36 ` Yao Qi
2015-08-19 13:55 ` Richard Biener
0 siblings, 2 replies; 11+ messages in thread
From: Aldy Hernandez @ 2015-08-18 19:48 UTC (permalink / raw)
To: Richard Biener, gcc-patches; +Cc: jason
On 08/18/2015 07:20 AM, Richard Biener wrote:
>
> This starts a series of patches (still in development) to refactor
> dwarf2out.c to better cope with early debug (and LTO debug).
Awesome! Thanks.
> Aldyh, what other testing did you usually do for changes? Run
> the gdb testsuite against the new compiler? Anything else?
gdb testsuite, and make sure you test GCC with
--enable-languages=all,go,ada, though the latter is mostly useful while
you iron out bugs initially. I found that ultimately, the best test was
C++.
Pre merge I also bootstrapped the compiler and compared .debug* section
sizes in object files to make sure things were within reason.
> +
> +static void
> +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> +{
> + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> + (*dwarf2_debug_hooks.early_finish) (filename);
> +}
You can get rid of ATTRIBUTE_UNUSED now.
Aldy
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-18 19:48 ` Aldy Hernandez
@ 2015-08-19 9:36 ` Yao Qi
2015-08-19 13:55 ` Richard Biener
1 sibling, 0 replies; 11+ messages in thread
From: Yao Qi @ 2015-08-19 9:36 UTC (permalink / raw)
To: Richard Biener, gcc-patches; +Cc: Aldy Hernandez, jason
On 18/08/15 20:32, Aldy Hernandez wrote:
>> Aldyh, what other testing did you usually do for changes? Run
>> the gdb testsuite against the new compiler? Anything else?
>
> gdb testsuite, and make sure you test GCC with
> --enable-languages=all,go,ada, though the latter is mostly useful while
> you iron out bugs initially. I found that ultimately, the best test was
> C++.
FWIW, it would be nice to run gdb testsuite with different dwarf
versions (3, 4, and 5).
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-18 19:48 ` Aldy Hernandez
2015-08-19 9:36 ` Yao Qi
@ 2015-08-19 13:55 ` Richard Biener
2015-08-19 13:57 ` Aldy Hernandez
` (3 more replies)
1 sibling, 4 replies; 11+ messages in thread
From: Richard Biener @ 2015-08-19 13:55 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Tue, 18 Aug 2015, Aldy Hernandez wrote:
> On 08/18/2015 07:20 AM, Richard Biener wrote:
> >
> > This starts a series of patches (still in development) to refactor
> > dwarf2out.c to better cope with early debug (and LTO debug).
>
> Awesome! Thanks.
>
> > Aldyh, what other testing did you usually do for changes? Run
> > the gdb testsuite against the new compiler? Anything else?
>
> gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> though the latter is mostly useful while you iron out bugs initially. I found
> that ultimately, the best test was C++.
I see.
> Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> in object files to make sure things were within reason.
>
> > +
> > +static void
> > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > +{
> > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > + (*dwarf2_debug_hooks.early_finish) (filename);
> > +}
>
> You can get rid of ATTRIBUTE_UNUSED now.
Done. I've also refrained from moving
gen_scheduled_generic_parms_dies ();
gen_remaining_tmpl_value_param_die_attribute ();
for now as that causes regressions I have to investigate.
The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu
as well as gdb testing. Twice unpatched, twice patched - results seem
to be somewhat unstable!? I even refrained from using any -j with
make check-gdb... maybe it's just contrib/test_summary not coping well
with gdb? any hints? Difference between unpatched run 1 & 2 is
for example
--- results.unpatched 2015-08-19 15:08:36.152899926 +0200
+++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200
@@ -209,7 +209,6 @@
WARNING: remote_expect statement without a default case?!
WARNING: remote_expect statement without a default case?!
WARNING: remote_expect statement without a default case?!
-FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3,
fc4)
FAIL: gdb.cp/inherit.exp: print g_vD
FAIL: gdb.cp/inherit.exp: print g_vE
FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)'
@@ -238,6 +237,7 @@
UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings
FAIL: gdb.fortran/whatis_type.exp: run to MAIN__
WARNING: remote_expect statement without a default case?!
+FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt
WARNING: remote_expect statement without a default case?!
WARNING: remote_expect statement without a default case?!
WARNING: remote_expect statement without a default case?!
@@ -362,12 +362,12 @@
=== gdb Summary ===
-# of expected passes 30881
+# of expected passes 30884
# of unexpected failures 284
# of unexpected successes 2
-# of expected failures 85
+# of expected failures 83
# of unknown successes 2
-# of known failures 60
+# of known failures 59
# of unresolved testcases 6
# of untested testcases 32
# of unsupported tests 165
the sames changes randomly appear/disappear in the patched case.
Otherwise patched/unpatched agree.
Ok?
Thanks,
Richard.
2015-08-18 Richard Biener <rguenther@suse.de>
* debug.h (gcc_debug_hooks::early_finish): Add filename argument.
* dbxout.c (dbx_debug_hooks): Adjust.
* debug.c (do_nothing_hooks): Likewise.
* sdbout.c (sdb_debug_hooks): Likewise.
* vmsdbgout.c (vmsdbgout_early_finish): New function dispatching
to dwarf2out variant if needed.
(vmsdbg_debug_hooks): Adjust.
* dwarf2out.c (dwarf2_line_hooks): Adjust.
(flush_limbo_die_list): New function.
(dwarf2out_finish): Call flush_limbo_die_list instead of
dwarf2out_early_finish. Assert there are no deferred asm-names.
Move early stuff ...
(dwarf2out_early_finish): ... here.
* cgraphunit.c (symbol_table::finalize_compilation_unit):
Call early_finish with main_input_filename argument.
Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c (revision 226966)
+++ gcc/cgraphunit.c (working copy)
@@ -2490,7 +2490,7 @@ symbol_table::finalize_compilation_unit
/* Clean up anything that needs cleaning up after initial debug
generation. */
- (*debug_hooks->early_finish) ();
+ (*debug_hooks->early_finish) (main_input_filename);
/* Finally drive the pass manager. */
compile ();
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c (revision 226966)
+++ gcc/dbxout.c (working copy)
@@ -354,7 +354,7 @@ const struct gcc_debug_hooks dbx_debug_h
{
dbxout_init,
dbxout_finish,
- debug_nothing_void,
+ debug_nothing_charstar,
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
Index: gcc/debug.c
===================================================================
--- gcc/debug.c (revision 226966)
+++ gcc/debug.c (working copy)
@@ -28,7 +28,7 @@ const struct gcc_debug_hooks do_nothing_
{
debug_nothing_charstar,
debug_nothing_charstar,
- debug_nothing_void, /* early_finish */
+ debug_nothing_charstar, /* early_finish */
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
Index: gcc/debug.h
===================================================================
--- gcc/debug.h (revision 226966)
+++ gcc/debug.h (working copy)
@@ -31,7 +31,7 @@ struct gcc_debug_hooks
void (* finish) (const char *main_filename);
/* Run cleanups necessary after early debug generation. */
- void (* early_finish) (void);
+ void (* early_finish) (const char *main_filename);
/* Called from cgraph_optimize before starting to assemble
functions/variables/toplevel asms. */
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 226966)
+++ gcc/dwarf2out.c (working copy)
@@ -2420,7 +2420,7 @@ build_cfa_aligned_loc (dw_cfa_location *
static void dwarf2out_init (const char *);
static void dwarf2out_finish (const char *);
-static void dwarf2out_early_finish (void);
+static void dwarf2out_early_finish (const char *);
static void dwarf2out_assembly_start (void);
static void dwarf2out_define (unsigned int, const char *);
static void dwarf2out_undef (unsigned int, const char *);
@@ -2494,7 +2494,7 @@ const struct gcc_debug_hooks dwarf2_line
{
dwarf2out_init,
debug_nothing_charstar,
- debug_nothing_void,
+ debug_nothing_charstar,
debug_nothing_void,
debug_nothing_int_charstar,
debug_nothing_int_charstar,
@@ -25128,47 +25128,81 @@ optimize_location_lists (dw_die_ref die)
optimize_location_lists_1 (die, &htab);
}
\f
+/* Traverse the limbo die list, and add parent/child links. The only
+ dies without parents that should be here are concrete instances of
+ inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
+ For concrete instances, we can get the parent die from the abstract
+ instance. */
+
+static void
+flush_limbo_die_list (void)
+{
+ limbo_die_node *node, *next_node;
+
+ for (node = limbo_die_list; node; node = next_node)
+ {
+ dw_die_ref die = node->die;
+ next_node = node->next;
+
+ if (die->die_parent == NULL)
+ {
+ dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
+
+ if (origin && origin->die_parent)
+ add_child_die (origin->die_parent, die);
+ else if (is_cu_die (die))
+ ;
+ else if (seen_error ())
+ /* It's OK to be confused by errors in the input. */
+ add_child_die (comp_unit_die (), die);
+ else
+ {
+ /* In certain situations, the lexical block containing a
+ nested function can be optimized away, which results
+ in the nested function die being orphaned. Likewise
+ with the return type of that nested function. Force
+ this to be a child of the containing function.
+
+ It may happen that even the containing function got fully
+ inlined and optimized out. In that case we are lost and
+ assign the empty child. This should not be big issue as
+ the function is likely unreachable too. */
+ gcc_assert (node->created_for);
+
+ if (DECL_P (node->created_for))
+ origin = get_context_die (DECL_CONTEXT (node->created_for));
+ else if (TYPE_P (node->created_for))
+ origin = scope_die_for (node->created_for, comp_unit_die ());
+ else
+ origin = comp_unit_die ();
+
+ add_child_die (origin, die);
+ }
+ }
+ }
+
+ limbo_die_list = NULL;
+}
+
/* Output stuff that dwarf requires at the end of every file,
and generate the DWARF-2 debugging info. */
static void
-dwarf2out_finish (const char *filename)
+dwarf2out_finish (const char *)
{
comdat_type_node *ctnode;
dw_die_ref main_comp_unit_die;
/* Flush out any latecomers to the limbo party. */
- dwarf2out_early_finish ();
+ flush_limbo_die_list ();
- /* PCH might result in DW_AT_producer string being restored from the
- header compilation, so always fill it with empty string initially
- and overwrite only here. */
- dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
- producer_string = gen_producer_string ();
- producer->dw_attr_val.v.val_str->refcount--;
- producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
+ /* We shouldn't have any symbols with delayed asm names for
+ DIEs generated after early finish. */
+ gcc_assert (deferred_asm_name == NULL);
gen_scheduled_generic_parms_dies ();
gen_remaining_tmpl_value_param_die_attribute ();
- /* Add the name for the main input file now. We delayed this from
- dwarf2out_init to avoid complications with PCH.
- For LTO produced units use a fixed artificial name to avoid
- leaking tempfile names into the dwarf. */
- if (!in_lto_p)
- add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
- else
- add_name_attribute (comp_unit_die (), "<artificial>");
- if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
- add_comp_dir_attribute (comp_unit_die ());
- else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
- {
- bool p = false;
- file_table->traverse<bool *, file_table_relative_p> (&p);
- if (p)
- add_comp_dir_attribute (comp_unit_die ());
- }
-
#if ENABLE_ASSERT_CHECKING
{
dw_die_ref die = comp_unit_die (), c;
@@ -25482,9 +25516,9 @@ dwarf2out_finish (const char *filename)
has run. */
static void
-dwarf2out_early_finish (void)
+dwarf2out_early_finish (const char *filename)
{
- limbo_die_node *node, *next_node;
+ limbo_die_node *node;
/* Add DW_AT_linkage_name for all deferred DIEs. */
for (node = deferred_asm_name; node; node = node->next)
@@ -25502,57 +25536,35 @@ dwarf2out_early_finish (void)
}
deferred_asm_name = NULL;
- /* Traverse the limbo die list, and add parent/child links. The only
- dies without parents that should be here are concrete instances of
- inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
- For concrete instances, we can get the parent die from the abstract
- instance.
-
- The point here is to flush out the limbo list so that it is empty
+ /* The point here is to flush out the limbo list so that it is empty
and we don't need to stream it for LTO. */
- for (node = limbo_die_list; node; node = next_node)
- {
- dw_die_ref die = node->die;
- next_node = node->next;
-
- if (die->die_parent == NULL)
- {
- dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
-
- if (origin && origin->die_parent)
- add_child_die (origin->die_parent, die);
- else if (is_cu_die (die))
- ;
- else if (seen_error ())
- /* It's OK to be confused by errors in the input. */
- add_child_die (comp_unit_die (), die);
- else
- {
- /* In certain situations, the lexical block containing a
- nested function can be optimized away, which results
- in the nested function die being orphaned. Likewise
- with the return type of that nested function. Force
- this to be a child of the containing function.
+ flush_limbo_die_list ();
- It may happen that even the containing function got fully
- inlined and optimized out. In that case we are lost and
- assign the empty child. This should not be big issue as
- the function is likely unreachable too. */
- gcc_assert (node->created_for);
-
- if (DECL_P (node->created_for))
- origin = get_context_die (DECL_CONTEXT (node->created_for));
- else if (TYPE_P (node->created_for))
- origin = scope_die_for (node->created_for, comp_unit_die ());
- else
- origin = comp_unit_die ();
+ /* PCH might result in DW_AT_producer string being restored from the
+ header compilation, so always fill it with empty string initially
+ and overwrite only here. */
+ dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
+ producer_string = gen_producer_string ();
+ producer->dw_attr_val.v.val_str->refcount--;
+ producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
- add_child_die (origin, die);
- }
- }
+ /* Add the name for the main input file now. We delayed this from
+ dwarf2out_init to avoid complications with PCH.
+ For LTO produced units use a fixed artificial name to avoid
+ leaking tempfile names into the dwarf. */
+ if (!in_lto_p)
+ add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
+ else
+ add_name_attribute (comp_unit_die (), "<artificial>");
+ if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
+ add_comp_dir_attribute (comp_unit_die ());
+ else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
+ {
+ bool p = false;
+ file_table->traverse<bool *, file_table_relative_p> (&p);
+ if (p)
+ add_comp_dir_attribute (comp_unit_die ());
}
-
- limbo_die_list = NULL;
}
/* Reset all state within dwarf2out.c so that we can rerun the compiler
Index: gcc/sdbout.c
===================================================================
--- gcc/sdbout.c (revision 226966)
+++ gcc/sdbout.c (working copy)
@@ -278,7 +278,7 @@ const struct gcc_debug_hooks sdb_debug_h
{
sdbout_init, /* init */
sdbout_finish, /* finish */
- debug_nothing_void, /* early_finish */
+ debug_nothing_charstar, /* early_finish */
debug_nothing_void, /* assembly_start */
debug_nothing_int_charstar, /* define */
debug_nothing_int_charstar, /* undef */
Index: gcc/vmsdbgout.c
===================================================================
--- gcc/vmsdbgout.c (revision 226966)
+++ gcc/vmsdbgout.c (working copy)
@@ -147,6 +147,7 @@ static int write_srccorrs (int);
static void vmsdbgout_init (const char *);
static void vmsdbgout_finish (const char *);
+static void vmsdbgout_early_finish (const char *);
static void vmsdbgout_assembly_start (void);
static void vmsdbgout_define (unsigned int, const char *);
static void vmsdbgout_undef (unsigned int, const char *);
@@ -174,7 +175,7 @@ static void vmsdbgout_abstract_function
const struct gcc_debug_hooks vmsdbg_debug_hooks
= {vmsdbgout_init,
vmsdbgout_finish,
- debug_nothing_void,
+ vmsdbgout_early_finish,
vmsdbgout_assembly_start,
vmsdbgout_define,
vmsdbgout_undef,
@@ -1552,7 +1553,17 @@ vmsdbgout_abstract_function (tree decl)
VMS Debug debugging info. */
static void
-vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
+vmsdbgout_early_finish (const char *filename)
+{
+ if (write_symbols == VMS_AND_DWARF2_DEBUG)
+ (*dwarf2_debug_hooks.early_finish) (filename);
+}
+
+/* Output stuff that Debug requires at the end of every file and generate the
+ VMS Debug debugging info. */
+
+static void
+vmsdbgout_finish (const char *filename)
{
unsigned int i, ifunc;
int totsize;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-19 13:55 ` Richard Biener
@ 2015-08-19 13:57 ` Aldy Hernandez
2015-08-19 14:54 ` Pedro Alves
2015-08-20 9:31 ` Richard Biener
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Aldy Hernandez @ 2015-08-19 13:57 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, jason, gdb
On 08/19/2015 06:45 AM, Richard Biener wrote:
[copying gdb folks]
> On Tue, 18 Aug 2015, Aldy Hernandez wrote:
>
>> On 08/18/2015 07:20 AM, Richard Biener wrote:
[snip]
> The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu
> as well as gdb testing. Twice unpatched, twice patched - results seem
> to be somewhat unstable!? I even refrained from using any -j with
> make check-gdb... maybe it's just contrib/test_summary not coping well
> with gdb? any hints? Difference between unpatched run 1 & 2 is
> for example
>
> --- results.unpatched 2015-08-19 15:08:36.152899926 +0200
> +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200
> @@ -209,7 +209,6 @@
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3,
> fc4)
> FAIL: gdb.cp/inherit.exp: print g_vD
> FAIL: gdb.cp/inherit.exp: print g_vE
> FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)'
> @@ -238,6 +237,7 @@
> UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings
> FAIL: gdb.fortran/whatis_type.exp: run to MAIN__
> WARNING: remote_expect statement without a default case?!
> +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> @@ -362,12 +362,12 @@
> === gdb Summary ===
>
> -# of expected passes 30881
> +# of expected passes 30884
> # of unexpected failures 284
> # of unexpected successes 2
> -# of expected failures 85
> +# of expected failures 83
> # of unknown successes 2
> -# of known failures 60
> +# of known failures 59
> # of unresolved testcases 6
> # of untested testcases 32
> # of unsupported tests 165
>
> the sames changes randomly appear/disappear in the patched case.
> Otherwise patched/unpatched agree.
This is somewhat expected. Well, at least I never found a good
explanation. Some tests seemed to be thread related and inconsistent.
Others, I have no idea.
After running the tests enough times I got a feeling of which tests
would always pass, and use those as reference. It was confusing at
first. Perhaps the GDB folks could shed some light? I've found them very
helpful.
Also, -j made things worse. I never used it.
Aldy
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-19 13:57 ` Aldy Hernandez
@ 2015-08-19 14:54 ` Pedro Alves
0 siblings, 0 replies; 11+ messages in thread
From: Pedro Alves @ 2015-08-19 14:54 UTC (permalink / raw)
To: Aldy Hernandez, Richard Biener; +Cc: gcc-patches, jason, gdb
On 08/19/2015 02:55 PM, Aldy Hernandez wrote:
> On 08/19/2015 06:45 AM, Richard Biener wrote:
>
> [copying gdb folks]
Thanks.
>
>> On Tue, 18 Aug 2015, Aldy Hernandez wrote:
>>
>>> On 08/18/2015 07:20 AM, Richard Biener wrote:
>
> [snip]
>
>> The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu
>> as well as gdb testing. Twice unpatched, twice patched - results seem
>> to be somewhat unstable!? I even refrained from using any -j with
>> make check-gdb... maybe it's just contrib/test_summary not coping well
>> with gdb? any hints? Difference between unpatched run 1 & 2 is
>> for example
>>
>> --- results.unpatched 2015-08-19 15:08:36.152899926 +0200
>> +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200
>> @@ -209,7 +209,6 @@
>> WARNING: remote_expect statement without a default case?!
>> WARNING: remote_expect statement without a default case?!
>> WARNING: remote_expect statement without a default case?!
>> -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3,
>> fc4)
if {![target_info exists gdb,skip_float_tests]} {
gdb_test_stdio "print find_max_double(5,1.0,17.0,2.0,3.0,4.0)" \
"find_max\\(.*\\) returns 17\\.000000\[ \r\n\]+" \
".\[0-9\]+ = 17" \
"print find_max_double(5,1.0,17.0,2.0,3.0,4.0)"
}
# Test _Complex type here if supported.
if [support_complex_tests] {
global gdb_prompt
set test "print find_max_float_real(4, fc1, fc2, fc3, fc4)"
gdb_test $test ".*= 4 \\+ 4 \\* I" $test
>> FAIL: gdb.cp/inherit.exp: print g_vD
>> FAIL: gdb.cp/inherit.exp: print g_vE
>> FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)'
>> @@ -238,6 +237,7 @@
>> UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings
>> FAIL: gdb.fortran/whatis_type.exp: run to MAIN__
>> WARNING: remote_expect statement without a default case?!
>> +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt
# Prime the system
gdb_test_stdio "call complaint (&symfile_complaints, \"Register a complaint\")" \
"During symbol reading, Register a complaint."
# Check that the complaint was inserted and where
gdb_test "print symfile_complaints->root->fmt" \
".\[0-9\]+ =.*\"Register a complaint\""
So in both cases, there was a "gdb_test_stdio" test just before
the test that failed. gdb_test_stdio is new, and it expects output
from two different spawn ids simultaneously. Sounds like it still
needs fixing... I'll guess that Richard has a much faster machine than
my getting-old laptop, which exposes races that I didn't trip on...
> This is somewhat expected. Well, at least I never found a good
> explanation. Some tests seemed to be thread related and inconsistent.
> Others, I have no idea.
>
Indeed there are still some threading tests that unfortunately still
cause intermittent fails. We've been fixing them but it's a
slow process. Judging by the GDB build bots, x86_64 GNU/Linux
testing seems to be mostly stable though. There's one DejaGNU issue
that is consistently causing trouble -- see below.
> After running the tests enough times I got a feeling of which tests
> would always pass, and use those as reference. It was confusing at
> first. Perhaps the GDB folks could shed some light? I've found them very
> helpful.
>
> Also, -j made things worse. I never used it.
It gets much better if you use git master DejaGNU, to pick this up:
http://lists.gnu.org/archive/html/dejagnu/2015-07/msg00005.html
Thanks,
Pedro Alves
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-19 13:55 ` Richard Biener
2015-08-19 13:57 ` Aldy Hernandez
@ 2015-08-20 9:31 ` Richard Biener
2015-08-20 10:25 ` Richard Biener
2015-08-26 10:50 ` Richard Biener
3 siblings, 0 replies; 11+ messages in thread
From: Richard Biener @ 2015-08-20 9:31 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Wed, 19 Aug 2015, Richard Biener wrote:
> On Tue, 18 Aug 2015, Aldy Hernandez wrote:
>
> > On 08/18/2015 07:20 AM, Richard Biener wrote:
> > >
> > > This starts a series of patches (still in development) to refactor
> > > dwarf2out.c to better cope with early debug (and LTO debug).
> >
> > Awesome! Thanks.
> >
> > > Aldyh, what other testing did you usually do for changes? Run
> > > the gdb testsuite against the new compiler? Anything else?
> >
> > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> > though the latter is mostly useful while you iron out bugs initially. I found
> > that ultimately, the best test was C++.
>
> I see.
>
> > Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> > in object files to make sure things were within reason.
> >
> > > +
> > > +static void
> > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > > +{
> > > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > > + (*dwarf2_debug_hooks.early_finish) (filename);
> > > +}
> >
> > You can get rid of ATTRIBUTE_UNUSED now.
>
> Done. I've also refrained from moving
>
> gen_scheduled_generic_parms_dies ();
> gen_remaining_tmpl_value_param_die_attribute ();
>
> for now as that causes regressions I have to investigate.
Tricky beast ;) For g++.dg/debug/dwarf2/template-func-params-3.C
we run into the issue that when doing early dwarf the
rtl_for_decl_init (&bleh) call will fail because it ends up asking
15809 && ! walk_tree (&init, reference_to_unused, NULL, NULL)
which uses TREE_ASM_WRITTEN to see of 'bleh' was emitted or not.
That's not going to work at this stage - we even have no idea
whether 'bleh' is going to survive IPA or not (might be inlined).
With LTO it gets even tricker as we only see a subset of the whole
program (or original TU) at LTRANS stage.
So it somehow looks like late dwarf thing for this kind of
symbolic constants - but it _also_ looks like a very bad
dwarf representation to me (going through RTL is bad enough, heh).
We expect DW_OP_addr and a reference to _Z4blehv as follows:
.byte 0x3 # DW_OP_addr
.quad _Z4blehv
but I wonder if DWARF has something better so we can refer
to _Z4blehv by means of the DIE for its declaration (so the
debugger can resolve the constant value)? That would allow
the debugger to print &bleh even if bleh was optimized out
(it just would have to print <optimized out> for the actual
address).
So what I'll do is have two phases of
gen_remaining_tmpl_value_param_die_attribute
(gen_scheduled_generic_parms_dies doesn't have a similar issue
AFAICS), during early-debug add those we can, retaining those
we can only handle late (just checking the return value of
tree_add_const_value_attribute). For LTO the remaining ones
will be dropped on the floor (or we'd have to stream them
somehow) unless we can change the DWARF representation of
these symbolic constants.
Thanks,
Richard.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-19 13:55 ` Richard Biener
2015-08-19 13:57 ` Aldy Hernandez
2015-08-20 9:31 ` Richard Biener
@ 2015-08-20 10:25 ` Richard Biener
2015-08-20 10:32 ` Richard Biener
2015-08-26 10:50 ` Richard Biener
3 siblings, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-08-20 10:25 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Wed, 19 Aug 2015, Richard Biener wrote:
> On Tue, 18 Aug 2015, Aldy Hernandez wrote:
>
> > On 08/18/2015 07:20 AM, Richard Biener wrote:
> > >
> > > This starts a series of patches (still in development) to refactor
> > > dwarf2out.c to better cope with early debug (and LTO debug).
> >
> > Awesome! Thanks.
> >
> > > Aldyh, what other testing did you usually do for changes? Run
> > > the gdb testsuite against the new compiler? Anything else?
> >
> > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> > though the latter is mostly useful while you iron out bugs initially. I found
> > that ultimately, the best test was C++.
>
> I see.
>
> > Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> > in object files to make sure things were within reason.
> >
> > > +
> > > +static void
> > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > > +{
> > > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > > + (*dwarf2_debug_hooks.early_finish) (filename);
> > > +}
> >
> > You can get rid of ATTRIBUTE_UNUSED now.
>
> Done. I've also refrained from moving
>
> gen_scheduled_generic_parms_dies ();
> gen_remaining_tmpl_value_param_die_attribute ();
>
> for now as that causes regressions I have to investigate.
So I thought gen_scheduled_generic_parms_dies was fine but it exposes
a hole in
/* Generate early debug for global variables. Any local variables will
be handled by either handling reachable functions from
finalize_compilation_unit (and by consequence, locally scoped
symbols), or by rest_of_type_compilation below.
...
&& !decl_type_context (decl))
(*debug_hooks->early_global_decl) (decl);
for __timepunct_cache::_S_timezones where through the
rest_of_type_compilation we quickly finish processing __timepunct_cache
as it is TYPE_DECL_SUPPRESS_DEBUG (so ->type_decl exits w/o doing
anything). So we fail to generate a type DIE for the global which
causes us, at late_global_decl time (we do output this global var)
ends up doing
#12 0x0000000000b831f1 in gen_decl_die (decl=0x7ffff5650a20, origin=0x0,
context_die=0x7ffff62ab000)
at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:21535
21532 /* And its containing type. */
21533 class_origin = decl_class_context (decl_or_origin);
21534 if (class_origin != NULL_TREE)
21535 gen_type_die_for_member (class_origin, decl_or_origin,
context_die);
and thus create the type DIE for __timepunct_cache late.
This is a hole in current early-debug. IMHO we should force
early_global_decl even for globals in decl_type_context ()
or at least for a type DIE to be created for TYPE_DECL_SUPPRESS_DEBUG
type decls.
Jason, any advice on this? I note
/* In a TYPE_DECL nonzero means the detail info about this type is not
dumped
into stabs. Instead it will generate cross reference ('x') of names.
This uses the same flag as DECL_EXTERNAL. */
#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
(TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1)
refering to STABS and "This uses the same flag as DECL_EXTERNAL" so
maybe this is just bad co-incidence? DECL_EXTERNAL doesn't check
it operates on a non-TYPE_DECL.
So without knowing that the flag is supposed to be doing in DWARF
(also the desired effect on any of its static members) I can only
suggest we maybe do not want any debug info for
__timepunct_cache::_S_timezones at all?
Thanks,
Richard.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-20 10:25 ` Richard Biener
@ 2015-08-20 10:32 ` Richard Biener
2015-08-21 13:46 ` Richard Biener
0 siblings, 1 reply; 11+ messages in thread
From: Richard Biener @ 2015-08-20 10:32 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Thu, 20 Aug 2015, Richard Biener wrote:
> On Wed, 19 Aug 2015, Richard Biener wrote:
>
> > On Tue, 18 Aug 2015, Aldy Hernandez wrote:
> >
> > > On 08/18/2015 07:20 AM, Richard Biener wrote:
> > > >
> > > > This starts a series of patches (still in development) to refactor
> > > > dwarf2out.c to better cope with early debug (and LTO debug).
> > >
> > > Awesome! Thanks.
> > >
> > > > Aldyh, what other testing did you usually do for changes? Run
> > > > the gdb testsuite against the new compiler? Anything else?
> > >
> > > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> > > though the latter is mostly useful while you iron out bugs initially. I found
> > > that ultimately, the best test was C++.
> >
> > I see.
> >
> > > Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> > > in object files to make sure things were within reason.
> > >
> > > > +
> > > > +static void
> > > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > > > +{
> > > > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > > > + (*dwarf2_debug_hooks.early_finish) (filename);
> > > > +}
> > >
> > > You can get rid of ATTRIBUTE_UNUSED now.
> >
> > Done. I've also refrained from moving
> >
> > gen_scheduled_generic_parms_dies ();
> > gen_remaining_tmpl_value_param_die_attribute ();
> >
> > for now as that causes regressions I have to investigate.
>
> So I thought gen_scheduled_generic_parms_dies was fine but it exposes
> a hole in
>
> /* Generate early debug for global variables. Any local variables will
> be handled by either handling reachable functions from
> finalize_compilation_unit (and by consequence, locally scoped
> symbols), or by rest_of_type_compilation below.
> ...
> && !decl_type_context (decl))
> (*debug_hooks->early_global_decl) (decl);
>
> for __timepunct_cache::_S_timezones where through the
> rest_of_type_compilation we quickly finish processing __timepunct_cache
> as it is TYPE_DECL_SUPPRESS_DEBUG (so ->type_decl exits w/o doing
> anything). So we fail to generate a type DIE for the global which
> causes us, at late_global_decl time (we do output this global var)
> ends up doing
>
> #12 0x0000000000b831f1 in gen_decl_die (decl=0x7ffff5650a20, origin=0x0,
> context_die=0x7ffff62ab000)
> at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:21535
> 21532 /* And its containing type. */
> 21533 class_origin = decl_class_context (decl_or_origin);
> 21534 if (class_origin != NULL_TREE)
> 21535 gen_type_die_for_member (class_origin, decl_or_origin,
> context_die);
>
> and thus create the type DIE for __timepunct_cache late.
>
> This is a hole in current early-debug. IMHO we should force
> early_global_decl even for globals in decl_type_context ()
> or at least for a type DIE to be created for TYPE_DECL_SUPPRESS_DEBUG
> type decls.
>
> Jason, any advice on this? I note
>
> /* In a TYPE_DECL nonzero means the detail info about this type is not
> dumped
> into stabs. Instead it will generate cross reference ('x') of names.
> This uses the same flag as DECL_EXTERNAL. */
> #define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
> (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1)
>
> refering to STABS and "This uses the same flag as DECL_EXTERNAL" so
> maybe this is just bad co-incidence? DECL_EXTERNAL doesn't check
> it operates on a non-TYPE_DECL.
>
> So without knowing that the flag is supposed to be doing in DWARF
> (also the desired effect on any of its static members) I can only
> suggest we maybe do not want any debug info for
> __timepunct_cache::_S_timezones at all?
Sorry to followup myself all the time ;) The following seems to
"work" for me here:
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 226937)
+++ gcc/dwarf2out.c (working copy)
@@ -21647,7 +21652,8 @@ dwarf2out_late_global_decl (tree decl)
Skip over functions because they were handled by the
debug_hooks->function_decl() call in rest_of_handle_final. */
if ((TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
- && !POINTER_BOUNDS_P (decl))
+ && !POINTER_BOUNDS_P (decl)
+ && lookup_decl_die (decl) != NULL)
dwarf2out_decl (decl);
}
which basically means only annotate gloabl decls late if we
created a DIE for it early.
Kind-of makes sense. Going to test that more extensively separately.
Richard.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-20 10:32 ` Richard Biener
@ 2015-08-21 13:46 ` Richard Biener
0 siblings, 0 replies; 11+ messages in thread
From: Richard Biener @ 2015-08-21 13:46 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Thu, 20 Aug 2015, Richard Biener wrote:
> On Thu, 20 Aug 2015, Richard Biener wrote:
>
> > On Wed, 19 Aug 2015, Richard Biener wrote:
> >
> > > On Tue, 18 Aug 2015, Aldy Hernandez wrote:
> > >
> > > > On 08/18/2015 07:20 AM, Richard Biener wrote:
> > > > >
> > > > > This starts a series of patches (still in development) to refactor
> > > > > dwarf2out.c to better cope with early debug (and LTO debug).
> > > >
> > > > Awesome! Thanks.
> > > >
> > > > > Aldyh, what other testing did you usually do for changes? Run
> > > > > the gdb testsuite against the new compiler? Anything else?
> > > >
> > > > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> > > > though the latter is mostly useful while you iron out bugs initially. I found
> > > > that ultimately, the best test was C++.
> > >
> > > I see.
> > >
> > > > Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> > > > in object files to make sure things were within reason.
> > > >
> > > > > +
> > > > > +static void
> > > > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > > > > +{
> > > > > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > > > > + (*dwarf2_debug_hooks.early_finish) (filename);
> > > > > +}
> > > >
> > > > You can get rid of ATTRIBUTE_UNUSED now.
> > >
> > > Done. I've also refrained from moving
> > >
> > > gen_scheduled_generic_parms_dies ();
> > > gen_remaining_tmpl_value_param_die_attribute ();
> > >
> > > for now as that causes regressions I have to investigate.
> >
> > So I thought gen_scheduled_generic_parms_dies was fine but it exposes
> > a hole in
> >
> > /* Generate early debug for global variables. Any local variables will
> > be handled by either handling reachable functions from
> > finalize_compilation_unit (and by consequence, locally scoped
> > symbols), or by rest_of_type_compilation below.
> > ...
> > && !decl_type_context (decl))
> > (*debug_hooks->early_global_decl) (decl);
> >
> > for __timepunct_cache::_S_timezones where through the
> > rest_of_type_compilation we quickly finish processing __timepunct_cache
> > as it is TYPE_DECL_SUPPRESS_DEBUG (so ->type_decl exits w/o doing
> > anything). So we fail to generate a type DIE for the global which
> > causes us, at late_global_decl time (we do output this global var)
> > ends up doing
> >
> > #12 0x0000000000b831f1 in gen_decl_die (decl=0x7ffff5650a20, origin=0x0,
> > context_die=0x7ffff62ab000)
> > at /space/rguenther/src/svn/trunk/gcc/dwarf2out.c:21535
> > 21532 /* And its containing type. */
> > 21533 class_origin = decl_class_context (decl_or_origin);
> > 21534 if (class_origin != NULL_TREE)
> > 21535 gen_type_die_for_member (class_origin, decl_or_origin,
> > context_die);
> >
> > and thus create the type DIE for __timepunct_cache late.
> >
> > This is a hole in current early-debug. IMHO we should force
> > early_global_decl even for globals in decl_type_context ()
> > or at least for a type DIE to be created for TYPE_DECL_SUPPRESS_DEBUG
> > type decls.
> >
> > Jason, any advice on this? I note
> >
> > /* In a TYPE_DECL nonzero means the detail info about this type is not
> > dumped
> > into stabs. Instead it will generate cross reference ('x') of names.
> > This uses the same flag as DECL_EXTERNAL. */
> > #define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
> > (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1)
> >
> > refering to STABS and "This uses the same flag as DECL_EXTERNAL" so
> > maybe this is just bad co-incidence? DECL_EXTERNAL doesn't check
> > it operates on a non-TYPE_DECL.
> >
> > So without knowing that the flag is supposed to be doing in DWARF
> > (also the desired effect on any of its static members) I can only
> > suggest we maybe do not want any debug info for
> > __timepunct_cache::_S_timezones at all?
>
> Sorry to followup myself all the time ;) The following seems to
> "work" for me here:
>
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c (revision 226937)
> +++ gcc/dwarf2out.c (working copy)
> @@ -21647,7 +21652,8 @@ dwarf2out_late_global_decl (tree decl)
> Skip over functions because they were handled by the
> debug_hooks->function_decl() call in rest_of_handle_final. */
> if ((TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
> - && !POINTER_BOUNDS_P (decl))
> + && !POINTER_BOUNDS_P (decl)
> + && lookup_decl_die (decl) != NULL)
> dwarf2out_decl (decl);
> }
>
> which basically means only annotate gloabl decls late if we
> created a DIE for it early.
>
> Kind-of makes sense. Going to test that more extensively separately.
So the following passes bootstrap & test & gdb test on
x86_64-unknown-linux-gnu. But it breaks old-style LTO (obviously).
I'm at the moment trying to refactor dwarf2out_function_decl in a
similar way to avoid adding another different entry-kind to
gen_subprogram_die and friends (late LTO).
Richard.
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 226966)
+++ gcc/dwarf2out.c (working copy)
@@ -21641,14 +21641,16 @@ dwarf2out_early_global_decl (tree decl)
static void
dwarf2out_late_global_decl (tree decl)
{
- /* Output any global decls we missed or fill-in any location
- information we were unable to determine on the first pass.
-
- Skip over functions because they were handled by the
- debug_hooks->function_decl() call in rest_of_handle_final. */
- if ((TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
+ /* Fill-in any location information we were unable to determine
+ on the first pass. */
+ if (TREE_CODE (decl) == VAR_DECL
&& !POINTER_BOUNDS_P (decl))
- dwarf2out_decl (decl);
+ {
+ dw_die_ref die = lookup_decl_die (decl);
+ if (die)
+ add_location_or_const_value_attribute (die, decl, false,
+ DW_AT_location);
+ }
}
/* Output debug information for type decl DECL. Called from toplev.c
Index: gcc/passes.c
===================================================================
--- gcc/passes.c (revision 226966)
+++ gcc/passes.c (working copy)
@@ -318,7 +318,15 @@ rest_of_decl_compilation (tree decl,
&& !decl_function_context (decl)
&& !current_function_decl
&& DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
- && !decl_type_context (decl))
+ && (!decl_type_context (decl)
+ /* If we created a varpool node for the decl make sure to
+ call early_global_decl. Otherwise we miss changes
+ introduced by member definitions like
+ struct A { static int staticdatamember; };
+ int A::staticdatamember;
+ and thus have incomplete early debug. */
+ || (TREE_CODE (decl) == VAR_DECL
+ && TREE_STATIC (decl) && !DECL_EXTERNAL (decl))))
(*debug_hooks->early_global_decl) (decl);
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][1/n] dwarf2out refactoring for early (LTO) debug
2015-08-19 13:55 ` Richard Biener
` (2 preceding siblings ...)
2015-08-20 10:25 ` Richard Biener
@ 2015-08-26 10:50 ` Richard Biener
3 siblings, 0 replies; 11+ messages in thread
From: Richard Biener @ 2015-08-26 10:50 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, jason
On Wed, 19 Aug 2015, Richard Biener wrote:
> On Tue, 18 Aug 2015, Aldy Hernandez wrote:
>
> > On 08/18/2015 07:20 AM, Richard Biener wrote:
> > >
> > > This starts a series of patches (still in development) to refactor
> > > dwarf2out.c to better cope with early debug (and LTO debug).
> >
> > Awesome! Thanks.
> >
> > > Aldyh, what other testing did you usually do for changes? Run
> > > the gdb testsuite against the new compiler? Anything else?
> >
> > gdb testsuite, and make sure you test GCC with --enable-languages=all,go,ada,
> > though the latter is mostly useful while you iron out bugs initially. I found
> > that ultimately, the best test was C++.
>
> I see.
>
> > Pre merge I also bootstrapped the compiler and compared .debug* section sizes
> > in object files to make sure things were within reason.
> >
> > > +
> > > +static void
> > > +vmsdbgout_early_finish (const char *filename ATTRIBUTE_UNUSED)
> > > +{
> > > + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> > > + (*dwarf2_debug_hooks.early_finish) (filename);
> > > +}
> >
> > You can get rid of ATTRIBUTE_UNUSED now.
>
> Done. I've also refrained from moving
>
> gen_scheduled_generic_parms_dies ();
> gen_remaining_tmpl_value_param_die_attribute ();
>
> for now as that causes regressions I have to investigate.
>
> The patch below has passed bootstrap & regtest on x86_64-unknown-linux-gnu
> as well as gdb testing. Twice unpatched, twice patched - results seem
> to be somewhat unstable!? I even refrained from using any -j with
> make check-gdb... maybe it's just contrib/test_summary not coping well
> with gdb? any hints? Difference between unpatched run 1 & 2 is
> for example
>
> --- results.unpatched 2015-08-19 15:08:36.152899926 +0200
> +++ results.unpatched2 2015-08-19 15:29:46.902060797 +0200
> @@ -209,7 +209,6 @@
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> -FAIL: gdb.base/varargs.exp: print find_max_float_real(4, fc1, fc2, fc3,
> fc4)
> FAIL: gdb.cp/inherit.exp: print g_vD
> FAIL: gdb.cp/inherit.exp: print g_vE
> FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f(std::string)'
> @@ -238,6 +237,7 @@
> UNRESOLVED: gdb.fortran/types.exp: set print sevenbit-strings
> FAIL: gdb.fortran/whatis_type.exp: run to MAIN__
> WARNING: remote_expect statement without a default case?!
> +FAIL: gdb.gdb/complaints.exp: print symfile_complaints->root->fmt
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> WARNING: remote_expect statement without a default case?!
> @@ -362,12 +362,12 @@
> === gdb Summary ===
>
> -# of expected passes 30881
> +# of expected passes 30884
> # of unexpected failures 284
> # of unexpected successes 2
> -# of expected failures 85
> +# of expected failures 83
> # of unknown successes 2
> -# of known failures 60
> +# of known failures 59
> # of unresolved testcases 6
> # of untested testcases 32
> # of unsupported tests 165
>
> the sames changes randomly appear/disappear in the patched case.
> Otherwise patched/unpatched agree.
>
> Ok?
Jason, are you willing to review these refactoring patches or can
I invoke my middle-end maintainer powers to remove some of this noise
from the LTO parts?
Thanks,
Richard.
> Thanks,
> Richard.
>
> 2015-08-18 Richard Biener <rguenther@suse.de>
>
> * debug.h (gcc_debug_hooks::early_finish): Add filename argument.
> * dbxout.c (dbx_debug_hooks): Adjust.
> * debug.c (do_nothing_hooks): Likewise.
> * sdbout.c (sdb_debug_hooks): Likewise.
> * vmsdbgout.c (vmsdbgout_early_finish): New function dispatching
> to dwarf2out variant if needed.
> (vmsdbg_debug_hooks): Adjust.
> * dwarf2out.c (dwarf2_line_hooks): Adjust.
> (flush_limbo_die_list): New function.
> (dwarf2out_finish): Call flush_limbo_die_list instead of
> dwarf2out_early_finish. Assert there are no deferred asm-names.
> Move early stuff ...
> (dwarf2out_early_finish): ... here.
> * cgraphunit.c (symbol_table::finalize_compilation_unit):
> Call early_finish with main_input_filename argument.
>
>
> Index: gcc/cgraphunit.c
> ===================================================================
> --- gcc/cgraphunit.c (revision 226966)
> +++ gcc/cgraphunit.c (working copy)
> @@ -2490,7 +2490,7 @@ symbol_table::finalize_compilation_unit
>
> /* Clean up anything that needs cleaning up after initial debug
> generation. */
> - (*debug_hooks->early_finish) ();
> + (*debug_hooks->early_finish) (main_input_filename);
>
> /* Finally drive the pass manager. */
> compile ();
> Index: gcc/dbxout.c
> ===================================================================
> --- gcc/dbxout.c (revision 226966)
> +++ gcc/dbxout.c (working copy)
> @@ -354,7 +354,7 @@ const struct gcc_debug_hooks dbx_debug_h
> {
> dbxout_init,
> dbxout_finish,
> - debug_nothing_void,
> + debug_nothing_charstar,
> debug_nothing_void,
> debug_nothing_int_charstar,
> debug_nothing_int_charstar,
> Index: gcc/debug.c
> ===================================================================
> --- gcc/debug.c (revision 226966)
> +++ gcc/debug.c (working copy)
> @@ -28,7 +28,7 @@ const struct gcc_debug_hooks do_nothing_
> {
> debug_nothing_charstar,
> debug_nothing_charstar,
> - debug_nothing_void, /* early_finish */
> + debug_nothing_charstar, /* early_finish */
> debug_nothing_void,
> debug_nothing_int_charstar,
> debug_nothing_int_charstar,
> Index: gcc/debug.h
> ===================================================================
> --- gcc/debug.h (revision 226966)
> +++ gcc/debug.h (working copy)
> @@ -31,7 +31,7 @@ struct gcc_debug_hooks
> void (* finish) (const char *main_filename);
>
> /* Run cleanups necessary after early debug generation. */
> - void (* early_finish) (void);
> + void (* early_finish) (const char *main_filename);
>
> /* Called from cgraph_optimize before starting to assemble
> functions/variables/toplevel asms. */
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c (revision 226966)
> +++ gcc/dwarf2out.c (working copy)
> @@ -2420,7 +2420,7 @@ build_cfa_aligned_loc (dw_cfa_location *
>
> static void dwarf2out_init (const char *);
> static void dwarf2out_finish (const char *);
> -static void dwarf2out_early_finish (void);
> +static void dwarf2out_early_finish (const char *);
> static void dwarf2out_assembly_start (void);
> static void dwarf2out_define (unsigned int, const char *);
> static void dwarf2out_undef (unsigned int, const char *);
> @@ -2494,7 +2494,7 @@ const struct gcc_debug_hooks dwarf2_line
> {
> dwarf2out_init,
> debug_nothing_charstar,
> - debug_nothing_void,
> + debug_nothing_charstar,
> debug_nothing_void,
> debug_nothing_int_charstar,
> debug_nothing_int_charstar,
> @@ -25128,47 +25128,81 @@ optimize_location_lists (dw_die_ref die)
> optimize_location_lists_1 (die, &htab);
> }
> \f
> +/* Traverse the limbo die list, and add parent/child links. The only
> + dies without parents that should be here are concrete instances of
> + inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
> + For concrete instances, we can get the parent die from the abstract
> + instance. */
> +
> +static void
> +flush_limbo_die_list (void)
> +{
> + limbo_die_node *node, *next_node;
> +
> + for (node = limbo_die_list; node; node = next_node)
> + {
> + dw_die_ref die = node->die;
> + next_node = node->next;
> +
> + if (die->die_parent == NULL)
> + {
> + dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
> +
> + if (origin && origin->die_parent)
> + add_child_die (origin->die_parent, die);
> + else if (is_cu_die (die))
> + ;
> + else if (seen_error ())
> + /* It's OK to be confused by errors in the input. */
> + add_child_die (comp_unit_die (), die);
> + else
> + {
> + /* In certain situations, the lexical block containing a
> + nested function can be optimized away, which results
> + in the nested function die being orphaned. Likewise
> + with the return type of that nested function. Force
> + this to be a child of the containing function.
> +
> + It may happen that even the containing function got fully
> + inlined and optimized out. In that case we are lost and
> + assign the empty child. This should not be big issue as
> + the function is likely unreachable too. */
> + gcc_assert (node->created_for);
> +
> + if (DECL_P (node->created_for))
> + origin = get_context_die (DECL_CONTEXT (node->created_for));
> + else if (TYPE_P (node->created_for))
> + origin = scope_die_for (node->created_for, comp_unit_die ());
> + else
> + origin = comp_unit_die ();
> +
> + add_child_die (origin, die);
> + }
> + }
> + }
> +
> + limbo_die_list = NULL;
> +}
> +
> /* Output stuff that dwarf requires at the end of every file,
> and generate the DWARF-2 debugging info. */
>
> static void
> -dwarf2out_finish (const char *filename)
> +dwarf2out_finish (const char *)
> {
> comdat_type_node *ctnode;
> dw_die_ref main_comp_unit_die;
>
> /* Flush out any latecomers to the limbo party. */
> - dwarf2out_early_finish ();
> + flush_limbo_die_list ();
>
> - /* PCH might result in DW_AT_producer string being restored from the
> - header compilation, so always fill it with empty string initially
> - and overwrite only here. */
> - dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
> - producer_string = gen_producer_string ();
> - producer->dw_attr_val.v.val_str->refcount--;
> - producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
> + /* We shouldn't have any symbols with delayed asm names for
> + DIEs generated after early finish. */
> + gcc_assert (deferred_asm_name == NULL);
>
> gen_scheduled_generic_parms_dies ();
> gen_remaining_tmpl_value_param_die_attribute ();
>
> - /* Add the name for the main input file now. We delayed this from
> - dwarf2out_init to avoid complications with PCH.
> - For LTO produced units use a fixed artificial name to avoid
> - leaking tempfile names into the dwarf. */
> - if (!in_lto_p)
> - add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
> - else
> - add_name_attribute (comp_unit_die (), "<artificial>");
> - if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
> - add_comp_dir_attribute (comp_unit_die ());
> - else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
> - {
> - bool p = false;
> - file_table->traverse<bool *, file_table_relative_p> (&p);
> - if (p)
> - add_comp_dir_attribute (comp_unit_die ());
> - }
> -
> #if ENABLE_ASSERT_CHECKING
> {
> dw_die_ref die = comp_unit_die (), c;
> @@ -25482,9 +25516,9 @@ dwarf2out_finish (const char *filename)
> has run. */
>
> static void
> -dwarf2out_early_finish (void)
> +dwarf2out_early_finish (const char *filename)
> {
> - limbo_die_node *node, *next_node;
> + limbo_die_node *node;
>
> /* Add DW_AT_linkage_name for all deferred DIEs. */
> for (node = deferred_asm_name; node; node = node->next)
> @@ -25502,57 +25536,35 @@ dwarf2out_early_finish (void)
> }
> deferred_asm_name = NULL;
>
> - /* Traverse the limbo die list, and add parent/child links. The only
> - dies without parents that should be here are concrete instances of
> - inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
> - For concrete instances, we can get the parent die from the abstract
> - instance.
> -
> - The point here is to flush out the limbo list so that it is empty
> + /* The point here is to flush out the limbo list so that it is empty
> and we don't need to stream it for LTO. */
> - for (node = limbo_die_list; node; node = next_node)
> - {
> - dw_die_ref die = node->die;
> - next_node = node->next;
> -
> - if (die->die_parent == NULL)
> - {
> - dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);
> -
> - if (origin && origin->die_parent)
> - add_child_die (origin->die_parent, die);
> - else if (is_cu_die (die))
> - ;
> - else if (seen_error ())
> - /* It's OK to be confused by errors in the input. */
> - add_child_die (comp_unit_die (), die);
> - else
> - {
> - /* In certain situations, the lexical block containing a
> - nested function can be optimized away, which results
> - in the nested function die being orphaned. Likewise
> - with the return type of that nested function. Force
> - this to be a child of the containing function.
> + flush_limbo_die_list ();
>
> - It may happen that even the containing function got fully
> - inlined and optimized out. In that case we are lost and
> - assign the empty child. This should not be big issue as
> - the function is likely unreachable too. */
> - gcc_assert (node->created_for);
> -
> - if (DECL_P (node->created_for))
> - origin = get_context_die (DECL_CONTEXT (node->created_for));
> - else if (TYPE_P (node->created_for))
> - origin = scope_die_for (node->created_for, comp_unit_die ());
> - else
> - origin = comp_unit_die ();
> + /* PCH might result in DW_AT_producer string being restored from the
> + header compilation, so always fill it with empty string initially
> + and overwrite only here. */
> + dw_attr_ref producer = get_AT (comp_unit_die (), DW_AT_producer);
> + producer_string = gen_producer_string ();
> + producer->dw_attr_val.v.val_str->refcount--;
> + producer->dw_attr_val.v.val_str = find_AT_string (producer_string);
>
> - add_child_die (origin, die);
> - }
> - }
> + /* Add the name for the main input file now. We delayed this from
> + dwarf2out_init to avoid complications with PCH.
> + For LTO produced units use a fixed artificial name to avoid
> + leaking tempfile names into the dwarf. */
> + if (!in_lto_p)
> + add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
> + else
> + add_name_attribute (comp_unit_die (), "<artificial>");
> + if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
> + add_comp_dir_attribute (comp_unit_die ());
> + else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
> + {
> + bool p = false;
> + file_table->traverse<bool *, file_table_relative_p> (&p);
> + if (p)
> + add_comp_dir_attribute (comp_unit_die ());
> }
> -
> - limbo_die_list = NULL;
> }
>
> /* Reset all state within dwarf2out.c so that we can rerun the compiler
> Index: gcc/sdbout.c
> ===================================================================
> --- gcc/sdbout.c (revision 226966)
> +++ gcc/sdbout.c (working copy)
> @@ -278,7 +278,7 @@ const struct gcc_debug_hooks sdb_debug_h
> {
> sdbout_init, /* init */
> sdbout_finish, /* finish */
> - debug_nothing_void, /* early_finish */
> + debug_nothing_charstar, /* early_finish */
> debug_nothing_void, /* assembly_start */
> debug_nothing_int_charstar, /* define */
> debug_nothing_int_charstar, /* undef */
> Index: gcc/vmsdbgout.c
> ===================================================================
> --- gcc/vmsdbgout.c (revision 226966)
> +++ gcc/vmsdbgout.c (working copy)
> @@ -147,6 +147,7 @@ static int write_srccorrs (int);
>
> static void vmsdbgout_init (const char *);
> static void vmsdbgout_finish (const char *);
> +static void vmsdbgout_early_finish (const char *);
> static void vmsdbgout_assembly_start (void);
> static void vmsdbgout_define (unsigned int, const char *);
> static void vmsdbgout_undef (unsigned int, const char *);
> @@ -174,7 +175,7 @@ static void vmsdbgout_abstract_function
> const struct gcc_debug_hooks vmsdbg_debug_hooks
> = {vmsdbgout_init,
> vmsdbgout_finish,
> - debug_nothing_void,
> + vmsdbgout_early_finish,
> vmsdbgout_assembly_start,
> vmsdbgout_define,
> vmsdbgout_undef,
> @@ -1552,7 +1553,17 @@ vmsdbgout_abstract_function (tree decl)
> VMS Debug debugging info. */
>
> static void
> -vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
> +vmsdbgout_early_finish (const char *filename)
> +{
> + if (write_symbols == VMS_AND_DWARF2_DEBUG)
> + (*dwarf2_debug_hooks.early_finish) (filename);
> +}
> +
> +/* Output stuff that Debug requires at the end of every file and generate the
> + VMS Debug debugging info. */
> +
> +static void
> +vmsdbgout_finish (const char *filename)
> {
> unsigned int i, ifunc;
> int totsize;
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-08-26 10:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-18 14:42 [PATCH][1/n] dwarf2out refactoring for early (LTO) debug Richard Biener
2015-08-18 19:48 ` Aldy Hernandez
2015-08-19 9:36 ` Yao Qi
2015-08-19 13:55 ` Richard Biener
2015-08-19 13:57 ` Aldy Hernandez
2015-08-19 14:54 ` Pedro Alves
2015-08-20 9:31 ` Richard Biener
2015-08-20 10:25 ` Richard Biener
2015-08-20 10:32 ` Richard Biener
2015-08-21 13:46 ` Richard Biener
2015-08-26 10:50 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).