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 <tejohn...@google.com> wrote: > On Fri, Jun 14, 2013 at 4:19 PM, ccoutant at gcc dot gnu.org > <gcc-bugzi...@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 | tejohn...@google.com | 408-460-2413