[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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+.
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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=gccview=revrev=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
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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.
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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?
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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).
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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).
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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.
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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
[Bug debug/51902] lexical_blocks inside inlined_subroutines generate duplicate debug_ranges
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?