This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/57451] Incorrect debug ranges emitted for -freorder-blocks-and-partition -g
- From: "tejohnson at google dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 09 Aug 2013 23:01:36 +0000
- Subject: [Bug rtl-optimization/57451] Incorrect debug ranges emitted for -freorder-blocks-and-partition -g
- Auto-submitted: auto-generated
- References: <bug-57451-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57451
--- Comment #6 from Teresa Johnson <tejohnson at google dot com> ---
On Sat, Jun 15, 2013 at 7:02 AM, Teresa Johnson <tejohnson@google.com> wrote:
> On Fri, Jun 14, 2013 at 4:19 PM, ccoutant at gcc dot gnu.org
> <gcc-bugzilla@gcc.gnu.org> wrote:
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57451
>>
>> --- Comment #4 from Cary Coutant <ccoutant at gcc dot gnu.org> ---
>> The problem is a lexical block in main() that appears to be getting split by
>> -freorder-blocks-and-partition, but when debug info is emitted during
>> rest_of_handle_final(), this particular lexical block still appears to be a
>> single block -- BLOCK_FRAGMENT_CHAIN is NULL, so the DWARF output code decides
>> that it can emit a DW_AT_low_pc/high_pc pair instead of a DW_AT_ranges. The
>> DW_AT_high_pc is now being output relative to DW_AT_low_pc, so we see an
>> assembly expression .LBE14 - .LBB14, which are labels attached to the block
>> start and block end, and should be in the same section.
>>
>> Here's the block:
>>
>> (gdb) p stmt
>> $1 = (tree) 0x7ffff5f4c4b0
>> (gdb) pt
>> warning: Expression is not an assignment (and might have no effect)
>> <block 0x7ffff5f4c4b0 asm_written used
>> vars <var_decl 0x7ffff608bc78 e
>> type <reference_type 0x7ffff609b930 type <record_type 0x7ffff608e9d8
>> MyException>
>> sizes-gimplified unsigned DI
>> size <integer_cst 0x7ffff5f24dc0 constant 64>
>> unit size <integer_cst 0x7ffff5f24de0 constant 8>
>> align 64 symtab 0 alias set -1 canonical type 0x7ffff609b930>
>> readonly tree_1 tree_3 unsigned decl_5 DI file pr49115.C line 21 col 25
>> size <integer_cst 0x7ffff5f24dc0 64> unit size <integer_cst 0x7ffff5f24de0 8>
>> align 64 context <function_decl 0x7ffff6096f00 main>>
>> supercontext <block 0x7ffff60c00f0 asm_written used
>> vars <var_decl 0x7ffff608bb48 data type <record_type 0x7ffff608ec78
>> Data>
>> used tree_1 tree_3 decl_5 SI file pr49115.C line 18 col 8
>> size <integer_cst 0x7ffff5f42140 constant 32>
>> unit size <integer_cst 0x7ffff5f42160 constant 4>
>> align 128 context <function_decl 0x7ffff6096f00 main>
>> (reg/v:SI 64 [ data ])>
>> supercontext <block 0x7ffff5f4c550 asm_written used supercontext
>> <function_decl 0x7ffff6096f00 main>
>> subblocks <block 0x7ffff5f4c500 asm_written used vars <var_decl
>> 0x7ffff608bb48 data> supercontext <block 0x7ffff5f4c550> subblocks <block
>> 0x7ffff5f4c4b0> chain <block 0x7ffff60c00f0>>>>>
>>
>> (gdb) p stmt->block
>> $2 = {base = {code = BLOCK, side_effects_flag = 0, constant_flag = 0,
>> addressable_flag = 0,
>> volatile_flag = 0, readonly_flag = 0, asm_written_flag = 1, nowarning_flag
>> = 0, visited = 0,
>> used_flag = 1, nothrow_flag = 0, static_flag = 0, public_flag = 0,
>> private_flag = 0,
>> protected_flag = 0, deprecated_flag = 0, default_def_flag = 0, u = {bits =
>> {lang_flag_0 = 0,
>> lang_flag_1 = 0, lang_flag_2 = 0, lang_flag_3 = 0, lang_flag_4 = 0,
>> lang_flag_5 = 0,
>> lang_flag_6 = 0, saturating_flag = 0, unsigned_flag = 0, packed_flag =
>> 0, user_align = 0,
>> nameless_flag = 1, spare0 = 0, spare1 = 0, address_space = 0}, length =
>> 2048,
>> version = 2048}}, chain = 0x0, abstract_flag = 0, block_num = 14, locus =
>> 0,
>> vars = 0x7ffff608bc78, nonlocalized_vars = 0x0, subblocks = 0x0, supercontext
>> = 0x7ffff60c00f0,
>> abstract_origin = 0x0, fragment_origin = 0x0, fragment_chain = 0x0}
>>
>> Here's the fragment of assembly code between .LBB14 and .LBE14:
>>
>> .LBB14:
>> # pr49115.C:21
>> .loc 1 21 0
>> call __cxa_begin_catch
>> .LVL7:
>> call __cxa_end_catch
>> .LVL8:
>> .p2align 4,,5
>> # SUCC: 3 [100.0%] count:1
>> jmp .L15
>> .cfi_endproc
>> .section .text.unlikely
>> .cfi_startproc
>> .cfi_personality 0x3,__gxx_personality_v0
>> .cfi_lsda 0x3,.LLSDAC4
>> # BLOCK 6 freq:5000 seq:4
>> # PRED: 4 [50.0%] (CROSSING,CAN_FALLTHRU)
>> .L14:
>> .cfi_def_cfa_offset 16
>> .p2align 4,,8
>> .LEHB1:
>> # SUCC:
>> call _Unwind_Resume
>> .LEHE1:
>> .LVL9:
>> .LBE14:
>> .LBE15:
>> .cfi_endproc
>>
>> You can see that the block from .LBB14 to .LBE14 has been split across two
>> sections. In order for dwarf2out to generate the proper debug info,
>> BLOCK_FRAGMENT_CHAIN(stmt) needs to be non-NULL. I'm not sure why that's not
>> happening when the block is split.
>
> It looks like this is all done during the final pass when assembly is
> being emitted. In final_start_function the NOTE_INSN_BLOCK_{BEG/END}
> notes are inserted based on lexical scopes (in
> reemit_insn_block_notes). At the end of reemit_insn_block_notes,
> reorder_blocks is called to identify blocks references by more than
> one NOTE_INSN_BLOCK_{BEG/END}. Any such blocks are duplicated and the
> BLOCK_FRAGMENT_CHAIN is setup.
>
> I'm not familiar with this code, but perhaps when a switch section
> note is seen by reemit_insn_block_notes, it should invoke change_scope
> to emit the necessary NOTE_INSN_BLOCK_* notes?
Indeed the following patch fixes the problem. Cary, are you familiar
with this code and does it seem like a reasonable fix? If so I will
send to trunk for review. It passed the gcc regression testing.
Index: final.c
===================================================================
--- final.c (revision 201461)
+++ final.c (working copy)
@@ -1560,6 +1560,16 @@ change_scope (rtx orig_insn, tree s1, tree s2)
tree ts1 = s1, ts2 = s2;
tree s;
+ if (NOTE_P (orig_insn) && NOTE_KIND (orig_insn) ==
NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ {
+ gcc_assert (s1 == s1);
+ rtx note = emit_note_before (NOTE_INSN_BLOCK_END, orig_insn);
+ NOTE_BLOCK (note) = s1;
+ note = emit_note_before (NOTE_INSN_BLOCK_BEG, next_insn (orig_insn));
+ NOTE_BLOCK (note) = s1;
+ return;
+ }
+
while (ts1 != ts2)
{
gcc_assert (ts1 && ts2);
@@ -1604,12 +1614,16 @@ reemit_insn_block_notes (void)
rtx insn, note;
insn = get_insns ();
- if (!active_insn_p (insn))
- insn = next_active_insn (insn);
- for (; insn; insn = next_active_insn (insn))
+ for (; insn; insn = next_insn (insn))
{
tree this_block;
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ change_scope (insn, cur_block, cur_block);
+
+ if (!active_insn_p (insn))
+ continue;
+
/* Avoid putting scope notes between jump table and its label. */
if (JUMP_TABLE_DATA_P (insn))
continue;
Thanks,
Teresa
>
> Thanks,
> Teresa
>
>>
>> --
>> You are receiving this mail because:
>> You are on the CC list for the bug.
>> You reported the bug.
>
>
>
> --
> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413