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);
}