Bug 25450 - Compress member function template DIEs
Summary: Compress member function template DIEs
Status: NEW
Alias: None
Product: dwz
Classification: Unclassified
Component: default (show other bugs)
Version: unspecified
: P2 enhancement
Target Milestone: ---
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-01-23 17:10 UTC by Tom de Vries
Modified: 2020-01-23 17:34 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2020-01-23 17:10:49 UTC
Consider the following test-case.

test.h:
...
struct aaa
{
  template<typename T> void foo(T obj) {}
};
...

test.cc:
...
extern void other_unit (void);

#include "test.h"

struct aaa var;

int
main (void)
{
  int a;
  float f;
  var.foo (a);
  var.foo (f);
  other_unit ();
  return 0;
}
...

test2.cc:
...
#include "test.h"

struct aaa var2;

void
other_unit (void)
{
  double d;
  var2.foo (d);
}
...

Compiled like this:
...
$ g++ test.cc test2.cc -g
...

In the test.cc compilation unit, we have:
...
 <1><f0>: Abbrev Number: 2 (DW_TAG_structure_type)
    <f1>   DW_AT_name        : aaa
    <f5>   DW_AT_byte_size   : 1
    <f6>   DW_AT_decl_file   : 2
    <f7>   DW_AT_decl_line   : 1
    <f8>   DW_AT_sibling     : <0x143>
 <2><fc>: Abbrev Number: 3 (DW_TAG_subprogram)
    <fd>   DW_AT_external    : 1
    <fd>   DW_AT_name        : (indirect string, offset: 0x1d0): foo<float>
    <101>   DW_AT_decl_file   : 2
    <102>   DW_AT_decl_line   : 3
    <103>   DW_AT_linkage_name: (indirect string, offset: 0x262): _ZN3aaa3fooIfEEvT_
    <107>   DW_AT_declaration : 1
    <107>   DW_AT_object_pointer: <0x116>
    <10b>   DW_AT_sibling     : <0x121>
 <3><10f>: Abbrev Number: 4 (DW_TAG_template_type_param)
    <110>   DW_AT_name        : T
    <112>   DW_AT_type        : <0x158>
 <3><116>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <117>   DW_AT_type        : <0x15f>
    <11b>   DW_AT_artificial  : 1
 <3><11b>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <11c>   DW_AT_type        : <0x158>
 <3><120>: Abbrev Number: 0
 <2><121>: Abbrev Number: 7 (DW_TAG_subprogram)
    <122>   DW_AT_external    : 1
    <122>   DW_AT_name        : (indirect string, offset: 0x254): foo<int>
    <126>   DW_AT_decl_file   : 2
    <127>   DW_AT_decl_line   : 3
    <128>   DW_AT_linkage_name: (indirect string, offset: 0x1db): _ZN3aaa3fooIiEEvT_
    <12c>   DW_AT_declaration : 1
    <12c>   DW_AT_object_pointer: <0x137>
 <3><130>: Abbrev Number: 4 (DW_TAG_template_type_param)
    <131>   DW_AT_name        : T
    <133>   DW_AT_type        : <0x1af>
 <3><137>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <138>   DW_AT_type        : <0x15f>
    <13c>   DW_AT_artificial  : 1
 <3><13c>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <13d>   DW_AT_type        : <0x1af>
...

And in the test2.cc compilation unit, we have:
...
 <1><25b>: Abbrev Number: 2 (DW_TAG_structure_type)
    <25c>   DW_AT_name        : aaa
    <260>   DW_AT_byte_size   : 1
    <261>   DW_AT_decl_file   : 2
    <262>   DW_AT_decl_line   : 1
    <263>   DW_AT_sibling     : <0x289>
 <2><267>: Abbrev Number: 3 (DW_TAG_subprogram)
    <268>   DW_AT_external    : 1
    <268>   DW_AT_name        : (indirect string, offset: 0x2b7): foo<double>
    <26c>   DW_AT_decl_file   : 2
    <26d>   DW_AT_decl_line   : 3
    <26e>   DW_AT_linkage_name: (indirect string, offset: 0x27b): _ZN3aaa3fooIdEEvT_
    <272>   DW_AT_declaration : 1
    <272>   DW_AT_object_pointer: <0x27d>
 <3><276>: Abbrev Number: 4 (DW_TAG_template_type_param)
    <277>   DW_AT_name        : T
    <279>   DW_AT_type        : <0x29e>
 <3><27d>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <27e>   DW_AT_type        : <0x2a5>
    <282>   DW_AT_artificial  : 1
 <3><282>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <283>   DW_AT_type        : <0x29e>
...

Despite the fact that the two DIEs are generated from the same header file, they are structurally different, due to the different instantiations of the member function template. Consequently, dwz does not factor out the DIEs.
Comment 1 Tom de Vries 2020-01-23 17:34:29 UTC
(In reply to Tom de Vries from comment #0)
> Despite the fact that the two DIEs are generated from the same header file,
> they are structurally different, due to the different instantiations of the
> member function template. Consequently, dwz does not factor out the DIEs.

One way to address this is to generate the union of the DIEs into a partial unit.    [ This does create the problem of having references from that union to DIEs that are unique to a certain CU, and consequently don't have a duplicate chain. ]

Another way is to factor out the common part of the DIEs into a partial unit, and include it from the original DIEs using DW_AT_specification.