This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/57451] Incorrect debug ranges emitted for -freorder-blocks-and-partition -g


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]