]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Only write gcov when file output is on [PR119553]
authorJørgen Kvalsvik <j@lambda.is>
Mon, 31 Mar 2025 17:03:37 +0000 (19:03 +0200)
committerJørgen Kvalsvik <j@lambda.is>
Mon, 31 Mar 2025 17:47:14 +0000 (19:47 +0200)
gcov_write_* functions must be guarded so they only are called when
output_to_file is true, like for -fcondition-coverage, otherwise it
triggers an invalid read as detected by valgrind. The gcno file is
mostly written to from profile.cc, so it doesn't make too much sense
to hide it in path-coverage.cc. The find_paths name was a bit
imprecise, and is renamed to instrument_prime_paths.

PR gcov-profile/119553

gcc/ChangeLog:

* path-coverage.cc (find_paths): Return path count, don't
write to gcno, and rename to ...
(instrument_prime_paths): ... this.
* profile.cc (branch_prob): Write path counts to gcno.

gcc/path-coverage.cc
gcc/profile.cc

index 55b3929860357f8cc1519367aaeb883591356c7c..55058fd04ff2c0e7e202f9e0744aa33bac5fda02 100644 (file)
@@ -504,8 +504,8 @@ flush_on_gsi (gimple_stmt_iterator *gsi, size_t bucket, tree local, tree mask,
    bit N%64 in bucket N/64.  For large functions, an individual basic block
    will only be part of a small subset of paths, and by extension buckets and
    local counters.  Only the necessary counters are read and written.  */
-void
-find_paths (struct function *fn)
+unsigned
+instrument_prime_paths (struct function *fn)
 {
   mark_dfs_back_edges (fn);
   vec<vec<int>> paths = find_prime_paths (fn);
@@ -515,7 +515,7 @@ find_paths (struct function *fn)
       warning_at (fn->function_start_locus, OPT_Wcoverage_too_many_paths,
                  "paths exceeding limit, giving up path coverage");
       release_vec_vec (paths);
-      return;
+      return 0;
     }
 
   tree gcov_type_node = get_gcov_type ();
@@ -526,14 +526,9 @@ find_paths (struct function *fn)
   if (!coverage_counter_alloc (GCOV_COUNTER_PATHS, nbuckets))
     {
       release_vec_vec (paths);
-      return;
+      return 0;
     }
 
-  gcov_position_t offset {};
-  offset = gcov_write_tag (GCOV_TAG_PATHS);
-  gcov_write_unsigned (paths.length ());
-  gcov_write_length (offset);
-
   hash_map <edge_hash, uint64_t> ands;
   hash_map <block_hash, uint64_t> iors;
   hash_map <block_hash, uint64_t> flushes;
@@ -771,6 +766,8 @@ find_paths (struct function *fn)
        }
     }
 
+  const unsigned npaths = paths.length ();
   blocks.release ();
   release_vec_vec (paths);
+  return npaths;
 }
index 0b222cf3864083089093610b595a78f60f96546a..c0f5097726bdd6d5b772b56cf27d44528e8d7edb 100644 (file)
@@ -1611,9 +1611,17 @@ branch_prob (bool thunk)
        instrument_values (values);
     }
 
-  void find_paths (struct function*);
+  unsigned instrument_prime_paths (struct function*);
   if (path_coverage_flag)
-    find_paths (cfun);
+    {
+      const unsigned npaths = instrument_prime_paths (cfun);
+      if (output_to_file)
+       {
+         gcov_position_t offset = gcov_write_tag (GCOV_TAG_PATHS);
+         gcov_write_unsigned (npaths);
+         gcov_write_length (offset);
+       }
+    }
 
   free_aux_for_edges ();