Re: [PR59319] output friends in debug info

2017-12-21 Thread Jason Merrill
On Tue, Dec 19, 2017 at 4:56 PM, Alexandre Oliva  wrote:
> 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

2017-12-19 Thread Alexandre Oliva
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 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

2017-12-14 Thread Jason Merrill

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

2017-12-07 Thread Alexandre Oliva
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

2017-04-12 Thread Jeff Law

On 03/21/2017 12:34 PM, Alexandre Oliva wrote:

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, [...]



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

2017-04-10 Thread Mike Stump
On Apr 7, 2017, at 11:32 AM, Alexandre Oliva  wrote:
> 
> 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

2017-04-07 Thread Alexandre Oliva
On Mar 21, 2017, Alexandre Oliva  wrote:
> 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

2017-03-21 Thread Alexandre Oliva
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, [...]

>>> 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

2017-01-26 Thread Alexandre Oliva
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

2016-10-19 Thread Alexandre Oliva
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)


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

2016-09-23 Thread Alexandre Oliva
On Aug 30, 2016, Alexandre Oliva  wrote:

> 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

2016-08-30 Thread Alexandre Oliva
On Aug 26, 2016, Jason Merrill  wrote:

> 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

2016-08-26 Thread Jason Merrill
On Fri, Aug 19, 2016 at 2:46 PM, Alexandre Oliva  wrote:
> 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

2016-08-26 Thread Richard Biener
On Fri, Aug 26, 2016 at 7:25 AM, Alexandre Oliva  wrote:
> 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

2016-08-25 Thread Alexandre Oliva
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).

-- 
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

2016-08-22 Thread Richard Biener
On Fri, Aug 19, 2016 at 8:46 PM, Alexandre Oliva  wrote:
> 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

2016-08-19 Thread Alexandre Oliva
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 ++