public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
@ 2012-01-19 15:01 mark at gcc dot gnu.org
2012-01-19 18:55 ` [Bug debug/51902] " jakub at gcc dot gnu.org
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: mark at gcc dot gnu.org @ 2012-01-19 15:01 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Bug #: 51902
Summary: lexical_blocks inside inlined_subroutines generate
duplicate debug_ranges
Classification: Unclassified
Product: gcc
Version: 4.7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: debug
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: mark@gcc.gnu.org
CC: jakub@gcc.gnu.org, jason@gcc.gnu.org
Created attachment 26380
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26380
debug_ranges.c - Get some statistics on .debug_ranges section.
I noticed that when you generate dwarf for an inlined function it often
comes with duplicate range lists for both the DW_TAG_inlined_subroutine
and the child DW_TAG_lexical_block DIE. For example:
static int k;
static int foo (int i)
{
int j = i + 42;
return k + (j > 14 ? j : i);
}
int main (int argc, char **argv)
{
int c = argc;
k = 2 * c;
c = foo (c);
return c;
}
Generates with -O2 -gdwarf-4:
DWARF section [27] '.debug_info' at offset 0x895:
[Offset]
Compilation unit at offset 0:
Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
[...]
[ a8] inlined_subroutine
abstract_origin (ref4) [ 31]
entry_pc (addr) 0x0000000000400360 <main>
ranges (data4) range list [ 0]
call_file (data1) 1
call_line (data1) 13
[ bb] formal_parameter
abstract_origin (ref4) [ 42]
location (block1)
[ 0] reg5
[ c2] lexical_block
ranges (data4) range list [ 40]
[ c7] variable
abstract_origin (ref4) [ 4b]
location (data4) location list [ 23]
[...]
DWARF section [32] '.debug_ranges' at offset 0xb4e:
[ 0] 0x0000000000400360 <main>..0x0000000000400363 <main+0x3>
0x0000000000400366 <main+0x6>..0x0000000000400369 <main+0x9>
0x000000000040036f <main+0xf>..0x0000000000400374 <main+0x14>
[ 40] 0x0000000000400360 <main>..0x0000000000400363 <main+0x3>
0x0000000000400366 <main+0x6>..0x0000000000400369 <main+0x9>
0x000000000040036f <main+0xf>..0x0000000000400374 <main+0x14>
[ 80] 0x0000000000400360 <main>..0x0000000000400375
So range list 0 for the inlined_subroutine DIE a8 is the same as range
list 40 for the lexical_block DIE c2.
I wrote a quick and dirty elfutils libdw/libdwfl based program to look for this
pattern and it seems to occur reasonably often:
$ ./debug_ranges /usr/lib/debug/bin/bash.debug
cus: 160
subprograms: 6397
inlined_subroutines: 838
lexical_blocks: 359
dup_ranges: 220
dup_addrs: 1454
$ ./debug_ranges ~/build/gcc-obj/gcc/cc1
cus: 390
subprograms: 84288
inlined_subroutines: 7860
lexical_blocks: 6256
dup_ranges: 5274
dup_addrs: 29190
$ ./debug_ranges /usr/lib/debug/lib/modules/3.1.9-1.fc16.x86_64/vmlinux
cus: 1616
subprograms: 108066
inlined_subroutines: 42784
lexical_blocks: 15276
dup_ranges: 7763
dup_addrs: 38586
Given that there will be relocations for .debug_ranges addresses pointing into
.text it could even save twice that number of addresses for ET_REL files.
See also this thread for a first try of a fix (needs some help):
http://gcc.gnu.org/ml/gcc/2012-01/msg00158.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
@ 2012-01-19 18:55 ` jakub at gcc dot gnu.org
2012-01-20 11:30 ` jakub at gcc dot gnu.org
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-19 18:55 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-19 18:04:54 UTC ---
Created attachment 26385
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26385
gcc47-pr51902.patch
Partial patch.
The following example shows it even better, there are 5 identical 3 item
ranges:
static int k;
static int
foo (int i)
{
int q1 = i, q2 = i;
{
int q3 = i;
{
int q4 = i, q5 = i;
{
int j = i + 42;
return k + (j > 14 ? j : i);
}
}
}
}
int
main (int argc, char **argv)
{
int c = argc;
k = 2 * c;
c = foo (c);
return c;
}
IMHO it is impossible to handle this solely in dwarf2out.c, you don't know if
the begin/end notes for a block are adjacent to its BLOCK_SUPERCONTEXT or not.
The attached patch is an untested attempt to provide that info (on a
per-fragment basis). If the stmt BLOCK given to add_high_low_attributes has
BLOCK_SAME_RANGE bit set and all blocks in its BLOCK_FRAGMENT_CHAIN have it set
as well, then you should be able to use the range of its BLOCK_SUPERCONTEXT (if
both stmt and BLOCK_SUPERCONTEXT (stmt) have the same length of fragment chain,
then the whole supercontext's range, otherwise some tail part of it). And
recursively so.
I guess in order to avoid searching through the fragment chains all the time
we should clear BLOCK_SAME_RANGE if BLOCK_SAME_RANGE (BLOCK_FRAGMENT_CHAIN) is
clear (somewhere still during reorder_blocks or number_blocks).
And then the question is how to find the range in the .debug_ranges table
effectively. Walking the whole table would be O(n^2), so have some hash table
that maps the BLOCK_NUM ints that have BLOCK_SAME_RANGE children (at least one)
to .debug_range offsets?
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
2012-01-19 18:55 ` [Bug debug/51902] " jakub at gcc dot gnu.org
@ 2012-01-20 11:30 ` jakub at gcc dot gnu.org
2012-01-20 14:19 ` mark at gcc dot gnu.org
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-20 11:30 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Attachment #26385|0 |1
is obsolete| |
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-20 10:46:29 UTC ---
Created attachment 26391
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26391
gcc47-pr51902.patch
This updated patch does that (I actually managed to implement it without
any sort of extra hash table or array). Fixes up the testcase, I wonder if I
can find a testcase where the supercontext doesn't have completely identical
range, but only tail of it (i.e. that nested block/inlined subroutine could
refer to a couple of tail elements in supercontext's range).
Mark, can you please look at this if it does the right thing you want from it?
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
2012-01-19 18:55 ` [Bug debug/51902] " jakub at gcc dot gnu.org
2012-01-20 11:30 ` jakub at gcc dot gnu.org
@ 2012-01-20 14:19 ` mark at gcc dot gnu.org
2012-01-20 14:20 ` jakub at gcc dot gnu.org
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: mark at gcc dot gnu.org @ 2012-01-20 14:19 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
--- Comment #3 from Mark Wielaard <mark at gcc dot gnu.org> 2012-01-20 13:31:04 UTC ---
(In reply to comment #2)
> Mark, can you please look at this if it does the right thing you want from it?
Yes, this seems to do what I was thinking of. And it works on my testcases.
It does a bit more by searching up the block supercontext and by trying to find
a partial range. I think it would be fine to look for and pick the first block
supercontext and only check the chains are equal (but haven't tried that yet).
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (2 preceding siblings ...)
2012-01-20 14:19 ` mark at gcc dot gnu.org
@ 2012-01-20 14:20 ` jakub at gcc dot gnu.org
2012-01-20 18:01 ` jakub at gcc dot gnu.org
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-20 14:20 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-20 13:37:50 UTC ---
We could go just to the immediate supercontext if BLOCK_SAME_RANGE (both when
the fragment count is the same and when it is smaller in the child), but we'd
lose all the verification (we couldn't test ranges_table[something].num against
BLOCK_NUM).
So perhaps we could do that, and only if ENABLE_CHECKING do the additional
verification afterwards, in the normal code just verify that the start of the
range has > 0 num (so it isn't one ranged by labels).
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (3 preceding siblings ...)
2012-01-20 14:20 ` jakub at gcc dot gnu.org
@ 2012-01-20 18:01 ` jakub at gcc dot gnu.org
2012-01-21 5:23 ` mark at gcc dot gnu.org
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-20 18:01 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-20 17:44:50 UTC ---
The patch breaks g++.dg/guality/redeclaration1.C on i?86 -m32 -Os -g.
The supercontext range has 3 elements, the same range child range has 2
elements, same as the first and last of the supercontext.
So, either we'd need to stop optimizing if thiscount != supercount, or tweak
somehow reorder_blocks_1 so that it clears BLOCK_SAME_RANGE even when it didn't
show up adjacent to supercontext's NOTE_INSN_BLOCK_BEGIN resp. END.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (4 preceding siblings ...)
2012-01-20 18:01 ` jakub at gcc dot gnu.org
@ 2012-01-21 5:23 ` mark at gcc dot gnu.org
2012-01-23 15:33 ` jakub at gcc dot gnu.org
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: mark at gcc dot gnu.org @ 2012-01-21 5:23 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Mark Wielaard <mark at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Attachment #26380|0 |1
is obsolete| |
--- Comment #6 from Mark Wielaard <mark at gcc dot gnu.org> 2012-01-21 00:33:03 UTC ---
Created attachment 26399
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26399
debug_ranges.c - Get some statistics on .debug_ranges section.
Here is a slightly tweaked version of debug_ranges.c that also recognizes
nested lexical_blocks and will print which dies/ranges it finds that are equal,
but are at different range offsets.
die [ed] and [d3] use range [40] and [0], 6 equal addresses.
die [100] and [ed] use range [80] and [40], 6 equal addresses.
die [10c] and [100] use range [c0] and [80], 6 equal addresses.
die [11f] and [10c] use range [100] and [c0], 6 equal addresses.
cus: 1
subprograms: 2
inlined_subroutines: 1
lexical_blocks: 4
equal_ranges: 0
shared_addrs: 0
dup_ranges: 4
dup_addrs: 24
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (5 preceding siblings ...)
2012-01-21 5:23 ` mark at gcc dot gnu.org
@ 2012-01-23 15:33 ` jakub at gcc dot gnu.org
2012-01-24 10:37 ` jakub at gcc dot gnu.org
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-23 15:33 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Attachment #26391|0 |1
is obsolete| |
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-23 15:25:09 UTC ---
Created attachment 26432
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26432
gcc47-pr51902.patch
Updated patch that ought to fix up redeclaration1.C.
It is like the previous patch, but additionally for the duration in between
reorder_blocks_1 and blocks_nreverse_all temporarily sets BLOCK_SUPERCONTEXT
not to the supercontext origin block, but to the supercontext fragment in which
it has been seen. This is then used in extra BLOCK_SAME_RANGE clearing. If we
didn't adjust BLOCK_SUPERCONTEXT to the old meaning right away, if
BLOCK_FRAGMENT_CHAIN (BLOCK_SUPERCONTEXT (block)) is different from
BLOCK_SUPERCONTEXT (BLOCK_FRAGMENT_CHAIN (block)), we clear BLOCK_SAME_RANGE
(block) as well. This should IMHO ensure that if BLOCK_SAME_RANGE is set,
the .debug_range can be merged or tail merged with the parent. As the patch
does adjust BLOCK_SUPERCONTEXT of the block in the same loop to avoid multiple
chain walks, we remember it in prev_super variable instead.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (6 preceding siblings ...)
2012-01-23 15:33 ` jakub at gcc dot gnu.org
@ 2012-01-24 10:37 ` jakub at gcc dot gnu.org
2012-03-05 20:18 ` jakub at gcc dot gnu.org
2012-03-06 17:43 ` jakub at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-01-24 10:37 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |4.8.0
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-24 10:19:02 UTC ---
http://gcc.gnu.org/ml/gcc-patches/2012-01/msg01171.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (7 preceding siblings ...)
2012-01-24 10:37 ` jakub at gcc dot gnu.org
@ 2012-03-05 20:18 ` jakub at gcc dot gnu.org
2012-03-06 17:43 ` jakub at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-03-05 20:18 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-03-05 20:17:54 UTC ---
Author: jakub
Date: Mon Mar 5 20:17:44 2012
New Revision: 184958
URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=184958
Log:
PR debug/51902
* tree.h (BLOCK_SAME_RANGE): Define.
* function.c (block_fragments_nreverse): Clear BLOCK_SAME_RANGE
if BLOCK_FRAGMENT_CHAIN is non-NULL, but has it cleared.
Also clear BLOCK_SAME_RANGE if fragment chain's supercontext fragment
isn't equal to supercontext fragment's fragment chain.
Adjust BLOCK_SUPERCONTEXT to point to supercontext fragment's
fragment origin.
(blocks_nreverse_all): Likewise.
(reorder_blocks_1): Compute BLOCK_SAME_RANGE bits. Set
BLOCK_SUPERCONTEXT to supercontext fragment instead of
supercontext fragment's fragment origin.
* dwarf2out.c (add_high_low_attributes): If stmt has the same
range as its parent (or parents thereof etc.), use the parent's
DW_AT_ranges value instead of creating a new .debug_ranges range.
Modified:
trunk/gcc/ChangeLog
trunk/gcc/dwarf2out.c
trunk/gcc/function.c
trunk/gcc/tree.h
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
` (8 preceding siblings ...)
2012-03-05 20:18 ` jakub at gcc dot gnu.org
@ 2012-03-06 17:43 ` jakub at gcc dot gnu.org
9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2012-03-06 17:43 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51902
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |FIXED
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-03-06 17:42:29 UTC ---
Fixed for 4.8+.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-03-06 17:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-19 15:01 [Bug debug/51902] New: lexical_blocks inside inlined_subroutines generate duplicate debug_ranges mark at gcc dot gnu.org
2012-01-19 18:55 ` [Bug debug/51902] " jakub at gcc dot gnu.org
2012-01-20 11:30 ` jakub at gcc dot gnu.org
2012-01-20 14:19 ` mark at gcc dot gnu.org
2012-01-20 14:20 ` jakub at gcc dot gnu.org
2012-01-20 18:01 ` jakub at gcc dot gnu.org
2012-01-21 5:23 ` mark at gcc dot gnu.org
2012-01-23 15:33 ` jakub at gcc dot gnu.org
2012-01-24 10:37 ` jakub at gcc dot gnu.org
2012-03-05 20:18 ` jakub at gcc dot gnu.org
2012-03-06 17:43 ` jakub at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).