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]

[PATCH] GCOV: add cache for streamed locations.


Hi.

Last patch from GCOV series is about not streaming of redundant lines
for a basic-block. It helps to fix few issues.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
Will install in couple of days if no objection.

Martin

gcc/ChangeLog:

2018-07-25  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/85338
        PR gcov-profile/85350
        PR gcov-profile/85372
        * profile.c (struct location_triplet): New.
	(struct location_triplet_hash): Likewise.
	(output_location): Do not output a BB that
        is already recorded for a line.
	(branch_prob): Use streamed_locations.

gcc/testsuite/ChangeLog:

2018-07-25  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/85338
        PR gcov-profile/85350
        PR gcov-profile/85372
	* gcc.misc-tests/gcov-pr85338.c: New test.
	* gcc.misc-tests/gcov-pr85350.c: New test.
	* gcc.misc-tests/gcov-pr85372.c: New test.
---
 gcc/profile.c                               | 91 +++++++++++++++++++--
 gcc/testsuite/gcc.misc-tests/gcov-pr85338.c | 21 +++++
 gcc/testsuite/gcc.misc-tests/gcov-pr85350.c | 21 +++++
 gcc/testsuite/gcc.misc-tests/gcov-pr85372.c | 28 +++++++
 4 files changed, 153 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr85338.c
 create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
 create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr85372.c


diff --git a/gcc/profile.c b/gcc/profile.c
index 00f37b657a4..cb51e0d4c51 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -919,17 +919,90 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
     free (histogram_counts[t]);
 }
 
+/* Location triplet which records a location.  */
+struct location_triplet
+{
+  const char *filename;
+  int lineno;
+  int bb_index;
+};
+
+/* Traits class for streamed_locations hash set below.  */
+
+struct location_triplet_hash : typed_noop_remove <location_triplet>
+{
+  typedef location_triplet value_type;
+  typedef location_triplet compare_type;
+
+  static hashval_t
+  hash (const location_triplet &ref)
+  {
+    inchash::hash hstate (0);
+    if (ref.filename)
+      hstate.add_int (strlen (ref.filename));
+    hstate.add_int (ref.lineno);
+    hstate.add_int (ref.bb_index);
+    return hstate.end ();
+  }
+
+  static bool
+  equal (const location_triplet &ref1, const location_triplet &ref2)
+  {
+    return ref1.lineno == ref2.lineno
+      && ref1.bb_index == ref2.bb_index
+      && ref1.filename != NULL
+      && ref2.filename != NULL
+      && strcmp (ref1.filename, ref2.filename) == 0;
+  }
+
+  static void
+  mark_deleted (location_triplet &ref)
+  {
+    ref.lineno = -1;
+  }
+
+  static void
+  mark_empty (location_triplet &ref)
+  {
+    ref.lineno = -2;
+  }
+
+  static bool
+  is_deleted (const location_triplet &ref)
+  {
+    return ref.lineno == -1;
+  }
+
+  static bool
+  is_empty (const location_triplet &ref)
+  {
+    return ref.lineno == -2;
+  }
+};
+
+
+
+
 /* When passed NULL as file_name, initialize.
    When passed something else, output the necessary commands to change
    line to LINE and offset to FILE_NAME.  */
 static void
-output_location (char const *file_name, int line,
+output_location (hash_set<location_triplet_hash> *streamed_locations,
+		 char const *file_name, int line,
 		 gcov_position_t *offset, basic_block bb)
 {
   static char const *prev_file_name;
   static int prev_line;
   bool name_differs, line_differs;
 
+  location_triplet triplet;
+  triplet.filename = file_name;
+  triplet.lineno = line;
+  triplet.bb_index = bb ? bb->index : 0;
+
+  if (streamed_locations->add (triplet))
+    return;
+
   if (!file_name)
     {
       prev_file_name = NULL;
@@ -1018,6 +1091,8 @@ branch_prob (void)
   flow_call_edges_add (NULL);
   add_noreturn_fake_exit_edges ();
 
+  hash_set <location_triplet_hash> streamed_locations;
+
   /* We can't handle cyclic regions constructed using abnormal edges.
      To avoid these we replace every source of abnormal edge by a fake
      edge from entry node and every destination by fake edge to exit.
@@ -1254,7 +1329,7 @@ branch_prob (void)
 
       /* Line numbers.  */
       /* Initialize the output.  */
-      output_location (NULL, 0, NULL, NULL);
+      output_location (&streamed_locations, NULL, 0, NULL, NULL);
 
       hash_set<int_hash <location_t, 0, 2> > seen_locations;
 
@@ -1268,8 +1343,8 @@ branch_prob (void)
 	      location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
 	      seen_locations.add (loc);
 	      expanded_location curr_location = expand_location (loc);
-	      output_location (curr_location.file, curr_location.line,
-			       &offset, bb);
+	      output_location (&streamed_locations, curr_location.file,
+			       curr_location.line, &offset, bb);
 	    }
 
 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -1279,8 +1354,8 @@ branch_prob (void)
 	      if (!RESERVED_LOCATION_P (loc))
 		{
 		  seen_locations.add (loc);
-		  output_location (gimple_filename (stmt), gimple_lineno (stmt),
-				   &offset, bb);
+		  output_location (&streamed_locations, gimple_filename (stmt),
+				   gimple_lineno (stmt), &offset, bb);
 		}
 	    }
 
@@ -1294,8 +1369,8 @@ branch_prob (void)
 	      && !seen_locations.contains (loc))
 	    {
 	      expanded_location curr_location = expand_location (loc);
-	      output_location (curr_location.file, curr_location.line,
-			       &offset, bb);
+	      output_location (&streamed_locations, curr_location.file,
+			       curr_location.line, &offset, bb);
 	    }
 
 	  if (offset)
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85338.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85338.c
new file mode 100644
index 00000000000..d1e16d29c7a
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85338.c
@@ -0,0 +1,21 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+void Test(long long Val, int Amt)
+{
+  __builtin_printf("  lshr: 0x%llx \t\t shl: 0x%llx\n", Val >> Amt, Val << Amt);  /* count(1) */
+  __builtin_printf("  lshr: 0x%llx\t\tshl: 0x%llx\n",  /* count(1) */
+    Val >> Amt, Val << Amt);
+  __builtin_printf("  lshr: 0x%llx \t\t shl: 0x%llx\n",  /* count(1) */
+    (unsigned long long)Val >> Amt, Val << Amt);
+}
+
+int main()
+{
+  Test(10, 4);
+
+  return 0;
+}
+
+
+/* { dg-final { run-gcov gcov-pr85338.c } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
new file mode 100644
index 00000000000..0383b81fdfb
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c
@@ -0,0 +1,21 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int main (void)
+{
+  const int t = 2; /* count(1) */
+  struct s1 {	/* count(1) */
+    int x;
+    int g[t];
+  };
+
+  struct s2 {
+    int x;
+    int g[2];
+  };
+
+  __builtin_printf("Sucess!\n");
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr85350.c } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85372.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85372.c
new file mode 100644
index 00000000000..7c90e68b0dc
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85372.c
@@ -0,0 +1,28 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+/* { dg-require-effective-target indirect_jumps } */
+
+void *buf[5];
+
+void fjmp (void) {
+  __builtin_longjmp (buf, 1);
+}
+
+int main(void)
+{
+  int last = 0;
+
+  if (__builtin_setjmp (buf) == 0) {	/* count(2) */
+    __builtin_printf("True  branch\n");
+    while (1) {
+      last = 1;	/* count(1) */
+      fjmp ();	/* count(1) */
+    }
+  } else {
+    __builtin_printf("False branch\n");
+  }
+
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr85372.c } } */


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