Executing on host: /test/gnu/gcc/objdir/gcc/xgcc -B/test/gnu/gcc/objdir/gcc/ /te st/gnu/gcc/gcc/gcc/testsuite/gcc.dg/debug/dwarf2/stacked-qualified-types-3.c -f no-diagnostics-show-caret -fdiagnostics-color=never -std=c11 -gdwarf-5 -dA -S -o stacked-qualified-types-3.s (timeout = 300) spawn /test/gnu/gcc/objdir/gcc/xgcc -B/test/gnu/gcc/objdir/gcc/ /test/gnu/gcc/gc c/gcc/testsuite/gcc.dg/debug/dwarf2/stacked-qualified-types-3.c -fno-diagnostics -show-caret -fdiagnostics-color=never -std=c11 -gdwarf-5 -dA -S -o stacked-quali fied-types-3.s PASS: gcc.dg/debug/dwarf2/stacked-qualified-types-3.c (test for excess errors) FAIL: gcc.dg/debug/dwarf2/stacked-qualified-types-3.c scan-assembler-times DIE \\([^\n]*\\) DW_TAG_(?:const|volatile|atomic|restrict)_type 8 -bash-4.3$ ./xgcc -B./ -v Reading specs from ./specs COLLECT_GCC=./xgcc COLLECT_LTO_WRAPPER=./lto-wrapper Target: hppa64-hp-hpux11.11 Configured with: ../gcc/configure --with-gnu-as --with-as=/opt/gnu64/bin/as --with-ld=/usr/ccs/bin/ld --enable-shared --with-local-prefix=/opt/gnu64 --prefix=/opt/gnu64/gcc/gcc-6 --build=hppa64-hp-hpux11.11 --enable-threads=posix --with-gmp=/opt/gnu64/gcc/gmp --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran Thread model: posix gcc version 6.0.0 20150624 (experimental) [trunk revision 224902] (GCC)
This happens almost everywhere, it seems. A reghunt confirmed that this regression was caused by the debug-early merge. Rainer
Yes, this is a known issue, likely across all architectures. I mentioned this upon merge of the debug-early work: https://gcc.gnu.org/ml/gcc/2015-06/msg00093.html As I discussed in the above post, this is a missed optimization while merging the common denominator of a set of qualifiers for a type within a DIE. For example, if two types share "const volatile" (say "const volatile int" and "const volatile char"), dwarf2out outputs things in the most efficient manner as to share the maximum common type DIEs. This is not working, as TYPE_MAIN_VARIANTs are not complete by the time early dwarf is run. Thanks for opening the PR.
Are there any news on this issue?
P1 as long as it clutters testresults.
The linked page from comment #2 mentions a discussion about this issue which I'm unable to find. Any hints where it is? Anyway, we've looked into it, and it seems that this bit of code generated a duplicate DIE: char a; char * _Atomic restrict h; char * _Atomic i; When handling "h", the algorithm in dwarf2out.c:get_nearest_type_subqualifiers() finds "char *" as the nearest existing type. Then the for-loop in modified_type_die (line 11254) generates an "intermediate" DIE for "char * _Atomic", and the required DIE for "char * _Atomic restrict". Eventually, only the latter one is linked to it's type with "equate_type_number_to_die()", but the intermediate type is not. When the code handles "i", and tries to lookup an existing DIE for "char * _Atomic" (line 11199) it does not find the "intermediate" DIE and generates another one. This is the additional "DW_TAG_atomic" that makes the test case fail. Without looking at the patches that cause this, I believe that with the "early debug" stuff the DIEs are now generated before the list of used types is available to the loop in get_nearest_type_subqualifiers: for (t = TYPE_MAIN_VARIANT (type); t && best_rank < max_rank; t = TYPE_NEXT_VARIANT (t)) It's probably just called earlier now. So, the algorithm to eliminate duplicate type DIEs does not work because it requires a complete and correct list of used types.
There are several approaches to fix the problem: 1) An "Intermediate" DIE is generated if the corresponding type has not yet been recorded. When creating the DIE also generate the type. This may lead to unused types in the list. 2) Like 1, but record the new types for "intermediate" DIEs in a separate place so that they are not visible to the remaining code. When the type is finally generated, "promote" it to the real type list. 3) Store the "intermediate" DIEs in a hash table (or some other structure). If lookup_type_die() fails, search through the hash table for a DIE describing the type at hand. To do this, it is necessary to generate a unique key from a given type (for lookup in the table). It is also necessary to generate the same key from a given DIE (to store a DIE without a type in the table). (Is the "signature" in a DIE any good for this?) May be expensive. 4) When lookup_type_die() fails, any relevant "intermediate" DIEs have been generated for existing types whose qualifiers are a superset of the current type. So, get a list of such types and recurse over all existing DIEs for these types and check whether one of them is the one we're looking for. May be expensive. Any comments or alternative solutions?
So, if what we care about here is solely debug info size and canonicalization of the order and amount of DW_TAG_atomic_type/DW_TAG_restrict_type/DW_TAG_volatile_type/DW_TAG_const_type DIEs for the same non-qualified type, we could perhaps just optimize it later, in one of the numerous walks over the DIE tree. Perhaps just if we see one of these 4 DIEs, and the referenced DIE has the same parent, just move all the qualified variants next to the underlying unqualified type, and then once they are all moved there, figure out what qualified variants we have, determine how to get fewest possible qualified DIEs for the non-qualified type, and build new qualified DIEs if needed and adjust them, and for the ones that should be replaced by others perhaps use a new die_struct bit to tell that all references should be rewritten to refer to some other DIE (and unlink them from the tree), then in another walk adjust all references to so marked DIEs. Mark/Jason, does that sound reasonable to you?
Created attachment 37417 [details] gcc6-pr66668.patch Untested fix. Though, I wonder if mod_type_die already has some parent it wouldn't be better to stick the qualified DIEs for it always under the same parent, rather than to whatever other mod_scope is current at the time when creating the DIEs.
Author: jakub Date: Fri Jan 22 09:40:54 2016 New Revision: 232719 URL: https://gcc.gnu.org/viewcvs?rev=232719&root=gcc&view=rev Log: PR debug/66668 * dwarf2out.c (add_child_die_after): New function. (dwarf_qual_info_t): New type. (dwarf_qual_info): New variable. (qualified_die_p): New function. (modified_type_die): For -fdebug-types-section, ensure canonical order of qualifiers. Put qualified DIEs adjacent to the corresponding non-qualified type DIE and search there for existing qualified DIEs. Modified: trunk/gcc/ChangeLog trunk/gcc/dwarf2out.c
Fixed.
The problem is gone with this fix on s390 and s390x, and check-gcc doesn't show any regressions. (Haven't run a full check though.)
I still see this for cris-elf, introduced in (r224151:r224167], i.e. consistent with the other observations in this report (yes, that old), but *not* fixed by the committed patch, so I'm reopening this with the target field adjusted.
Created attachment 46392 [details] stacked-qualified-types-3.s generated for cris-elf at r271469
Still there at r11-7328 aka. 8e99b5ba4c19
The master branch has been updated by Hans-Peter Nilsson <hp@gcc.gnu.org>: https://gcc.gnu.org/g:8d240b3f0615a890d8bdd9319842601a48292522 commit r11-7518-g8d240b3f0615a890d8bdd9319842601a48292522 Author: Hans-Peter Nilsson <hp@axis.com> Date: Fri Mar 5 01:44:05 2021 +0100 gcc.dg/debug/dwarf2/stacked-qualified-types-3.c: xfail for cris The test is still failing and is a regression on master for cris-elf: the remedy for (all) other targets wasn't sufficient. I'm not myself going to put any effort into it (debug-information being different enough for a test to fail, is not a priority) and apparently not anyone else in the last 5 years, so I'm just going to xfail it. gcc/testsuite: PR debug/66668 * gcc.dg/debug/dwarf2/stacked-qualified-types-3.c: xfail for cris-*-*
Observed at a6bc1680a493 r11-7510. Not sure what's the criteria for WONTFIX, but JFTR I don't mind it closed as such.