Hi, This came up on the gcc list when extending the number of DWARF type qualifier modifiers that are handled. But the issue can be shown with just const and volatile.
The issue is that there is no ordering constraint on the type qualifier modifier tags (they can appear in any order), but the type signature computation for type units depends on an flattened ordered DIE tree to get the same signature for the same type from different compile units. This seems to only cause a missed opportunity of optimizing when using type units (the type cannot be merged). But maybe there are more subtle issues if the same type from different compilation units create different type unit signatures? Take for example these two compile units, which both define the same type struct s, but also have some different types: 1) int a; const int b; volatile const c; struct s { const volatile int i; } s; Here GCC would create a const type that points to an int and a volatile type that points to that const type. When constructing the DWARF representation of the struct s, it sees it already has a type DIE for const volatile int and reuses that. So in this case the DIE chain for the s.i type comes out as: DW_TAG_volatile_type -> DW_TAG_const_type -> DW_TAG_base_type 2) int a; volatile int b; volatile const c; struct s { const volatile int i; } s; Here GCC would create a volatile type that points to an int and a const type that points to that volatile type. When constructing the DWARF representation of the struct s, it again sees it already has a type DIE for const volatile int and reuses that. So in this case the DIE chain for the s.i type comes out as: DW_TAG_const_type -> DW_TAG_volatile_type -> DW_TAG_base_type The result is that the flattened description of struct s as used by the type signature computation is different in these two compile units. And so the MD5 hash used as signature will differ. I think what GCC does when constructing the DIE type trees is correct. It creates the most efficient type tree in both compile units. To create type trees that look the same in flattened form in both compile units it would have to add extra type trees (a volatile -> int in one or a const -> int in the other) that aren't used otherwise. And it cannot really know which ordering is preferred across all compilation units up front. But it is somewhat unfortunate that it causes the type units to come out with different signatures meaning they cannot be merged. What would be the best way to solve this? I see a couple of options: 0) Don't change anything. It is just a missed optimization. 1) DWARF could prescribe an ordering to use when multiple qualifiers type tags are in used. This might cause producers to create some extra type trees if different subsets of type qualifiers are used, but if type units are used, it might lead to a couple more types to share the same signature. 2) The Type Signature Computation could be changed to understand that type qualifier tags pointing to each other need to be sorted first. This makes the algorithm a little trickier, but means less different type trees in the compile units. 3) DWARF(v5) could deprecate nested type qualifier modifiers as separate tags and replace them with one DW_TAG_qualified_type tag with either separate DW_AT_const|volatile|restrict|atomic flag attributes or a DW_AT_qualifiers attribute that indicates the combined qualifiers (const, volatile, restrict, atomic). That removes the whole ordering issues, so it doesn't matter in which order the DIE chain is flattened. Ideas and/or opinions? Thanks, Mark _______________________________________________ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org