With this patch DW_LNS_set_basic_block opcodes are emitted in the .debug_line section marking the instructions that indicate the beginning of a basic block as specified by the dwarf standards 2,3 and 4.
Tested on x86_64-linux also against gdb's 7.3.1 testsuite. r gcc/Changelog: 2011-11-14 Roberto Agostino Vitillo <raviti...@lbl.gov> * final.c (is_bb_first): New variable. (is_bb_start): New variable. (final_start_function): Initialize above variables. (final_scan_insn): Determine a basic block change and pass it to the debug hook. (notice_source_line): Check for a basic block change. * dwarf2out.c (enum dw_line_info_opcode): Add new value. (dwarf2out_source_line): Add new parameter and change callers. Emit basic block changes in .loc directive or in the current line table. (output_one_line_info_table): Emit basic block changes in the .debug_line section. * debug.c (struct gcc_debug_hooks): Change placeholder for source_line hook. (debug_nothing_int_charstar_int_bool): Replaced by.. (debug_nothing_int_charstar_int_bool_bool): ...this. * vmsdbgout.c (vmsdbgout_source_line): Add new parameter. All callers changed. * dbxout.c (dbxout_source_line): Add new parameter. All callers changed. * sdbout.c (sdbout_source_line): Add new parameter. Index: ../gcc/gcc/final.c =================================================================== --- ../gcc/gcc/final.c (revision 181345) +++ ../gcc/gcc/final.c (working copy) @@ -133,6 +133,12 @@ /* Discriminator of current block. */ static int discriminator; +/* True if the current basic block is the first one. */ +static bool is_bb_first; + +/* True if a new basic block was found. */ +static bool is_bb_start; + /* Highest line number in current block. */ static int high_block_linenum; @@ -1536,6 +1542,7 @@ last_filename = locator_file (prologue_locator); last_linenum = locator_line (prologue_locator); last_discriminator = discriminator = 0; + is_bb_first = is_bb_start = true; high_block_linenum = high_function_linenum = last_linenum; @@ -1945,6 +1952,7 @@ *seen |= SEEN_BB; discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; + is_bb_start = true; break; @@ -2179,7 +2187,7 @@ rtx body = PATTERN (insn); int insn_code_number; const char *templ; - bool is_stmt; + bool is_stmt = false; /* Reset this early so it is correct for ASM statements. */ current_insn_predicate = NULL_RTX; @@ -2282,8 +2290,12 @@ note in a row. */ if (!DECL_IGNORED_P (current_function_decl) && notice_source_line (insn, &is_stmt)) - (*debug_hooks->source_line) (last_linenum, last_filename, - last_discriminator, is_stmt); + { + (*debug_hooks->source_line) (last_linenum, last_filename, + last_discriminator, is_stmt, + is_bb_start); + is_bb_start = false; + } if (GET_CODE (body) == ASM_INPUT) { @@ -2745,6 +2757,7 @@ } if (!DECL_IGNORED_P (current_function_decl)) debug_hooks->var_location (insn); + is_bb_start = true; } /* Output assembler code from the template. */ @@ -2787,8 +2800,14 @@ linenum = insn_line (insn); } + if (is_bb_first) + { + /* Source line was already emitted in the function prologue */ + is_bb_first = is_bb_start = false; + } + if (filename == NULL) - return false; + return is_bb_start; if (force_source_line || filename != last_filename @@ -2810,11 +2829,10 @@ output the line table entry with is_stmt false so the debugger does not treat this as a breakpoint location. */ last_discriminator = discriminator; - *is_stmt = false; return true; } - return false; + return is_bb_start; } /* For each operand in INSN, simplify (subreg (reg)) so that it refers Index: ../gcc/gcc/vmsdbgout.c =================================================================== --- ../gcc/gcc/vmsdbgout.c (revision 181345) +++ ../gcc/gcc/vmsdbgout.c (working copy) @@ -157,7 +157,7 @@ static void vmsdbgout_begin_block (unsigned int, unsigned int); static void vmsdbgout_end_block (unsigned int, unsigned int); static bool vmsdbgout_ignore_block (const_tree); -static void vmsdbgout_source_line (unsigned int, const char *, int, bool); +static void vmsdbgout_source_line (unsigned int, const char *, int, bool, bool); static void vmsdbgout_begin_prologue (unsigned int, const char *); static void vmsdbgout_end_prologue (unsigned int, const char *); static void vmsdbgout_end_function (unsigned int); @@ -1162,7 +1162,7 @@ ASM_OUTPUT_LABEL (asm_out_file, label); /* VMS PCA expects every PC range to correlate to some line and file. */ - vmsdbgout_source_line (line, file, 0, true); + vmsdbgout_source_line (line, file, 0, true, false); } } @@ -1202,7 +1202,7 @@ /* VMS PCA expects every PC range to correlate to some line and file. */ - vmsdbgout_source_line (line, file, 0, true); + vmsdbgout_source_line (line, file, 0, true, false); } } } @@ -1228,7 +1228,7 @@ ASM_OUTPUT_LABEL (asm_out_file, label); /* VMS PCA expects every PC range to correlate to some line and file. */ - vmsdbgout_source_line (line, file, 0, true); + vmsdbgout_source_line (line, file, 0, true, false); } } @@ -1389,10 +1389,11 @@ static void vmsdbgout_source_line (register unsigned line, register const char *filename, - int discriminator, bool is_stmt) + int discriminator, bool is_stmt, bool is_bb_start) { if (write_symbols == VMS_AND_DWARF2_DEBUG) - (*dwarf2_debug_hooks.source_line) (line, filename, discriminator, is_stmt); + (*dwarf2_debug_hooks.source_line) (line, filename, discriminator, is_stmt, + is_bb_start); if (debug_info_level >= DINFO_LEVEL_TERSE) { Index: ../gcc/gcc/debug.c =================================================================== --- ../gcc/gcc/debug.c (revision 181345) +++ ../gcc/gcc/debug.c (working copy) @@ -33,29 +33,29 @@ debug_nothing_int_charstar, debug_nothing_int_charstar, debug_nothing_int, - debug_nothing_int_int, /* begin_block */ - debug_nothing_int_int, /* end_block */ - debug_true_const_tree, /* ignore_block */ - debug_nothing_int_charstar_int_bool, /* source_line */ - debug_nothing_int_charstar, /* begin_prologue */ - debug_nothing_int_charstar, /* end_prologue */ - debug_nothing_int_charstar, /* begin_epilogue */ - debug_nothing_int_charstar, /* end_epilogue */ - debug_nothing_tree, /* begin_function */ - debug_nothing_int, /* end_function */ - debug_nothing_tree, /* function_decl */ - debug_nothing_tree, /* global_decl */ - debug_nothing_tree_int, /* type_decl */ - debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */ - debug_nothing_tree, /* deferred_inline_function */ - debug_nothing_tree, /* outlining_inline_function */ - debug_nothing_rtx, /* label */ - debug_nothing_int, /* handle_pch */ - debug_nothing_rtx, /* var_location */ - debug_nothing_void, /* switch_text_section */ - debug_nothing_tree_tree, /* set_name */ - 0, /* start_end_main_source_file */ - TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */ + debug_nothing_int_int, /* begin_block */ + debug_nothing_int_int, /* end_block */ + debug_true_const_tree, /* ignore_block */ + debug_nothing_int_charstar_int_bool_bool, /* source_line */ + debug_nothing_int_charstar, /* begin_prologue */ + debug_nothing_int_charstar, /* end_prologue */ + debug_nothing_int_charstar, /* begin_epilogue */ + debug_nothing_int_charstar, /* end_epilogue */ + debug_nothing_tree, /* begin_function */ + debug_nothing_int, /* end_function */ + debug_nothing_tree, /* function_decl */ + debug_nothing_tree, /* global_decl */ + debug_nothing_tree_int, /* type_decl */ + debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx, /* label */ + debug_nothing_int, /* handle_pch */ + debug_nothing_rtx, /* var_location */ + debug_nothing_void, /* switch_text_section */ + debug_nothing_tree_tree, /* set_name */ + 0, /* start_end_main_source_file */ + TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */ }; /* This file contains implementations of each debug hook that do @@ -114,10 +114,11 @@ } void -debug_nothing_int_charstar_int_bool (unsigned int line ATTRIBUTE_UNUSED, - const char *text ATTRIBUTE_UNUSED, - int discriminator ATTRIBUTE_UNUSED, - bool is_stmt ATTRIBUTE_UNUSED) +debug_nothing_int_charstar_int_bool_bool (unsigned int line ATTRIBUTE_UNUSED, + const char *text ATTRIBUTE_UNUSED, + int discriminator ATTRIBUTE_UNUSED, + bool is_stmt ATTRIBUTE_UNUSED, + bool is_bb_start ATTRIBUTE_UNUSED) { } Index: ../gcc/gcc/debug.h =================================================================== --- ../gcc/gcc/debug.h (revision 181345) +++ ../gcc/gcc/debug.h (working copy) @@ -65,7 +65,7 @@ /* Record a source file location at (FILE, LINE, DISCRIMINATOR). */ void (* source_line) (unsigned int line, const char *file, - int discriminator, bool is_stmt); + int discriminator, bool is_stmt, bool is_bb_start); /* Called at start of prologue code. LINE is the first line in the function. */ @@ -152,8 +152,9 @@ extern void debug_nothing_void (void); extern void debug_nothing_charstar (const char *); extern void debug_nothing_int_charstar (unsigned int, const char *); -extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *, - int, bool); +extern void debug_nothing_int_charstar_int_bool_bool (unsigned int, + const char *, int, + bool, bool); extern void debug_nothing_int (unsigned int); extern void debug_nothing_int_int (unsigned int, unsigned int); extern void debug_nothing_tree (tree); Index: ../gcc/gcc/dbxout.c =================================================================== --- ../gcc/gcc/dbxout.c (revision 181345) +++ ../gcc/gcc/dbxout.c (working copy) @@ -333,7 +333,7 @@ /* The debug hooks structure. */ #if defined (DBX_DEBUGGING_INFO) -static void dbxout_source_line (unsigned int, const char *, int, bool); +static void dbxout_source_line (unsigned int, const char *, int, bool, bool); static void dbxout_begin_prologue (unsigned int, const char *); static void dbxout_source_file (const char *); static void dbxout_function_end (tree); @@ -1295,7 +1295,7 @@ /* pre-increment the scope counter */ scope_labelno++; - dbxout_source_line (lineno, filename, 0, true); + dbxout_source_line (lineno, filename, 0, true, true); /* Output function begin block at function scope, referenced by dbxout_block, dbxout_source_line and dbxout_function_end. */ emit_pending_bincls_if_required (); @@ -1308,7 +1308,8 @@ static void dbxout_source_line (unsigned int lineno, const char *filename, int discriminator ATTRIBUTE_UNUSED, - bool is_stmt ATTRIBUTE_UNUSED) + bool is_stmt ATTRIBUTE_UNUSED, + bool is_bb_start ATTRIBUTE_UNUSED) { dbxout_source_file (filename); Index: ../gcc/gcc/dwarf2out.c =================================================================== --- ../gcc/gcc/dwarf2out.c (revision 181345) +++ ../gcc/gcc/dwarf2out.c (working copy) @@ -96,7 +96,7 @@ #include "cfglayout.h" #include "opts.h" -static void dwarf2out_source_line (unsigned int, const char *, int, bool); +static void dwarf2out_source_line (unsigned int, const char *, int, bool, bool); static rtx last_var_location_insn; static rtx cached_next_real_insn; @@ -1017,7 +1017,7 @@ prologue case, not the eh frame case. */ #ifdef DWARF2_DEBUGGING_INFO if (file) - dwarf2out_source_line (line, file, 0, true); + dwarf2out_source_line (line, file, 0, true, true); #endif if (dwarf2out_do_cfi_asm ()) @@ -2754,7 +2754,10 @@ LI_set_epilogue_begin, /* Emit a DW_LNE_set_discriminator. */ - LI_set_discriminator + LI_set_discriminator, + + /* Emit a DW_LNS_set_basic_block. */ + LI_set_basic_block }; typedef struct GTY(()) dw_line_info_struct { @@ -9389,6 +9392,10 @@ dw2_asm_output_data (1, DW_LNE_set_discriminator, NULL); dw2_asm_output_data_uleb128 (ent->val, NULL); break; + + case LI_set_basic_block: + dw2_asm_output_data (1, DW_LNS_set_basic_block, "basic_block"); + break; } } @@ -20427,7 +20434,7 @@ static void dwarf2out_source_line (unsigned int line, const char *filename, - int discriminator, bool is_stmt) + int discriminator, bool is_stmt, bool is_bb_start) { unsigned int file_num; dw_line_info_table *table; @@ -20492,6 +20499,8 @@ fputs (" discriminator ", asm_out_file); fprint_ul (asm_out_file, (unsigned long) discriminator); } + if (is_bb_start) + fputs (" basic_block", asm_out_file); putc ('\n', asm_out_file); } else @@ -20507,6 +20516,8 @@ push_dw_line_info_entry (table, LI_set_discriminator, discriminator); if (is_stmt != table->is_stmt) push_dw_line_info_entry (table, LI_negate_stmt, 0); + if (is_bb_start) + push_dw_line_info_entry (table, LI_set_basic_block, 1); push_dw_line_info_entry (table, LI_set_line, line); } Index: ../gcc/gcc/sdbout.c =================================================================== --- ../gcc/gcc/sdbout.c (revision 181345) +++ ../gcc/gcc/sdbout.c (working copy) @@ -117,7 +117,8 @@ static void sdbout_end_source_file (unsigned int); static void sdbout_begin_block (unsigned int, unsigned int); static void sdbout_end_block (unsigned int, unsigned int); -static void sdbout_source_line (unsigned int, const char *, int, bool); +static void sdbout_source_line (unsigned int, const char *, int, + bool, bool); static void sdbout_end_epilogue (unsigned int, const char *); static void sdbout_global_decl (tree); #ifndef MIPS_DEBUGGING_INFO @@ -1548,7 +1549,8 @@ static void sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED, int discriminator ATTRIBUTE_UNUSED, - bool is_stmt ATTRIBUTE_UNUSED) + bool is_stmt ATTRIBUTE_UNUSED, + bool is_bb_start ATTRIBUTE_UNUSED) { /* COFF relative line numbers must be positive. */ if ((int) line > sdb_begin_function_line)