Message ID | 542C72A9.9090602@redhat.com |
---|---|
State | New |
Headers | show |
On 10/01/2014 05:31 PM, Aldy Hernandez wrote: > + for (tree t = level->names; t; t = TREE_CHAIN(t)) > + if (TREE_CODE (t) != TYPE_DECL > + && TREE_CODE (t) != PARM_DECL > + && !DECL_IS_BUILTIN (t)) > + debug_hooks->early_global_decl (t); What does this do for templates? I think we don't want to send a template off to early_global_decl, but rather walk through its specializations and emit them. Why do you need to check for PARM_DECL? There shouldn't be any PARM_DECL at namespace scope. Why do you want to skip TYPE_DECL? I think we should leave the decision about whether to emit a typedef to the debugging back end. Jason
On 10/02/14 08:46, Jason Merrill wrote: > On 10/01/2014 05:31 PM, Aldy Hernandez wrote: >> + for (tree t = level->names; t; t = TREE_CHAIN(t)) >> + if (TREE_CODE (t) != TYPE_DECL >> + && TREE_CODE (t) != PARM_DECL >> + && !DECL_IS_BUILTIN (t)) >> + debug_hooks->early_global_decl (t); > > What does this do for templates? I think we don't want to send a > template off to early_global_decl, but rather walk through its > specializations and emit them. Hmm, I'll look into this. > Why do you need to check for PARM_DECL? There shouldn't be any > PARM_DECL at namespace scope. > > Why do you want to skip TYPE_DECL? I think we should leave the decision > about whether to emit a typedef to the debugging back end. Actually, I think we/I need to rethink this whole globals thing. Currently we're early dumping global *_DECLs, and hoping dwarf2out recursion will also pick up types and any derivatives from the *_DECLs, but taking a closer look I've noticed a lot of things are not being dumped early. For instance: foo() { typedef int ITYPE; ITYPE var = 5; } For the above code, var's DIE gets outputted _after_ the compilation proper has been run here: if (! declaration && outer_scope && TREE_CODE (outer_scope) != ERROR_MARK && (!DECL_STRUCT_FUNCTION (decl) || DECL_STRUCT_FUNCTION (decl)->gimple_df)) ... ... decls_for_scope (outer_scope, subr_die, 0); I think we should be outputting DIEs for locals at the end of parsing, so my patch going through level->names IMO is wrong. We should be dumping all *_DECLs created by the FE, not just globally scoped ones. This means that we'll need to clean up unreachable/unused DIEs after the flow graph has been built. Another example currently not being dumped early is... function() { class Local { public: void loc_foo (void) { } }; Local l; l.loc_foo (); } ...since loc_foo() is not in level->names. Again, this seems like an argument for early dumping all *_DECLs directly from rest_of_decl_compilation() (as you've hinted) and then cleaning up unused DIEs after we have flow information. Does this seem reasonable? Aldy
On October 2, 2014 8:21:51 PM CEST, Aldy Hernandez <aldyh@redhat.com> wrote: >On 10/02/14 08:46, Jason Merrill wrote: >> On 10/01/2014 05:31 PM, Aldy Hernandez wrote: >>> + for (tree t = level->names; t; t = TREE_CHAIN(t)) >>> + if (TREE_CODE (t) != TYPE_DECL >>> + && TREE_CODE (t) != PARM_DECL >>> + && !DECL_IS_BUILTIN (t)) >>> + debug_hooks->early_global_decl (t); >> >> What does this do for templates? I think we don't want to send a >> template off to early_global_decl, but rather walk through its >> specializations and emit them. > >Hmm, I'll look into this. > >> Why do you need to check for PARM_DECL? There shouldn't be any >> PARM_DECL at namespace scope. >> >> Why do you want to skip TYPE_DECL? I think we should leave the >decision >> about whether to emit a typedef to the debugging back end. > >Actually, I think we/I need to rethink this whole globals thing. >Currently we're early dumping global *_DECLs, and hoping dwarf2out >recursion will also pick up types and any derivatives from the *_DECLs, > >but taking a closer look I've noticed a lot of things are not being >dumped early. > >For instance: > > > foo() > { > typedef int ITYPE; > ITYPE var = 5; > } > >For the above code, var's DIE gets outputted _after_ the compilation >proper has been run here: > >if (! declaration && outer_scope && TREE_CODE (outer_scope) != >ERROR_MARK > && (!DECL_STRUCT_FUNCTION (decl) > || DECL_STRUCT_FUNCTION (decl)->gimple_df)) > ... > ... > decls_for_scope (outer_scope, subr_die, 0); > >I think we should be outputting DIEs for locals at the end of parsing, Yes we should. >so my patch going through level->names IMO is wrong. We should be >dumping all *_DECLs created by the FE, not just globally scoped ones. > >This means that we'll need to clean up unreachable/unused DIEs after >the >flow graph has been built. If they are there after parsing a debugger should see them. Even if it just prints <optimized out>. >Another example currently not being dumped early is... > > function() > { > class Local { > public: > void loc_foo (void) { } > }; > > Local l; > l.loc_foo (); > } > >...since loc_foo() is not in level->names. Again, this seems like an >argument for early dumping all *_DECLs directly from >rest_of_decl_compilation() (as you've hinted) and then cleaning up >unused DIEs after we have flow information. > >Does this seem reasonable? Yes, but I don't see why we need the cleanup step. The decls are real after all. Richard. >Aldy
On 10/02/14 12:56, Richard Biener wrote:
> Yes, but I don't see why we need the cleanup step. The decls are real after all.
You won't hear me complain.
I was just worried people were going to start complaining about larger
.debug_info sections, since I see that the current code, as it stands in
mainline, doesn't dump (some of) the *_DECLs not currently reachable.
But hey... less work for me!
Thanks.
Aldy
On 10/02/2014 02:21 PM, Aldy Hernandez wrote: > Actually, I think we/I need to rethink this whole globals thing. > Currently we're early dumping global *_DECLs, and hoping dwarf2out > recursion will also pick up types and any derivatives from the *_DECLs, > but taking a closer look I've noticed a lot of things are not being > dumped early. > > For instance: > > > foo() > { > typedef int ITYPE; > ITYPE var = 5; > } > > For the above code, var's DIE gets outputted _after_ the compilation > proper has been run here: > > if (! declaration && outer_scope && TREE_CODE (outer_scope) != > ERROR_MARK > && (!DECL_STRUCT_FUNCTION (decl) > || DECL_STRUCT_FUNCTION (decl)->gimple_df)) > ... > ... > decls_for_scope (outer_scope, subr_die, 0); > > I think we should be outputting DIEs for locals at the end of parsing, > so my patch going through level->names IMO is wrong. We should be > dumping all *_DECLs created by the FE, not just globally scoped ones. The way to dump locals is by recursion. If the current process isn't hitting these, that's a bug, but I don't think it means we need to fundamentally change the approach. Why aren't we hitting that decls_for_scope when we early dump foo? > Another example currently not being dumped early is... > > function() > { > class Local { > public: > void loc_foo (void) { } > }; > > Local l; > l.loc_foo (); > } > > ...since loc_foo() is not in level->names. Again, dumping function() should imply dumping Local and its members. Jason
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 64cd968..1479f03 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "c-family/c-ada-spec.h" #include "asan.h" +#include "debug.h" extern cpp_reader *parse_in; @@ -4298,7 +4299,13 @@ emit_debug_for_namespace (tree name_space, void* data ATTRIBUTE_UNUSED) int len = statics->length (); check_global_declarations (vec, len); - emit_debug_global_declarations (vec, len, EMIT_DEBUG_EARLY); + + for (tree t = level->names; t; t = TREE_CHAIN(t)) + if (TREE_CODE (t) != TYPE_DECL + && TREE_CODE (t) != PARM_DECL + && !DECL_IS_BUILTIN (t)) + debug_hooks->early_global_decl (t); + return 0; } diff --git a/gcc/passes.c b/gcc/passes.c index 5001c3d..aabd365 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -268,6 +268,12 @@ rest_of_decl_compilation (tree decl, else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl) && TREE_STATIC (decl)) varpool_node::get_create (decl); + + /* ?? Theoretically, we should be able to to call + debug_hooks->early_global_decl() here just as we do for + rest_of_type_compilation below. This would require changing how + we're currently calling early_global_decl() in all the + front-ends. Something to look into later. */ } /* Called after finishing a record, union or enumeral type. */