This is the mail archive of the gcc-patches@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]

[google][patch] Track discriminators by instruction instead of by basic block (issue4441075)


commit 76c5256b18ce0357dc0fc38ce143b8979318b823
Author: Cary Coutant <ccoutant@google.com>
Date:   Thu Apr 28 10:48:56 2011 -0700

    Track discriminators by instruction instead of by basic block
    
    Rework discriminator assignment so that it attaches the discriminator
    to the source location of each instruction instead of to the basic
    block itself.

    This patch was submitted for review in Nov. 2009:
    http://gcc.gnu.org/ml/gcc-patches/2009-11/msg00563.html

    It's not ready for trunk yet because it does not yet preserve
    the discriminators across LTO, so I'd like to put it in
    google/main until I have a chance to get that part working.

    OK for google/main?

    -cary

M	gcc/basic-block.h
M	gcc/cfghooks.c
M	gcc/cfglayout.c
M	gcc/final.c
M	gcc/gimple-pretty-print.c
M	gcc/input.c
M	gcc/input.h
M	gcc/print-rtl.c
M	gcc/rtl.h
M	gcc/tree-cfg.c
M	gcc/tree-pretty-print.c

Tested:
  Bootstrapped on x86_64.

ChangeLog:

2011-04-28  Cary Coutant  <ccoutant@google.com>

	* basic-block.h (struct basic_block_def): Remove discriminator field.
	* cfghooks.c (split_block): Remove discriminator field.
	* cfglayout.c (insn_discriminator): New function.
	* final.c (discriminator): Remove.
	(override_discriminator): New file-scope variable.
	(final_start_function): Remove tracking of discriminator by basic
	block.
	(final_scan_insn): Track discriminator by instruction.
	(notice_source_line): Check for discriminator override. Get
	discriminator from instruction.
	* gimple-pretty-print.c (dump_gimple_stmt): Print discriminator.
	(dump_bb_header): Don't print discriminator.
	* input.c: Include vecprim.h.
	(discriminator_location_locations): New variable.
	(discriminator_location_discriminators): New variable.
	(min_discriminator_location): New variable.
	(expand_location): Use map_discriminator_location.
	(location_with_discriminator): New function.
	(has_discriminator): New function.
	(map_discriminator_location): New function.
	(get_discriminator_from_locus): New function.
	* input.h (location_with_discriminator): New function.
	(has_discriminator): New function.
	(map_discriminator_location): New function.
	(get_discriminator_from_locus): New function.
	* print-rtl.c (print_rtx): Print discriminator.
	* rtl.h (insn_discriminator): New function.
	* tree-cfg.c: Include input.h.
	(assign_discriminator): Assign discriminators to instructions rather
	than to the basic block.
	* tree-pretty-print.c (dump_location): Print discriminator.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 946fe9d..f46c25c 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -162,9 +162,6 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d
   /* Expected frequency.  Normalized to be in range 0 to BB_FREQ_MAX.  */
   int frequency;
 
-  /* The discriminator for this block.  */
-  int discriminator;
-
   /* Various flags.  See BB_* below.  */
   int flags;
 };
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index c4c51cc..d77dc7c 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -437,7 +437,6 @@ split_block (basic_block bb, void *i)
   new_bb->count = bb->count;
   new_bb->frequency = bb->frequency;
   new_bb->loop_depth = bb->loop_depth;
-  new_bb->discriminator = bb->discriminator;
 
   if (dom_info_available_p (CDI_DOMINATORS))
     {
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 548e21f..cb52634 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -567,6 +567,16 @@ insn_file (const_rtx insn)
   return locator_file (INSN_LOCATOR (insn));
 }
 
+/* Return discriminator of the statement that produced this insn.  */
+int
+insn_discriminator (const_rtx insn)
+{
+  int loc = INSN_LOCATOR (insn);
+  if (!loc)
+    return 0;
+  return get_discriminator_from_locus (locator_location (loc));
+}
+
 /* Return true if LOC1 and LOC2 locators have the same location and scope.  */
 bool
 locator_eq (int loc1, int loc2)
diff --git a/gcc/final.c b/gcc/final.c
index df5d7d5..d89938c 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -134,9 +134,6 @@ static int last_linenum;
 /* Last discriminator written to assembly.  */
 static int last_discriminator;
 
-/* Discriminator of current block.  */
-static int discriminator;
-
 /* Highest line number in current block.  */
 static int high_block_linenum;
 
@@ -146,9 +143,10 @@ static int high_function_linenum;
 /* Filename of last NOTE.  */
 static const char *last_filename;
 
-/* Override filename and line number.  */
+/* Override filename, line number, and discriminator.  */
 static const char *override_filename;
 static int override_linenum;
+static int override_discriminator;
 
 /* Whether to force emission of a line note before the next insn.  */
 static bool force_source_line = false;
@@ -1539,7 +1537,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
 
   last_filename = locator_file (prologue_locator);
   last_linenum = locator_line (prologue_locator);
-  last_discriminator = discriminator = 0;
+  last_discriminator = 0;
 
   high_block_linenum = high_function_linenum = last_linenum;
 
@@ -1943,8 +1941,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  else
 	    *seen |= SEEN_BB;
 
-          discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
-
 	  break;
 
 	case NOTE_INSN_EH_REGION_BEG:
@@ -2029,6 +2025,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 		{
 		  override_filename = LOCATION_FILE (*locus_ptr);
 		  override_linenum = LOCATION_LINE (*locus_ptr);
+		  override_discriminator =
+		      get_discriminator_from_locus (*locus_ptr);
 		}
 	    }
 	  break;
@@ -2062,11 +2060,14 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 		{
 		  override_filename = LOCATION_FILE (*locus_ptr);
 		  override_linenum = LOCATION_LINE (*locus_ptr);
+		  override_discriminator =
+		      get_discriminator_from_locus (*locus_ptr);
 		}
 	      else
 		{
 		  override_filename = NULL;
 		  override_linenum = 0;
+		  override_discriminator = 0;
 		}
 	    }
 	  break;
@@ -2788,16 +2789,19 @@ notice_source_line (rtx insn, bool *is_stmt)
 {
   const char *filename;
   int linenum;
+  int discriminator;
 
   if (override_filename)
     {
       filename = override_filename;
       linenum = override_linenum;
+      discriminator = override_discriminator;
     }
   else
     {
       filename = insn_file (insn);
       linenum = insn_line (insn);
+      discriminator = insn_discriminator (insn);
     }
 
   if (filename == NULL)
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index b27b1a5..312d98d 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1656,7 +1656,9 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
 
   if ((flags & TDF_LINENO) && gimple_has_location (gs))
     {
-      expanded_location xloc = expand_location (gimple_location (gs));
+      location_t loc = gimple_location (gs);
+      expanded_location xloc = expand_location (loc);
+      int discriminator = get_discriminator_from_locus (loc);
       pp_character (buffer, '[');
       if (xloc.file)
 	{
@@ -1666,6 +1668,11 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
       pp_decimal_int (buffer, xloc.line);
       pp_string (buffer, ":");
       pp_decimal_int (buffer, xloc.column);
+      if (discriminator)
+	{
+	  pp_string (buffer, " discrim ");
+	  pp_decimal_int (buffer, discriminator);
+	}
       pp_string (buffer, "] ");
     }
 
@@ -1888,12 +1895,6 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
 		pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
 		break;
 	      }
-
-          if (bb->discriminator)
-            {
-              pp_string (buffer, ", discriminator ");
-	      pp_decimal_int (buffer, bb->discriminator);
-            }
 	}
       newline_and_indent (buffer, indent);
 
diff --git a/gcc/input.c b/gcc/input.c
index e5e051f..1f137b6 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "intl.h"
 #include "input.h"
+#include "vec.h"
+#include "vecprim.h"
 
 /* Current position in real source file.  */
 
@@ -30,10 +32,23 @@ location_t input_location;
 
 struct line_maps *line_table;
 
+/* Vectors to map a discriminator-enhanced locus to a real locus and
+   discriminator value.  */
+static VEC(int,heap) *discriminator_location_locations = NULL;
+static VEC(int,heap) *discriminator_location_discriminators = NULL;
+static location_t min_discriminator_location = UNKNOWN_LOCATION;
+
 expanded_location
 expand_location (source_location loc)
 {
   expanded_location xloc;
+
+  /* If LOC describes a location with a discriminator, extract the
+     discriminator and map it to the real location.  */
+  if (min_discriminator_location != UNKNOWN_LOCATION
+      && loc >= min_discriminator_location)
+    loc = map_discriminator_location (loc);
+
   if (loc <= BUILTINS_LOCATION)
     {
       xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
@@ -51,3 +66,57 @@ expand_location (source_location loc)
     };
   return xloc;
 }
+
+/* Associate the DISCRIMINATOR with LOCUS, and return a new locus.
+   We associate discriminators with a locus by allocating location_t
+   values beyond those assigned by libcpp.  Each new value is mapped
+   directly to a real location_t value, and separately to the
+   discriminator.  */
+
+location_t
+location_with_discriminator (location_t locus, int discriminator)
+{
+  static int next_discriminator_location = 0;
+
+  if (min_discriminator_location == UNKNOWN_LOCATION)
+    {
+      min_discriminator_location = line_table->highest_location + 1;
+      next_discriminator_location = min_discriminator_location;
+    }
+
+  VEC_safe_push (int, heap, discriminator_location_locations, (int) locus);
+  VEC_safe_push (int, heap, discriminator_location_discriminators,
+		 discriminator);
+  return next_discriminator_location++;
+}
+
+/* Return TRUE if LOCUS represents a location with a discriminator.  */
+
+bool
+has_discriminator (location_t locus)
+{
+  return (min_discriminator_location != UNKNOWN_LOCATION
+  	  && locus >= min_discriminator_location);
+}
+
+/* Return the real location_t value for LOCUS.  */
+
+location_t
+map_discriminator_location (location_t locus)
+{
+  if (! has_discriminator (locus))
+    return locus;
+  return (location_t) VEC_index (int, discriminator_location_locations,
+				 locus - min_discriminator_location);
+}
+
+/* Return the discriminator for LOCUS.  */
+
+int
+get_discriminator_from_locus (location_t locus)
+{
+  if (! has_discriminator (locus))
+    return 0;
+  return VEC_index (int, discriminator_location_discriminators,
+		    locus - min_discriminator_location);
+}
diff --git a/gcc/input.h b/gcc/input.h
index 5929064..6b79871 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -59,6 +59,11 @@ typedef source_location location_t;
 
 extern location_t input_location;
 
+extern location_t location_with_discriminator (location_t, int);
+extern bool has_discriminator (location_t);
+extern location_t map_discriminator_location (location_t);
+extern int get_discriminator_from_locus (location_t);
+
 #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
 #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
 
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index a0f9dfb..2edea26 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -403,7 +403,13 @@ print_rtx (const_rtx in_rtx)
 		redundant with line number information and do not print anything
 		when there is no location information available.  */
 	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
-	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
+	      {
+		int discriminator = insn_discriminator (in_rtx);
+		fprintf (outfile, " %s:%i", insn_file (in_rtx),
+			 insn_line (in_rtx));
+		if (discriminator)
+		  fprintf (outfile, " discrim %d", discriminator);
+	      }
 #endif
 	  }
 	else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 67dbf2b..6d398de 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1751,6 +1751,7 @@ extern rtx prev_cc0_setter (rtx);
 /* In cfglayout.c  */
 extern int insn_line (const_rtx);
 extern const char * insn_file (const_rtx);
+extern int insn_discriminator (const_rtx);
 extern location_t locator_location (int);
 extern int locator_line (int);
 extern const char * locator_file (int);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 40f7688..f2bc473 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "output.h"
 #include "flags.h"
+#include "input.h"
 #include "function.h"
 #include "ggc.h"
 #include "langhooks.h"
@@ -760,22 +761,59 @@ same_line_p (location_t locus1, location_t locus2)
           && filename_cmp (from.file, to.file) == 0);
 }
 
-/* Assign a unique discriminator value to block BB if it begins at the same
-   LOCUS as its predecessor block.  */
+/* Assign a unique discriminator value to instructions in block BB that
+   have the same LOCUS as its predecessor block.  */
 
 static void
 assign_discriminator (location_t locus, basic_block bb)
 {
   gimple first_in_to_bb, last_in_to_bb;
+  int discriminator = 0;
 
-  if (locus == 0 || bb->discriminator != 0)
+  if (locus == UNKNOWN_LOCATION)
     return;
 
+  if (has_discriminator (locus))
+    locus = map_discriminator_location (locus);
+
+  /* Check the locus of the first (non-label) instruction in the block.  */
   first_in_to_bb = first_non_label_stmt (bb);
-  last_in_to_bb = last_stmt (bb);
-  if ((first_in_to_bb && same_line_p (locus, gimple_location (first_in_to_bb)))
-      || (last_in_to_bb && same_line_p (locus, gimple_location (last_in_to_bb))))
-    bb->discriminator = next_discriminator_for_locus (locus);
+  if (first_in_to_bb)
+    {
+      location_t first_locus = gimple_location (first_in_to_bb);
+      if (! has_discriminator (first_locus)
+	  && same_line_p (locus, first_locus))
+	discriminator = next_discriminator_for_locus (locus);
+    }
+
+  /* If the first instruction doesn't trigger a discriminator, check the
+     last instruction of the block.  This catches the case where the
+     increment portion of a for loop is placed at the end of the loop
+     body.  */
+  if (discriminator == 0)
+    {
+      last_in_to_bb = last_stmt (bb);
+      if (last_in_to_bb)
+	{
+	   location_t last_locus = gimple_location (last_in_to_bb);
+	   if (! has_discriminator (last_locus)
+	       && same_line_p (locus, last_locus))
+	     discriminator = next_discriminator_for_locus (locus);
+	}
+    }
+
+  if (discriminator != 0)
+    {
+      location_t new_locus = location_with_discriminator (locus, discriminator);
+      gimple_stmt_iterator gsi;
+
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+	{
+	  gimple stmt = gsi_stmt (gsi);
+	  if (same_line_p (locus, gimple_location (stmt)))
+	    gimple_set_location (stmt, new_locus);
+	}
+    }
 }
 
 /* Create the edges for a GIMPLE_COND starting at block BB.  */
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index f2f5a22..4541614 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -456,6 +456,7 @@ static void
 dump_location (pretty_printer *buffer, location_t loc)
 {
   expanded_location xloc = expand_location (loc);
+  int discriminator = get_discriminator_from_locus (loc);
 
   pp_character (buffer, '[');
   if (xloc.file)
@@ -464,6 +465,11 @@ dump_location (pretty_printer *buffer, location_t loc)
       pp_string (buffer, " : ");
     }
   pp_decimal_int (buffer, xloc.line);
+  if (discriminator)
+    {
+      pp_string (buffer, " discrim ");
+      pp_decimal_int (buffer, discriminator);
+    }
   pp_string (buffer, "] ");
 }
 

--
This patch is available for review at http://codereview.appspot.com/4441075


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