Re: [PR59319] output friends in debug info
On Tue, Dec 19, 2017 at 4:56 PM, Alexandre Olivawrote: > On Dec 14, 2017, Jason Merrill wrote: > >> On 12/07/2017 04:04 PM, Alexandre Oliva wrote: > >>> For other templates, I ended up writing code to look for >>> specializations in the hashtables of decl or type specializations. >>> That's not exactly efficient, but it gets the job done. > >> How inefficient is it, exactly? > > Err... O(n)? :-) For a single friend, but more generally O(M*N) where M is the number of template friends (including instantiations of class templates containing template friends) and N is the total number of instantiations of all (decl) templates. Right? > For the cases we go down this path, we iterate over the hashtable of > specializations of types or functions, testing whether each one fits the > friend template declaration with is_specialization_of_friend(). The > tests there are not particularly expensive, but I suppose they could add > up given tons of template instantiations. I assume the test is already > made efficient, but perhaps a different version could be tuned to this > use, or something, or we could try to come up with a completely > different algorithm that, I don't know, grouped instantiations and > friend declarations by identifiers first, or somesuch. > > Now, perhaps it is possible to locate instantiations more immediately in > cases I haven't been able to figure out. It's not like I know my way > around the internal representation of templates ;-) If you have any > suggestions and directions, I'm all ears. No, currently instantiations of most templates are only hashed, not enumerated. Which was why... >> I wonder about changing register_specialization to fill out >> DECL_TEMPLATE_INSTANTIATIONS for more templates (even more than you >> already do). ...although this would only work for template friends that befriend a specific template; for friend declarations that befriend a member of a class template, we'd still need to do the enumeration the way you do it now, since those declarations also befriend matching members of an explicit specialization of the class template. >>> + /* At DETAIL level 0, returns non-NULL if the named class TYPE has >>> + any friends, NULL otherwise. At higher detail levels, return a >>> + tree list with the friends of the named class type. Each >>> + TREE_VALUE contains one friend type or function decl. For >>> + non-template friends, TREE_PURPOSE is NULL. For template friend >>> + declarations, the returned entries depend on the DETAIL level. >>> + At level 1, and only at level 1, an entry with NULL TREE_VALUE >>> + and non-NULL TREE_PURPOSE will START the returned list to >>> + indicate the named class TYPE has at least one template friend. >>> + At level 2, each template friend will be in an entry with NULL >>> + TREE_VALUE, and with the TEMPLATE_DECL in TREE_PURPOSE. At level >>> + 3, instead of a NULL TREE_VALUE, we add one entry for each >>> + instantiation or specialization of the template that fits the >>> + template friend declaration, as long as there is at least one >>> + instantiation or specialization; if there isn't any, an entry >>> + with NULL TREE_VALUE is created. A negative detail level will >>> + omit non-template friends from the returned list. */ > >> The calls I see only seem to use details 0 and 3, while I would expect >> level 3 to only be used with -g3. What is the purpose of the negative >> level? > > I designed the API so as to give dwarf2out some flexibility in getting > to the information in different ways, allowing queries that wouldn't > waste much memory building lists just to throw them away right away. My > goal was always to list all befriended instantiations at -g, but e.g. if > we've already got the data for non-template friends in an earlier query, > I wanted to avoid duplicating them in a subsequent query for template > friends. That's where the negative levels would come handy. The code > could be structured so as to query at level 1 at first, emit the > non-template friend attributes, and then issue a level 2 or 3 query to > deal with template ones only if the special entry is returned in the > first query. But that subsequent query would duplicate template > entries, whereas with a negative level they would be left out, saving > the memory the list would spend on them. > > Now, regardless of what I set out to do, I figured we might want to vary > the amount of detail put in debug info, and that there might be > discussion about it, so the detail levels would help in that regard too. > I envisioned command line options to control some of that, but I didn't > go down this path further before discussion as to what's desirable, > costly, etc. My inclination is not to enumerate specializations of friend templates at -g1; it seems expensive both in compile time and debug info size. Jason
Re: [PR59319] output friends in debug info
On Dec 14, 2017, Jason Merrillwrote: > On 12/07/2017 04:04 PM, Alexandre Oliva wrote: >> For other templates, I ended up writing code to look for >> specializations in the hashtables of decl or type specializations. >> That's not exactly efficient, but it gets the job done. > How inefficient is it, exactly? Err... O(n)? :-) For the cases we go down this path, we iterate over the hashtable of specializations of types or functions, testing whether each one fits the friend template declaration with is_specialization_of_friend(). The tests there are not particularly expensive, but I suppose they could add up given tons of template instantiations. I assume the test is already made efficient, but perhaps a different version could be tuned to this use, or something, or we could try to come up with a completely different algorithm that, I don't know, grouped instantiations and friend declarations by identifiers first, or somesuch. Now, perhaps it is possible to locate instantiations more immediately in cases I haven't been able to figure out. It's not like I know my way around the internal representation of templates ;-) If you have any suggestions and directions, I'm all ears. > I wonder about changing register_specialization to fill out > DECL_TEMPLATE_INSTANTIATIONS for more templates (even more than you > already do). If spending "permanent" memory to this end is better than gathering it when needed makes it more efficient, sure. >> + /* At DETAIL level 0, returns non-NULL if the named class TYPE has >> + any friends, NULL otherwise. At higher detail levels, return a >> + tree list with the friends of the named class type. Each >> + TREE_VALUE contains one friend type or function decl. For >> + non-template friends, TREE_PURPOSE is NULL. For template friend >> + declarations, the returned entries depend on the DETAIL level. >> + At level 1, and only at level 1, an entry with NULL TREE_VALUE >> + and non-NULL TREE_PURPOSE will START the returned list to >> + indicate the named class TYPE has at least one template friend. >> + At level 2, each template friend will be in an entry with NULL >> + TREE_VALUE, and with the TEMPLATE_DECL in TREE_PURPOSE. At level >> + 3, instead of a NULL TREE_VALUE, we add one entry for each >> + instantiation or specialization of the template that fits the >> + template friend declaration, as long as there is at least one >> + instantiation or specialization; if there isn't any, an entry >> + with NULL TREE_VALUE is created. A negative detail level will >> + omit non-template friends from the returned list. */ > The calls I see only seem to use details 0 and 3, while I would expect > level 3 to only be used with -g3. What is the purpose of the negative > level? I designed the API so as to give dwarf2out some flexibility in getting to the information in different ways, allowing queries that wouldn't waste much memory building lists just to throw them away right away. My goal was always to list all befriended instantiations at -g, but e.g. if we've already got the data for non-template friends in an earlier query, I wanted to avoid duplicating them in a subsequent query for template friends. That's where the negative levels would come handy. The code could be structured so as to query at level 1 at first, emit the non-template friend attributes, and then issue a level 2 or 3 query to deal with template ones only if the special entry is returned in the first query. But that subsequent query would duplicate template entries, whereas with a negative level they would be left out, saving the memory the list would spend on them. Now, regardless of what I set out to do, I figured we might want to vary the amount of detail put in debug info, and that there might be discussion about it, so the detail levels would help in that regard too. I envisioned command line options to control some of that, but I didn't go down this path further before discussion as to what's desirable, costly, etc. -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On 12/07/2017 04:04 PM, Alexandre Oliva wrote: On Apr 7, 2017, Alexandre Oliva <aol...@redhat.com> wrote: On Mar 21, 2017, Alexandre Oliva <aol...@redhat.com> wrote: On Jan 27, 2017, Alexandre Oliva <aol...@redhat.com> wrote: On Oct 19, 2016, Alexandre Oliva <aol...@redhat.com> wrote: On Sep 23, 2016, Alexandre Oliva <aol...@redhat.com> wrote: On Aug 30, 2016, Alexandre Oliva <aol...@redhat.com> wrote: Handling non-template friends is kind of easy, [...] Ping? Ping? (conflicts resolved, patch refreshed and retested) Ping? (trivial conflicts resolved) Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html Ping? Ping? (refreshed, retested) [PR59319] output friends in debug info Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handling template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well. I considered marking those as DW_AT_artificial, to indicate they're not explicitly stated in the source code, but in the end we decided that was not useful. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of class-scoped functions and of nested templates. For other templates, I ended up writing code to look for specializations in the hashtables of decl or type specializations. That's not exactly efficient, but it gets the job done. How inefficient is it, exactly? I'm concerned about the impact on compile time of scanning the entire hash table for each friend declaration in a template instantiation. This sounds prohibitive for template-heavy code that uses friends. I wonder about changing register_specialization to fill out DECL_TEMPLATE_INSTANTIATIONS for more templates (even more than you already do). + /* At DETAIL level 0, returns non-NULL if the named class TYPE has + any friends, NULL otherwise. At higher detail levels, return a + tree list with the friends of the named class type. Each + TREE_VALUE contains one friend type or function decl. For + non-template friends, TREE_PURPOSE is NULL. For template friend + declarations, the returned entries depend on the DETAIL level. + At level 1, and only at level 1, an entry with NULL TREE_VALUE + and non-NULL TREE_PURPOSE will START the returned list to + indicate the named class TYPE has at least one template friend. + At level 2, each template friend will be in an entry with NULL + TREE_VALUE, and with the TEMPLATE_DECL in TREE_PURPOSE. At level + 3, instead of a NULL TREE_VALUE, we add one entry for each + instantiation or specialization of the template that fits the + template friend declaration, as long as there is at least one + instantiation or specialization; if there isn't any, an entry + with NULL TREE_VALUE is created. A negative detail level will + omit non-template friends from the returned list. */ The calls I see only seem to use details 0 and 3, while I would expect level 3 to only be used with -g3. What is the purpose of the negative level? Jason
Re: [PR59319] output friends in debug info
On Apr 7, 2017, Alexandre Oliva <aol...@redhat.com> wrote: > On Mar 21, 2017, Alexandre Oliva <aol...@redhat.com> wrote: >> On Jan 27, 2017, Alexandre Oliva <aol...@redhat.com> wrote: >>> On Oct 19, 2016, Alexandre Oliva <aol...@redhat.com> wrote: >>>> On Sep 23, 2016, Alexandre Oliva <aol...@redhat.com> wrote: >>>>> On Aug 30, 2016, Alexandre Oliva <aol...@redhat.com> wrote: >>>>>> Handling non-template friends is kind of easy, [...] >>>>> Ping? >>>> Ping? (conflicts resolved, patch refreshed and retested) >>> Ping? (trivial conflicts resolved) >> Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html > Ping? Ping? (refreshed, retested) [PR59319] output friends in debug info Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handling template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well. I considered marking those as DW_AT_artificial, to indicate they're not explicitly stated in the source code, but in the end we decided that was not useful. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of class-scoped functions and of nested templates. For other templates, I ended up writing code to look for specializations in the hashtables of decl or type specializations. That's not exactly efficient, but it gets the job done. for gcc/ChangeLog PR debug/59319 * dwarf2out.c (class_types_with_friends): New. (gen_friend_tags_for_type, gen_friend_tags): New. (gen_member_die): Record class types with friends. (deferred_marks): New. (prune_unused_types_defer_undecided_mark_p): New. (prune_unused_types_defer_mark): New. (prune_unused_types_deferred_walk): New. (prune_unused_types_walk): Defer DW_TAG_friend. (prune_unused_types): Check deferred marks is empty on entry, empty it after processing. (dwarf2out_finish): Generate friend tags. (dwarf2out_early_finish): Likewise. * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * langhooks.h (lang_hooks_for_types): Add get_friends. * hooks.c (hook_tree_const_tree_int_null): New. * hooks.h (hook_tree_const_tree_int_null): Declare. for gcc/cp/ChangeLog PR debug/59319 * cp-objcp-common.c (cp_get_friends): New. * cp-objcp-common.h (cp_get_friends): Declare. (LANG_HOOKS_GET_FRIENDS): Override. * cp-tree.h (enumerate_friend_specializations): Declare. * pt.c (optimize_friend_specialization_lookup_p): New. (retrieve_friend_specialization): New. (enumerate_friend_specializations): New. (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS for functions, even after definition, if we are emitting debug info. for gcc/testsuite/ChangeLog PR debug/59319 * g++.dg/debug/dwarf2/friend-1.C: New. * g++.dg/debug/dwarf2/friend-2.C: New. * g++.dg/debug/dwarf2/friend-3.C: New. * g++.dg/debug/dwarf2/friend-4.C: New. * g++.dg/debug/dwarf2/friend-5.C: New. * g++.dg/debug/dwarf2/friend-6.C: New. * g++.dg/debug/dwarf2/friend-7.C: New. * g++.dg/debug/dwarf2/friend-8.C: New. * g++.dg/debug/dwarf2/friend-9.C: New. * g++.dg/debug/dwarf2/friend-10.C: New. * g++.dg/debug/dwarf2/friend-11.C: New. * g++.dg/debug/dwarf2/friend-12.C: New. * g++.dg/debug/dwarf2/friend-13.C: New. * g++.dg/debug/dwarf2/friend-14.C: New. * g++.dg/debug/dwarf2/friend-15.C: New. * g++.dg/debug/dwarf2/friend-16.C: New. * g++.dg/debug/dwarf2/friend-17.C: New. * g++.dg/debug/dwarf2/friend-18.C: New. --- gcc/cp/cp-objcp-common.c | 106 ++ gcc/cp/cp-objcp-common.h |4 + gcc/cp/cp-tree.h
Re: [PR59319] output friends in debug info
On 03/21/2017 12:34 PM, Alexandre Oliva wrote: On Jan 27, 2017, Alexandre Olivawrote: On Oct 19, 2016, Alexandre Oliva wrote: On Sep 23, 2016, Alexandre Oliva wrote: On Aug 30, 2016, Alexandre Oliva wrote: Handling non-template friends is kind of easy, [...] Regstrapped on x86_64-linux-gnu and i686-linux-gnu, I'd failed to mention. Ping? Ping? (conflicts resolved, patch refreshed and retested) Ping? (trivial conflicts resolved) Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html Going to punt to gcc-8. Sorry, but we're just getting late in the release process.. jeff
Re: [PR59319] output friends in debug info
On Apr 7, 2017, at 11:32 AM, Alexandre Olivawrote: > > On Mar 21, 2017, Alexandre Oliva wrote: >> >> Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html > Ping? The Objective-C/C++ parts look fine.
Re: [PR59319] output friends in debug info
On Mar 21, 2017, Alexandre Olivawrote: > On Jan 27, 2017, Alexandre Oliva wrote: >> On Oct 19, 2016, Alexandre Oliva wrote: >>> On Sep 23, 2016, Alexandre Oliva wrote: On Aug 30, 2016, Alexandre Oliva wrote: > Handling non-template friends is kind of easy, [...] Ping? >>> Ping? (conflicts resolved, patch refreshed and retested) >> Ping? (trivial conflicts resolved) > Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html Ping? >> Handling non-template friends is kind of easy, but it required a bit >> of infrastructure in dwarf2out to avoid (i) forcing debug info for >> unused types or functions: DW_TAG_friend DIEs are only emitted if >> their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such >> types or functions just to have them discarded at the end. To this >> end, I introduced a list (vec, actually) of types with friends, >> processed at the end of the translation unit, and a list of >> DW_TAG_friend DIEs that, when we're pruning unused types, reference >> DIEs that are still not known to be used, revisited after we finish >> deciding all other DIEs, so that we prune DIEs that would have >> referenced pruned types or functions. >> Handling template friends turned out to be trickier: there's no >> representation in DWARF for templates. I decided to give debuggers as >> much information as possible, enumerating all specializations of >> friend templates and outputting DW_TAG_friend DIEs referencing them as >> well. I considered marking those as DW_AT_artificial, to indicate >> they're not explicitly stated in the source code, but in the end we >> decided that was not useful. The greatest challenge was to enumerate >> all specializations of a template. It looked trivial at first, given >> DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of >> class-scoped functions and of nested templates. For other templates, >> I ended up writing code to look for specializations in the hashtables >> of decl or type specializations. That's not exactly efficient, but it >> gets the job done. >> for gcc/ChangeLog >> PR debug/59319 >> * dwarf2out.c (class_types_with_friends): New. >> (gen_friend_tags_for_type, gen_friend_tags): New. >> (gen_member_die): Record class types with friends. >> (deferred_marks): New. >> (prune_unused_types_defer_undecided_mark_p): New. >> (prune_unused_types_defer_mark): New. >> (prune_unused_types_deferred_walk): New. >> (prune_unused_types_walk): Defer DW_TAG_friend. >> (prune_unused_types): Check deferred marks is empty on entry, >> empty it after processing. >> (dwarf2out_finish): Generate friend tags. >> (dwarf2out_early_finish): Likewise. >> * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. >> (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. >> * langhooks.h (lang_hooks_for_types): Add get_friends. >> * hooks.c (hook_tree_const_tree_int_null): New. >> * hooks.h (hook_tree_const_tree_int_null): Declare. >> for gcc/cp/ChangeLog >> PR debug/59319 >> * cp-objcp-common.c (cp_get_friends): New. >> * cp-objcp-common.h (cp_get_friends): Declare. >> (LANG_HOOKS_GET_FRIENDS): Override. >> * cp-tree.h (enumerate_friend_specializations): Declare. >> * pt.c (optimize_friend_specialization_lookup_p): New. >> (retrieve_friend_specialization): New. >> (enumerate_friend_specializations): New. >> (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS >> for functions, even after definition, if we are emitting debug >> info. >> for gcc/testsuite/ChangeLog >> PR debug/59319 >> * g++.dg/debug/dwarf2/friend-1.C: New. >> * g++.dg/debug/dwarf2/friend-2.C: New. >> * g++.dg/debug/dwarf2/friend-3.C: New. >> * g++.dg/debug/dwarf2/friend-4.C: New. >> * g++.dg/debug/dwarf2/friend-5.C: New. >> * g++.dg/debug/dwarf2/friend-6.C: New. >> * g++.dg/debug/dwarf2/friend-7.C: New. >> * g++.dg/debug/dwarf2/friend-8.C: New. >> * g++.dg/debug/dwarf2/friend-9.C: New. >> * g++.dg/debug/dwarf2/friend-10.C: New. >> * g++.dg/debug/dwarf2/friend-11.C: New. >> * g++.dg/debug/dwarf2/friend-12.C: New. >> * g++.dg/debug/dwarf2/friend-13.C: New. >> * g++.dg/debug/dwarf2/friend-14.C: New. >> * g++.dg/debug/dwarf2/friend-15.C: New. >> * g++.dg/debug/dwarf2/friend-16.C: New. >> * g++.dg/debug/dwarf2/friend-17.C: New. >> * g++.dg/debug/dwarf2/friend-18.C: New. -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On Jan 27, 2017, Alexandre Olivawrote: > On Oct 19, 2016, Alexandre Oliva wrote: >> On Sep 23, 2016, Alexandre Oliva wrote: >>> On Aug 30, 2016, Alexandre Oliva wrote: Handling non-template friends is kind of easy, [...] >>> Regstrapped on x86_64-linux-gnu and i686-linux-gnu, I'd failed to >>> mention. >>> Ping? >> Ping? (conflicts resolved, patch refreshed and retested) > Ping? (trivial conflicts resolved) Ping? https://gcc.gnu.org/ml/gcc-patches/2017-01/msg02112.html > Handling non-template friends is kind of easy, but it required a bit > of infrastructure in dwarf2out to avoid (i) forcing debug info for > unused types or functions: DW_TAG_friend DIEs are only emitted if > their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such > types or functions just to have them discarded at the end. To this > end, I introduced a list (vec, actually) of types with friends, > processed at the end of the translation unit, and a list of > DW_TAG_friend DIEs that, when we're pruning unused types, reference > DIEs that are still not known to be used, revisited after we finish > deciding all other DIEs, so that we prune DIEs that would have > referenced pruned types or functions. > Handling template friends turned out to be trickier: there's no > representation in DWARF for templates. I decided to give debuggers as > much information as possible, enumerating all specializations of > friend templates and outputting DW_TAG_friend DIEs referencing them as > well. I considered marking those as DW_AT_artificial, to indicate > they're not explicitly stated in the source code, but in the end we > decided that was not useful. The greatest challenge was to enumerate > all specializations of a template. It looked trivial at first, given > DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of > class-scoped functions and of nested templates. For other templates, > I ended up writing code to look for specializations in the hashtables > of decl or type specializations. That's not exactly efficient, but it > gets the job done. > for gcc/ChangeLog > PR debug/59319 > * dwarf2out.c (class_types_with_friends): New. > (gen_friend_tags_for_type, gen_friend_tags): New. > (gen_member_die): Record class types with friends. > (deferred_marks): New. > (prune_unused_types_defer_undecided_mark_p): New. > (prune_unused_types_defer_mark): New. > (prune_unused_types_deferred_walk): New. > (prune_unused_types_walk): Defer DW_TAG_friend. > (prune_unused_types): Check deferred marks is empty on entry, > empty it after processing. > (dwarf2out_finish): Generate friend tags. > (dwarf2out_early_finish): Likewise. > * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. > (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. > * langhooks.h (lang_hooks_for_types): Add get_friends. > * hooks.c (hook_tree_const_tree_int_null): New. > * hooks.h (hook_tree_const_tree_int_null): Declare. > for gcc/cp/ChangeLog > PR debug/59319 > * cp-objcp-common.c (cp_get_friends): New. > * cp-objcp-common.h (cp_get_friends): Declare. > (LANG_HOOKS_GET_FRIENDS): Override. > * cp-tree.h (enumerate_friend_specializations): Declare. > * pt.c (optimize_friend_specialization_lookup_p): New. > (retrieve_friend_specialization): New. > (enumerate_friend_specializations): New. > (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS > for functions, even after definition, if we are emitting debug > info. > for gcc/testsuite/ChangeLog > PR debug/59319 > * g++.dg/debug/dwarf2/friend-1.C: New. > * g++.dg/debug/dwarf2/friend-2.C: New. > * g++.dg/debug/dwarf2/friend-3.C: New. > * g++.dg/debug/dwarf2/friend-4.C: New. > * g++.dg/debug/dwarf2/friend-5.C: New. > * g++.dg/debug/dwarf2/friend-6.C: New. > * g++.dg/debug/dwarf2/friend-7.C: New. > * g++.dg/debug/dwarf2/friend-8.C: New. > * g++.dg/debug/dwarf2/friend-9.C: New. > * g++.dg/debug/dwarf2/friend-10.C: New. > * g++.dg/debug/dwarf2/friend-11.C: New. > * g++.dg/debug/dwarf2/friend-12.C: New. > * g++.dg/debug/dwarf2/friend-13.C: New. > * g++.dg/debug/dwarf2/friend-14.C: New. > * g++.dg/debug/dwarf2/friend-15.C: New. > * g++.dg/debug/dwarf2/friend-16.C: New. > * g++.dg/debug/dwarf2/friend-17.C: New. > * g++.dg/debug/dwarf2/friend-18.C: New. -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On Oct 19, 2016, Alexandre Oliva <aol...@redhat.com> wrote: > On Sep 23, 2016, Alexandre Oliva <aol...@redhat.com> wrote: >> On Aug 30, 2016, Alexandre Oliva <aol...@redhat.com> wrote: >>> Handling non-template friends is kind of easy, [...] >> Regstrapped on x86_64-linux-gnu and i686-linux-gnu, I'd failed to >> mention. >> Ping? > Ping? (conflicts resolved, patch refreshed and retested) Ping? (trivial conflicts resolved) [PR59319] output friends in debug info From: Alexandre Oliva <aol...@redhat.com> Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handling template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well. I considered marking those as DW_AT_artificial, to indicate they're not explicitly stated in the source code, but in the end we decided that was not useful. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of class-scoped functions and of nested templates. For other templates, I ended up writing code to look for specializations in the hashtables of decl or type specializations. That's not exactly efficient, but it gets the job done. for gcc/ChangeLog PR debug/59319 * dwarf2out.c (class_types_with_friends): New. (gen_friend_tags_for_type, gen_friend_tags): New. (gen_member_die): Record class types with friends. (deferred_marks): New. (prune_unused_types_defer_undecided_mark_p): New. (prune_unused_types_defer_mark): New. (prune_unused_types_deferred_walk): New. (prune_unused_types_walk): Defer DW_TAG_friend. (prune_unused_types): Check deferred marks is empty on entry, empty it after processing. (dwarf2out_finish): Generate friend tags. (dwarf2out_early_finish): Likewise. * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * langhooks.h (lang_hooks_for_types): Add get_friends. * hooks.c (hook_tree_const_tree_int_null): New. * hooks.h (hook_tree_const_tree_int_null): Declare. for gcc/cp/ChangeLog PR debug/59319 * cp-objcp-common.c (cp_get_friends): New. * cp-objcp-common.h (cp_get_friends): Declare. (LANG_HOOKS_GET_FRIENDS): Override. * cp-tree.h (enumerate_friend_specializations): Declare. * pt.c (optimize_friend_specialization_lookup_p): New. (retrieve_friend_specialization): New. (enumerate_friend_specializations): New. (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS for functions, even after definition, if we are emitting debug info. for gcc/testsuite/ChangeLog PR debug/59319 * g++.dg/debug/dwarf2/friend-1.C: New. * g++.dg/debug/dwarf2/friend-2.C: New. * g++.dg/debug/dwarf2/friend-3.C: New. * g++.dg/debug/dwarf2/friend-4.C: New. * g++.dg/debug/dwarf2/friend-5.C: New. * g++.dg/debug/dwarf2/friend-6.C: New. * g++.dg/debug/dwarf2/friend-7.C: New. * g++.dg/debug/dwarf2/friend-8.C: New. * g++.dg/debug/dwarf2/friend-9.C: New. * g++.dg/debug/dwarf2/friend-10.C: New. * g++.dg/debug/dwarf2/friend-11.C: New. * g++.dg/debug/dwarf2/friend-12.C: New. * g++.dg/debug/dwarf2/friend-13.C: New. * g++.dg/debug/dwarf2/friend-14.C: New. * g++.dg/debug/dwarf2/friend-15.C: New. * g++.dg/debug/dwarf2/friend-16.C: New. * g++.dg/debug/dwarf2/friend-17.C: New. * g++.dg/debug/dwarf2/friend-18.C: New. --- gcc/cp/cp-objcp-common.c | 106 ++ gcc/cp/cp-objcp-common.h |4 + gcc/cp/cp-tree.h |1 gcc/cp/pt.c | 194 + gcc/dwarf2out.c | 165 + gcc/hooks.c |7 + gcc/hooks.h |
Re: [PR59319] output friends in debug info
On Sep 23, 2016, Alexandre Olivawrote: > On Aug 30, 2016, Alexandre Oliva wrote: >> Handling non-template friends is kind of easy, [...] > Regstrapped on x86_64-linux-gnu and i686-linux-gnu, I'd failed to > mention. > Ping? Ping? (conflicts resolved, patch refreshed and retested) Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handling template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well. I considered marking those as DW_AT_artificial, to indicate they're not explicitly stated in the source code, but in the end we decided that was not useful. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of class-scoped functions and of nested templates. For other templates, I ended up writing code to look for specializations in the hashtables of decl or type specializations. That's not exactly efficient, but it gets the job done. for gcc/ChangeLog PR debug/59319 * dwarf2out.c (class_types_with_friends): New. (gen_friend_tags_for_type, gen_friend_tags): New. (gen_member_die): Record class types with friends. (deferred_marks): New. (prune_unused_types_defer_undecided_mark_p): New. (prune_unused_types_defer_mark): New. (prune_unused_types_deferred_walk): New. (prune_unused_types_walk): Defer DW_TAG_friend. (prune_unused_types): Check deferred marks is empty on entry, empty it after processing. (dwarf2out_finish): Generate friend tags. (dwarf2out_early_finish): Likewise. * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * langhooks.h (lang_hooks_for_types): Add get_friends. for gcc/cp/ChangeLog PR debug/59319 * cp-objcp-common.c (cp_get_friends): New. * cp-objcp-common.h (cp_get_friends): Declare. (LANG_HOOKS_GET_FRIENDS): Override. * cp-tree.h (enumerate_friend_specializations): Declare. * pt.c (optimize_friend_specialization_lookup_p): New. (retrieve_friend_specialization): New. (enumerate_friend_specializations): New. (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS for functions, even after definition, if we are emitting debug info. for gcc/testsuite/ChangeLog PR debug/59319 * g++.dg/debug/dwarf2/friend-1.C: New. * g++.dg/debug/dwarf2/friend-2.C: New. * g++.dg/debug/dwarf2/friend-3.C: New. * g++.dg/debug/dwarf2/friend-4.C: New. * g++.dg/debug/dwarf2/friend-5.C: New. * g++.dg/debug/dwarf2/friend-6.C: New. * g++.dg/debug/dwarf2/friend-7.C: New. * g++.dg/debug/dwarf2/friend-8.C: New. * g++.dg/debug/dwarf2/friend-9.C: New. * g++.dg/debug/dwarf2/friend-10.C: New. * g++.dg/debug/dwarf2/friend-11.C: New. * g++.dg/debug/dwarf2/friend-12.C: New. * g++.dg/debug/dwarf2/friend-13.C: New. * g++.dg/debug/dwarf2/friend-14.C: New. * g++.dg/debug/dwarf2/friend-15.C: New. * g++.dg/debug/dwarf2/friend-16.C: New. * g++.dg/debug/dwarf2/friend-17.C: New. * g++.dg/debug/dwarf2/friend-18.C: New. --- gcc/cp/cp-objcp-common.c | 106 ++ gcc/cp/cp-objcp-common.h |3 gcc/cp/cp-tree.h |1 gcc/cp/pt.c | 194 + gcc/dwarf2out.c | 165 + gcc/langhooks-def.h |4 - gcc/langhooks.h | 19 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-1.C | 10 + gcc/testsuite/g++.dg/debug/dwarf2/friend-10.C | 13 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-11.C | 13 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-12.C | 15 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-13.C | 12 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-14.C | 20 +++
Re: [PR59319] output friends in debug info
On Aug 30, 2016, Alexandre Olivawrote: > Handling non-template friends is kind of easy, but it required a bit > of infrastructure in dwarf2out to avoid (i) forcing debug info for > unused types or functions: DW_TAG_friend DIEs are only emitted if > their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such > types or functions just to have them discarded at the end. To this > end, I introduced a list (vec, actually) of types with friends, > processed at the end of the translation unit, and a list of > DW_TAG_friend DIEs that, when we're pruning unused types, reference > DIEs that are still not known to be used, revisited after we finish > deciding all other DIEs, so that we prune DIEs that would have > referenced pruned types or functions. > Handling template friends turned out to be trickier: there's no > representation in DWARF for templates. I decided to give debuggers as > much information as possible, enumerating all specializations of > friend templates and outputting DW_TAG_friend DIEs referencing them as > well. I considered marking those as DW_AT_artificial, to indicate > they're not explicitly stated in the source code, but in the end we > decided that was not useful. The greatest challenge was to enumerate > all specializations of a template. It looked trivial at first, given > DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of > class-scoped functions and of nested templates. For other templates, > I ended up writing code to look for specializations in the hashtables > of decl or type specializations. That's not exactly efficient, but it > gets the job done. Regstrapped on x86_64-linux-gnu and i686-linux-gnu, I'd failed to mention. Ping? https://gcc.gnu.org/ml/gcc-patches/2016-08/msg02092.html -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On Aug 26, 2016, Jason Merrillwrote: > I suppose we can teach dwz to use the maximal set of friends... *nod* > This seems unnecessary; there is no semantic difference for a > particular specialization depending on whether it became a friend > directly or from its template. 'k, I took that out. If we change our minds, it's easy enough to put it back in. > But looking more closely I see that for functions, it is only > maintained before the function template is defined. That should be > simple enough to change. Done. >> - I haven't used local_specializations, should I? I was a bit >> confused about the apparently unused local_specialization_stack, >> too. > No, local_specializations is just for function-local decls. Thanks. Here's the updated patch. Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handling template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well. I considered marking those as DW_AT_artificial, to indicate they're not explicitly stated in the source code, but in the end we decided that was not useful. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but it won't list specializations of class-scoped functions and of nested templates. For other templates, I ended up writing code to look for specializations in the hashtables of decl or type specializations. That's not exactly efficient, but it gets the job done. for gcc/ChangeLog PR debug/59319 * dwarf2out.c (class_types_with_friends): New. (gen_friend_tags_for_type, gen_friend_tags): New. (gen_member_die): Record class types with friends. (deferred_marks): New. (prune_unused_types_defer_undecided_mark_p): New. (prune_unused_types_defer_mark): New. (prune_unused_types_deferred_walk): New. (prune_unused_types_walk): Defer DW_TAG_friend. (prune_unused_types): Check deferred marks is empty on entry, empty it after processing. (dwarf2out_finish): Generate friend tags. (dwarf2out_early_finish): Likewise. * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * langhooks.h (lang_hooks_for_types): Add get_friends. for gcc/cp/ChangeLog PR debug/59319 * cp-objcp-common.c (cp_get_friends): New. * cp-objcp-common.h (cp_get_friends): Declare. (LANG_HOOKS_GET_FRIENDS): Override. * cp-tree.h (enumerate_friend_specializations): Declare. * pt.c (optimize_friend_specialization_lookup_p): New. (retrieve_friend_specialization): New. (enumerate_friend_specializations): New. (register_specialization): Update DECL_TEMPLATE_INSTANTIATIONS for functions, even after definition, if we are emitting debug info. for gcc/testsuite/ChangeLog PR debug/59319 * g++.dg/debug/dwarf2/friend-1.C: New. * g++.dg/debug/dwarf2/friend-2.C: New. * g++.dg/debug/dwarf2/friend-3.C: New. * g++.dg/debug/dwarf2/friend-4.C: New. * g++.dg/debug/dwarf2/friend-5.C: New. * g++.dg/debug/dwarf2/friend-6.C: New. * g++.dg/debug/dwarf2/friend-7.C: New. * g++.dg/debug/dwarf2/friend-8.C: New. * g++.dg/debug/dwarf2/friend-9.C: New. * g++.dg/debug/dwarf2/friend-10.C: New. * g++.dg/debug/dwarf2/friend-11.C: New. * g++.dg/debug/dwarf2/friend-12.C: New. * g++.dg/debug/dwarf2/friend-13.C: New. * g++.dg/debug/dwarf2/friend-14.C: New. * g++.dg/debug/dwarf2/friend-15.C: New. * g++.dg/debug/dwarf2/friend-16.C: New. * g++.dg/debug/dwarf2/friend-17.C: New. * g++.dg/debug/dwarf2/friend-18.C: New. --- gcc/cp/cp-objcp-common.c | 106 ++ gcc/cp/cp-objcp-common.h |3 gcc/cp/cp-tree.h |1 gcc/cp/pt.c | 194 + gcc/dwarf2out.c | 165 +
Re: [PR59319] output friends in debug info
On Fri, Aug 19, 2016 at 2:46 PM, Alexandre Olivawrote: > Handling non-template friends is kind of easy, but it required a bit > of infrastructure in dwarf2out to avoid (i) forcing debug info for > unused types or functions: DW_TAG_friend DIEs are only emitted if > their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such > types or functions just to have them discarded at the end. To this > end, I introduced a list (vec, actually) of types with friends, > processed at the end of the translation unit, and a list of > DW_TAG_friend DIEs that, when we're pruning unused types, reference > DIEs that are still not known to be used, revisited after we finish > deciding all other DIEs, so that we prune DIEs that would have > referenced pruned types or functions. > > Handlig template friends turned out to be trickier: there's no > representation in DWARF for templates. I decided to give debuggers as > much information as possible, enumerating all specializations of > friend templates and outputting DW_TAG_friend DIEs referencing them as > well, This makes sense, though I'm concerned about the impact on DWARF optimizers. I suppose we can teach dwz to use the maximal set of friends... > but marking them as DW_AT_artificial to indicate they're not > explicitly stated in the source code. This seems unnecessary; there is no semantic difference for a particular specialization depending on whether it became a friend directly or from its template. > This attribute is not valid for > DW_TAG_friend, so it's only emitted in non-strict mode. The greatest > challenge was to enumerate all specializations of a template. It > looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but in > some of the testcases, cases it wouldn't list any specializations, and > in others it would list only some of them. Hmm, I would expect it to work where it's documented to be meaningful: namespace-scope functions and classes. But looking more closely I see that for functions, it is only maintained before the function template is defined. That should be simple enough to change. > I couldn't figure out the > logic behind that, and it seemed clear from the documentation of this > macro that at least in some cases it wouldn't hold the list, so I > ended up writing code to look for specializations in the hashtables of > decl or type specializations. That worked fine, but it's not exactly > an efficient way to obtain the desired information, at least in some > cases. > - should we output specializations of friend templates as friends even > in strict mode? Currently we output them with DW_AT_artificial in > non-strict mode, and without the artificial mark in strict mode. > > - is there any way we can use DECL_TEMPLATE_INSTANTIATIONS reliably to > enumerate the specializations of a friend template, or at least tell > when it can be used? > > - I haven't used local_specializations, should I? I was a bit > confused about the apparently unused local_specialization_stack, > too. No, local_specializations is just for function-local decls. Jason
Re: [PR59319] output friends in debug info
On Fri, Aug 26, 2016 at 7:25 AM, Alexandre Olivawrote: > On Aug 22, 2016, Richard Biener wrote: > >> Just throwing in a wrench from the side ... you should do this in >> dwarf2out_early_finish as late there will be no frontend around anymore. > > Thanks for the heads up, I've adjusted my local copy to do so. > >> Yeah, prune_unused_types is still done in dwarf2out_finish on trunk > > That doesn't matter much, the DW_TAG_friend pruning doesn't look at the > types, only the class_types_with_friends users did, and those run much > earlier (now at dwarf2out_early_finish too). Thanks! Richard. > -- > Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ > You must be the change you wish to see in the world. -- Gandhi > Be Free! -- http://FSFLA.org/ FSF Latin America board member > Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On Aug 22, 2016, Richard Bienerwrote: > Just throwing in a wrench from the side ... you should do this in > dwarf2out_early_finish as late there will be no frontend around anymore. Thanks for the heads up, I've adjusted my local copy to do so. > Yeah, prune_unused_types is still done in dwarf2out_finish on trunk That doesn't matter much, the DW_TAG_friend pruning doesn't look at the types, only the class_types_with_friends users did, and those run much earlier (now at dwarf2out_early_finish too). -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Re: [PR59319] output friends in debug info
On Fri, Aug 19, 2016 at 8:46 PM, Alexandre Olivawrote: > This is not a finished patch. There are two issues I'd like feedback > on before a final submission. See them below. First, a general > description. > > Handling non-template friends is kind of easy, but it required a bit > of infrastructure in dwarf2out to avoid (i) forcing debug info for > unused types or functions: DW_TAG_friend DIEs are only emitted if > their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such > types or functions just to have them discarded at the end. To this > end, I introduced a list (vec, actually) of types with friends, > processed at the end of the translation unit, and a list of > DW_TAG_friend DIEs that, when we're pruning unused types, reference > DIEs that are still not known to be used, revisited after we finish > deciding all other DIEs, so that we prune DIEs that would have > referenced pruned types or functions. > > Handlig template friends turned out to be trickier: there's no > representation in DWARF for templates. I decided to give debuggers as > much information as possible, enumerating all specializations of > friend templates and outputting DW_TAG_friend DIEs referencing them as > well, but marking them as DW_AT_artificial to indicate they're not > explicitly stated in the source code. This attribute is not valid for > DW_TAG_friend, so it's only emitted in non-strict mode. The greatest > challenge was to enumerate all specializations of a template. It > looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but in > some of the testcases, cases it wouldn't list any specializations, and > in others it would list only some of them. I couldn't figure out the > logic behind that, and it seemed clear from the documentation of this > macro that at least in some cases it wouldn't hold the list, so I > ended up writing code to look for specializations in the hashtables of > decl or type specializations. That worked fine, but it's not exactly > an efficient way to obtain the desired information, at least in some > cases. > > > > - should we output specializations of friend templates as friends even > in strict mode? Currently we output them with DW_AT_artificial in > non-strict mode, and without the artificial mark in strict mode. > > - is there any way we can use DECL_TEMPLATE_INSTANTIATIONS reliably to > enumerate the specializations of a friend template, or at least tell > when it can be used? > > - I haven't used local_specializations, should I? I was a bit > confused about the apparently unused local_specialization_stack, > too. > > I haven't covered partial and explicit specializations in the > testcases yet. > > > for gcc/ChangeLog > > PR debug/59319 > * dwarf2out.c (class_types_with_friends): New. > (gen_friend_tags_for_type, gen_friend_tags): New. > (gen_member_die): Record class types with friends. > (deferred_marks): New. > (prune_unused_types_defer_undecided_mark_p): New. > (prune_unused_types_defer_mark): New. > (prune_unused_types_deferred_walk): New. > (prune_unused_types_walk): Defer DW_TAG_friend. > (prune_unused_types): Check deferred marks is empty on entry, > empty it after processing. > (dwarf2out_finish): Generate friend tags. Just throwing in a wrench from the side ... you should do this in dwarf2out_early_finish as late there will be no frontend around anymore. Yeah, prune_unused_types is still done in dwarf2out_finish on trunk but I am moving it early for LTO early debug (I didn't try doing this in isolation on trunk now but you may ...;)). In fact I am moving almost all type related post-processing from dwarf2out_finish to dwarf2out_early_finish. Richard. > * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. > (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. > * langhooks.h (lang_hooks_for_types): Add get_friends. > > for gcc/cp/ChangeLog > > PR debug/59319 > * cp-objcp-common.c (cp_get_friends): New. > * cp-objcp-common.h (cp_get_friends): Declare. > (LANG_HOOKS_GET_FRIENDS): Override. > * cp-tree.h (enumerate_friend_specializations): Declare. > * pt.c (enumerate_friend_specializations): New. > > for gcc/testsuite/ChangeLog > > PR debug/59319 > * g++.dg/debug/dwarf2/friend-1.C: New. > * g++.dg/debug/dwarf2/friend-2.C: New. > * g++.dg/debug/dwarf2/friend-3.C: New. > * g++.dg/debug/dwarf2/friend-4.C: New. > * g++.dg/debug/dwarf2/friend-5.C: New. > * g++.dg/debug/dwarf2/friend-6.C: New. > * g++.dg/debug/dwarf2/friend-7.C: New. > * g++.dg/debug/dwarf2/friend-8.C: New. > * g++.dg/debug/dwarf2/friend-9.C: New. > * g++.dg/debug/dwarf2/friend-10.C: New. > * g++.dg/debug/dwarf2/friend-11.C: New. > * g++.dg/debug/dwarf2/friend-12.C: New. > *
[PR59319] output friends in debug info
This is not a finished patch. There are two issues I'd like feedback on before a final submission. See them below. First, a general description. Handling non-template friends is kind of easy, but it required a bit of infrastructure in dwarf2out to avoid (i) forcing debug info for unused types or functions: DW_TAG_friend DIEs are only emitted if their DW_AT_friend DIE is emitted, and (ii) creating DIEs for such types or functions just to have them discarded at the end. To this end, I introduced a list (vec, actually) of types with friends, processed at the end of the translation unit, and a list of DW_TAG_friend DIEs that, when we're pruning unused types, reference DIEs that are still not known to be used, revisited after we finish deciding all other DIEs, so that we prune DIEs that would have referenced pruned types or functions. Handlig template friends turned out to be trickier: there's no representation in DWARF for templates. I decided to give debuggers as much information as possible, enumerating all specializations of friend templates and outputting DW_TAG_friend DIEs referencing them as well, but marking them as DW_AT_artificial to indicate they're not explicitly stated in the source code. This attribute is not valid for DW_TAG_friend, so it's only emitted in non-strict mode. The greatest challenge was to enumerate all specializations of a template. It looked trivial at first, given DECL_TEMPLATE_INSTANTIATIONS, but in some of the testcases, cases it wouldn't list any specializations, and in others it would list only some of them. I couldn't figure out the logic behind that, and it seemed clear from the documentation of this macro that at least in some cases it wouldn't hold the list, so I ended up writing code to look for specializations in the hashtables of decl or type specializations. That worked fine, but it's not exactly an efficient way to obtain the desired information, at least in some cases. - should we output specializations of friend templates as friends even in strict mode? Currently we output them with DW_AT_artificial in non-strict mode, and without the artificial mark in strict mode. - is there any way we can use DECL_TEMPLATE_INSTANTIATIONS reliably to enumerate the specializations of a friend template, or at least tell when it can be used? - I haven't used local_specializations, should I? I was a bit confused about the apparently unused local_specialization_stack, too. I haven't covered partial and explicit specializations in the testcases yet. for gcc/ChangeLog PR debug/59319 * dwarf2out.c (class_types_with_friends): New. (gen_friend_tags_for_type, gen_friend_tags): New. (gen_member_die): Record class types with friends. (deferred_marks): New. (prune_unused_types_defer_undecided_mark_p): New. (prune_unused_types_defer_mark): New. (prune_unused_types_deferred_walk): New. (prune_unused_types_walk): Defer DW_TAG_friend. (prune_unused_types): Check deferred marks is empty on entry, empty it after processing. (dwarf2out_finish): Generate friend tags. * langhooks-def.h (LANG_HOOKS_GET_FRIENDS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * langhooks.h (lang_hooks_for_types): Add get_friends. for gcc/cp/ChangeLog PR debug/59319 * cp-objcp-common.c (cp_get_friends): New. * cp-objcp-common.h (cp_get_friends): Declare. (LANG_HOOKS_GET_FRIENDS): Override. * cp-tree.h (enumerate_friend_specializations): Declare. * pt.c (enumerate_friend_specializations): New. for gcc/testsuite/ChangeLog PR debug/59319 * g++.dg/debug/dwarf2/friend-1.C: New. * g++.dg/debug/dwarf2/friend-2.C: New. * g++.dg/debug/dwarf2/friend-3.C: New. * g++.dg/debug/dwarf2/friend-4.C: New. * g++.dg/debug/dwarf2/friend-5.C: New. * g++.dg/debug/dwarf2/friend-6.C: New. * g++.dg/debug/dwarf2/friend-7.C: New. * g++.dg/debug/dwarf2/friend-8.C: New. * g++.dg/debug/dwarf2/friend-9.C: New. * g++.dg/debug/dwarf2/friend-10.C: New. * g++.dg/debug/dwarf2/friend-11.C: New. * g++.dg/debug/dwarf2/friend-12.C: New. * g++.dg/debug/dwarf2/friend-13.C: New. --- gcc/cp/cp-objcp-common.c | 103 gcc/cp/cp-objcp-common.h |3 gcc/cp/cp-tree.h |1 gcc/cp/pt.c | 73 +++ gcc/dwarf2out.c | 161 + gcc/langhooks-def.h |4 - gcc/langhooks.h | 19 +++ gcc/testsuite/g++.dg/debug/dwarf2/friend-1.C | 10 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-10.C | 13 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-11.C | 13 ++ gcc/testsuite/g++.dg/debug/dwarf2/friend-12.C | 15 ++