Bug 66668 - FAIL: gcc.dg/debug/dwarf2/stacked-qualified-types-3.c scan-assembler-times DIE \\([^\n]*\\) DW_TAG_(?:const|volatile|atomic|restrict)_type 8
Summary: FAIL: gcc.dg/debug/dwarf2/stacked-qualified-types-3.c scan-assembler-times DI...
Status: REOPENED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 6.0
: P1 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: testsuite-fail, xfail
Depends on:
Blocks:
 
Reported: 2015-06-25 14:10 UTC by John David Anglin
Modified: 2023-08-20 09:27 UTC (History)
7 users (show)

See Also:
Host:
Target: cris-elf
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-03-05 00:00:00


Attachments
gcc6-pr66668.patch (2.17 KB, patch)
2016-01-21 12:21 UTC, Jakub Jelinek
Details | Diff
stacked-qualified-types-3.s generated for cris-elf at r271469 (1.49 KB, text/plain)
2019-05-22 05:43 UTC, Hans-Peter Nilsson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John David Anglin 2015-06-25 14:10:36 UTC
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)
Comment 1 Rainer Orth 2015-07-01 13:58:15 UTC
This happens almost everywhere, it seems.  A reghunt confirmed that this
regression was caused by the debug-early merge.

  Rainer
Comment 2 Aldy Hernandez 2015-07-01 17:14:14 UTC
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.
Comment 3 Dominik Vogt 2016-01-11 16:21:50 UTC
Are there any news on this issue?
Comment 4 Richard Biener 2016-01-13 14:37:15 UTC
P1 as long as it clutters testresults.
Comment 5 Dominik Vogt 2016-01-14 09:30:51 UTC
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.
Comment 6 Dominik Vogt 2016-01-14 09:48:33 UTC
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?
Comment 7 Jakub Jelinek 2016-01-19 11:44:23 UTC
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?
Comment 8 Jakub Jelinek 2016-01-21 12:21:21 UTC
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.
Comment 9 Jakub Jelinek 2016-01-22 09:41:26 UTC
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
Comment 10 Jakub Jelinek 2016-01-22 09:54:58 UTC
Fixed.
Comment 11 Dominik Vogt 2016-01-22 11:14:44 UTC
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.)
Comment 12 Hans-Peter Nilsson 2019-05-22 05:40:35 UTC
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.
Comment 13 Hans-Peter Nilsson 2019-05-22 05:43:43 UTC
Created attachment 46392 [details]
stacked-qualified-types-3.s generated for cris-elf at r271469
Comment 14 Hans-Peter Nilsson 2021-02-23 03:09:50 UTC
Still there at r11-7328 aka. 8e99b5ba4c19
Comment 15 GCC Commits 2021-03-05 01:01:50 UTC
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-*-*
Comment 16 Hans-Peter Nilsson 2021-03-05 01:10:13 UTC
Observed at a6bc1680a493 r11-7510.
Not sure what's the criteria for WONTFIX, but JFTR I don't mind it closed as such.