diff mbox

[debug] Emit basic block markers in .debug_line section

Message ID C8DBFE56-A48D-4368-B6E4-757842437F00@lbl.gov
State New
Headers show

Commit Message

Roberto Agostino Vitillo Nov. 15, 2011, 2:50 a.m. UTC
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  <ravitillo@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.

Comments

Tom Tromey Nov. 15, 2011, 3:17 p.m. UTC | #1
>>>>> "Roberto" == Roberto Agostino Vitillo <ravitillo@lbl.gov> writes:

Roberto> With this patch DW_LNS_set_basic_block opcodes are emitted in
Roberto> the .debug_line section marking the instructions that indicate
Roberto> the beginning of a basic block as specified by the dwarf
Roberto> standards 2,3 and 4.

I'm curious to know what use you have for this.

Tom
Roberto Agostino Vitillo Nov. 15, 2011, 6:31 p.m. UTC | #2
I considered to use it as a starting point to build the control-flow graph of 
a function in order to display it in a custom profiler we use internally since
I could assume that I had the debugging information and I had to read the 
.debug_line section anyway to get the source lines.
I ended up not using it and it's clear to me that its practical uses may be 
questionable ("fast" single stepping in a debugger?) but I thought it might 
be worth to share it.

r

On Nov 15, 2011, at 7:17 AM, Tom Tromey wrote:

>>>>>> "Roberto" == Roberto Agostino Vitillo <ravitillo@lbl.gov> writes:
> 
> Roberto> With this patch DW_LNS_set_basic_block opcodes are emitted in
> Roberto> the .debug_line section marking the instructions that indicate
> Roberto> the beginning of a basic block as specified by the dwarf
> Roberto> standards 2,3 and 4.
> 
> I'm curious to know what use you have for this.
> 
> Tom
Tom Tromey Nov. 18, 2011, 2:44 p.m. UTC | #3
>>>>> "Roberto" == Roberto Agostino Vitillo <ravitillo@lbl.gov> writes:

Roberto> I ended up not using it and it's clear to me that its practical
Roberto> uses may be questionable ("fast" single stepping in a
Roberto> debugger?) but I thought it might be worth to share it.

Thanks.

I think that if there is no use for the output, then the patch should
not go in.

Tom
diff mbox

Patch

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)