Fix GCOV CFG related issues.
authorMartin Liska <mliska@suse.cz>
Tue, 31 Jul 2018 10:33:21 +0000 (12:33 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 31 Jul 2018 10:33:21 +0000 (10:33 +0000)
2018-07-31  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/83813
        PR gcov-profile/84758
        PR gcov-profile/85217
        PR gcov-profile/85332
* profile.c (branch_prob): Do not record GOTO expressions
        for GIMPLE statements which locations are already streamed.
2018-07-31  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/83813
        PR gcov-profile/84758
        PR gcov-profile/85217
        PR gcov-profile/85332
* gcc.misc-tests/gcov-pr83813.c: New test.
* gcc.misc-tests/gcov-pr84758.c: New test.
* gcc.misc-tests/gcov-pr85217.c: New test.
* gcc.misc-tests/gcov-pr85332.c: New test.

From-SVN: r263111

gcc/ChangeLog
gcc/profile.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.misc-tests/gcov-pr83813.c [new file with mode: 0644]
gcc/testsuite/gcc.misc-tests/gcov-pr84758.c [new file with mode: 0644]
gcc/testsuite/gcc.misc-tests/gcov-pr85217.c [new file with mode: 0644]
gcc/testsuite/gcc.misc-tests/gcov-pr85332.c [new file with mode: 0644]

index 3237566..97bc2fd 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-31  Martin Liska  <mliska@suse.cz>
+
+        PR gcov-profile/83813
+        PR gcov-profile/84758
+        PR gcov-profile/85217
+        PR gcov-profile/85332
+       * profile.c (branch_prob): Do not record GOTO expressions
+        for GIMPLE statements which locations are already streamed.
+
 2018-07-31  Olivier Hainque  <hainque@adacore.com>
 
        * gcc.c (handle_spec_function): Accept a soft_matched_part
index 0cd0270..00f37b6 100644 (file)
@@ -1256,6 +1256,8 @@ branch_prob (void)
       /* Initialize the output.  */
       output_location (NULL, 0, NULL, NULL);
 
+      hash_set<int_hash <location_t, 0, 2> > seen_locations;
+
       FOR_EACH_BB_FN (bb, cfun)
        {
          gimple_stmt_iterator gsi;
@@ -1263,8 +1265,9 @@ branch_prob (void)
 
          if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
            {
-             expanded_location curr_location =
-               expand_location (DECL_SOURCE_LOCATION (current_function_decl));
+             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);
            }
@@ -1272,17 +1275,25 @@ branch_prob (void)
          for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
            {
              gimple *stmt = gsi_stmt (gsi);
-             if (!RESERVED_LOCATION_P (gimple_location (stmt)))
-               output_location (gimple_filename (stmt), gimple_lineno (stmt),
-                                &offset, bb);
+             location_t loc = gimple_location (stmt);
+             if (!RESERVED_LOCATION_P (loc))
+               {
+                 seen_locations.add (loc);
+                 output_location (gimple_filename (stmt), gimple_lineno (stmt),
+                                  &offset, bb);
+               }
            }
 
-         /* Notice GOTO expressions eliminated while constructing the CFG.  */
+         /* Notice GOTO expressions eliminated while constructing the CFG.
+            It's hard to distinguish such expression, but goto_locus should
+            not be any of already seen location.  */
+         location_t loc;
          if (single_succ_p (bb)
-             && !RESERVED_LOCATION_P (single_succ_edge (bb)->goto_locus))
+             && (loc = single_succ_edge (bb)->goto_locus)
+             && !RESERVED_LOCATION_P (loc)
+             && !seen_locations.contains (loc))
            {
-             expanded_location curr_location
-               = expand_location (single_succ_edge (bb)->goto_locus);
+             expanded_location curr_location = expand_location (loc);
              output_location (curr_location.file, curr_location.line,
                               &offset, bb);
            }
index 6b4e679..f726e24 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-31  Martin Liska  <mliska@suse.cz>
+
+        PR gcov-profile/83813
+        PR gcov-profile/84758
+        PR gcov-profile/85217
+        PR gcov-profile/85332
+       * gcc.misc-tests/gcov-pr83813.c: New test.
+       * gcc.misc-tests/gcov-pr84758.c: New test.
+       * gcc.misc-tests/gcov-pr85217.c: New test.
+       * gcc.misc-tests/gcov-pr85332.c: New test.
+
 2018-07-31  Ed Schonberg  <schonberg@adacore.com>
 
        * gnat.dg/prot5.adb, gnat.dg/prot5_pkg.adb,
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr83813.c b/gcc/testsuite/gcc.misc-tests/gcov-pr83813.c
new file mode 100644 (file)
index 0000000..ac935b9
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+union U
+{
+    int f0;
+    unsigned char f1;
+};
+
+int main()
+{
+    int i = 0;
+    union U u = {0};  /* count(1) */
+    for (u.f1 = 0; u.f1 != -2; ++u.f1) {
+        i ^= u.f1;  /* count(1) */
+        if (i < 1)  /* count(1) */
+            return 0;  /* count(1) */
+    }
+
+    return 1;
+}
+
+/* { dg-final { run-gcov gcov-pr83813.c } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr84758.c b/gcc/testsuite/gcc.misc-tests/gcov-pr84758.c
new file mode 100644 (file)
index 0000000..2ae6900
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int x, y;
+
+static void
+foo (int a, int b)
+{
+  {
+    if (a == 1 || a == 2)  /* count(1) */
+      {
+       x = 4;  /* count(1) */
+       if (b == 3)  /* count(1) */
+         x = 6;  /* count(1) */
+      }
+    else
+      x = 15;  /* count(#####) */
+  }
+}
+
+int
+main (void)
+{
+  foo (2, 3);
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr84758.c } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85217.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85217.c
new file mode 100644 (file)
index 0000000..86a3c4b
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int a=0;
+
+int main() {
+  for (;; a++) {
+    int c[1];
+    if (a) {
+      break;
+      a;
+      continue; /* count(1) */
+    }
+    continue; /* count(1) */
+  }
+
+  return 0;
+}
+
+/* { dg-final { run-gcov gcov-pr85217.c } } */
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85332.c
new file mode 100644 (file)
index 0000000..73e50b1
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int doit(int sel, int n, void *p)
+{
+  int * const p0 = p;
+
+  switch (sel)
+  {
+    case 0: /* count(3) */
+      do {*p0 += *p0;} while (--n); /* count(3) */
+      return *p0 == 0; /* count(1) */
+
+    default:
+      __builtin_abort ();
+  }
+}
+
+int main()
+{
+  int v0;
+  v0 = 1; doit(0, 3, &v0);
+  __builtin_exit (0);
+}
+
+/* { dg-final { run-gcov gcov-pr85332.c } } */