[llvm] b2c32c9 - [llvm-cov gcov] Add -r (--relative-only) && -s (--source-prefix)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 14:54:43 PDT 2020


Author: Fangrui Song
Date: 2020-09-13T14:54:20-07:00
New Revision: b2c32c90bab09a6e2c1f370429db26017a182143

URL: https://github.com/llvm/llvm-project/commit/b2c32c90bab09a6e2c1f370429db26017a182143
DIFF: https://github.com/llvm/llvm-project/commit/b2c32c90bab09a6e2c1f370429db26017a182143.diff

LOG: [llvm-cov gcov] Add -r (--relative-only) && -s (--source-prefix)

gcov 4.7 introduced the two options.
https://sourceware.org/pipermail/gcc-patches/2011-November/328782.html

-r only dumps files with relative paths or absolute paths with the prefix
specified by -s. The two options are useful filtering out system header files.

Added: 
    llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda
    llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno
    llvm/test/tools/llvm-cov/gcov/relative-only.test

Modified: 
    llvm/include/llvm/ProfileData/GCOV.h
    llvm/lib/ProfileData/GCOV.cpp
    llvm/tools/llvm-cov/gcov.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h
index 3c6312f91674..56b512b6d606 100644
--- a/llvm/include/llvm/ProfileData/GCOV.h
+++ b/llvm/include/llvm/ProfileData/GCOV.h
@@ -48,10 +48,11 @@ enum GCOVVersion { V304, V407, V408, V800, V900 };
 /// A struct for passing gcov options between functions.
 struct Options {
   Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L,
-          bool N, bool T, bool X)
+          bool N, bool R, bool T, bool X, std::string SourcePrefix)
       : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
         PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L),
-        NoOutput(N), UseStdout(T), HashFilenames(X) {}
+        NoOutput(N), RelativeOnly(R), UseStdout(T), HashFilenames(X),
+        SourcePrefix(std::move(SourcePrefix)) {}
 
   bool AllBlocks;
   bool BranchInfo;
@@ -62,8 +63,10 @@ struct Options {
   bool Intermediate;
   bool LongFileNames;
   bool NoOutput;
+  bool RelativeOnly;
   bool UseStdout;
   bool HashFilenames;
+  std::string SourcePrefix;
 };
 
 } // end namespace GCOV
@@ -341,9 +344,11 @@ struct GCOVCoverage {
 
 struct SourceInfo {
   StringRef filename;
+  SmallString<0> displayName;
   std::string name;
   std::vector<GCOVFunction *> functions;
   GCOVCoverage coverage;
+  bool ignored = false;
   SourceInfo(StringRef filename) : filename(filename) {}
 };
 

diff  --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index d4a4a8979e81..20118a0378b7 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -261,8 +261,24 @@ LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
 /// reading .gcno and .gcda files.
 void GCOVFile::collectLineCounts(FileInfo &fi) {
   assert(fi.sources.empty());
-  for (StringRef filename : filenames)
+  for (StringRef filename : filenames) {
     fi.sources.emplace_back(filename);
+    SourceInfo &si = fi.sources.back();
+    si.displayName = si.filename;
+    if (!fi.Options.SourcePrefix.empty() &&
+        sys::path::replace_path_prefix(si.displayName, fi.Options.SourcePrefix,
+                                       "") &&
+        !si.displayName.empty()) {
+      // TODO replace_path_prefix may strip the prefix even if the remaining
+      // part does not start with a separator.
+      if (sys::path::is_separator(si.displayName[0]))
+        si.displayName.erase(si.displayName.begin());
+      else
+        si.displayName = si.filename;
+    }
+    if (fi.Options.RelativeOnly && sys::path::is_absolute(si.displayName))
+      si.ignored = true;
+  }
   for (GCOVFunction &f : *this) {
     f.collectLineCounts(fi);
     fi.sources[f.srcIdx].functions.push_back(&f);
@@ -664,6 +680,10 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
   llvm::sort(Filenames);
 
   for (StringRef Filename : Filenames) {
+    SourceInfo &source = sources[file.filenameToIdx.find(Filename)->second];
+    if (source.ignored)
+      continue;
+
     auto AllLines =
         Options.Intermediate ? LineConsumer() : LineConsumer(Filename);
     std::string CoveragePath = getCoveragePath(Filename, MainFilename);
@@ -675,7 +695,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
     raw_ostream &CovOS =
         !Options.NoOutput && Options.UseStdout ? llvm::outs() : *CovStream;
 
-    CovOS << "        -:    0:Source:" << Filename << "\n";
+    CovOS << "        -:    0:Source:" << source.displayName << "\n";
     CovOS << "        -:    0:Graph:" << GCNOFile << "\n";
     CovOS << "        -:    0:Data:" << GCDAFile << "\n";
     CovOS << "        -:    0:Runs:" << RunCount << "\n";
@@ -683,7 +703,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
       CovOS << "        -:    0:Programs:" << ProgramCount << "\n";
 
     const LineData &Line = LineInfo[Filename];
-    GCOVCoverage FileCoverage(Filename);
+    GCOVCoverage FileCoverage(source.displayName);
     for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
          ++LineIndex) {
       if (Options.BranchInfo) {
@@ -767,7 +787,6 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
         }
       }
     }
-    SourceInfo &source = sources[file.filenameToIdx.find(Filename)->second];
     source.name = CoveragePath;
     source.coverage = FileCoverage;
   }
@@ -928,6 +947,8 @@ void FileInfo::printFuncCoverage(raw_ostream &OS) const {
 // printFileCoverage - Print per-file coverage info.
 void FileInfo::printFileCoverage(raw_ostream &OS) const {
   for (const SourceInfo &source : sources) {
+    if (source.ignored)
+      continue;
     const GCOVCoverage &Coverage = source.coverage;
     OS << "File '" << Coverage.Name << "'\n";
     printCoverage(OS, Coverage);

diff  --git a/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda
new file mode 100644
index 000000000000..806dc6a2aa0f
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda 
diff er

diff  --git a/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno
new file mode 100644
index 000000000000..1bd83064d67b
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno 
diff er

diff  --git a/llvm/test/tools/llvm-cov/gcov/relative-only.test b/llvm/test/tools/llvm-cov/gcov/relative-only.test
new file mode 100644
index 000000000000..157441e7673f
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/gcov/relative-only.test
@@ -0,0 +1,37 @@
+# Test -r (--relative-only) and -s (--source-prefix).
+RUN: rm -rf %t && mkdir %t && cd %t
+RUN: cp %S/Inputs/abs-path.gcno %S/Inputs/abs-path.gcda .
+
+RUN: llvm-cov gcov abs-path.gcda | FileCheck %s
+RUN: rm abs-path.c.gcov a.h.gcov
+CHECK: File '/tmp/c/abs-path.c'
+CHECK: File '/tmp/h/a.h'
+
+# If there is no source file with a relative path, nothing is dumped.
+RUN: llvm-cov gcov -r abs-path.gcda 2>&1 | count 0
+RUN: llvm-cov gcov -r -s /t abs-path.gcda 2>&1 | count 0
+RUN: not ls abs-path.c.gcov 2> /dev/null
+
+# -s strips a prefix from filenames and can change filtering of -r.
+RUN: llvm-cov gcov -r -s /tmp abs-path.gcda | FileCheck %s --check-prefix=STRIP1 --match-full-lines --strict-whitespace
+RUN: FileCheck %s --check-prefix=STRIP1_C < abs-path.c.gcov
+RUN: FileCheck %s --check-prefix=STRIP1_H < a.h.gcov
+
+# Test full option names.
+RUN: llvm-cov gcov --relative-only --source-prefix=/tmp abs-path.gcda | FileCheck %s --check-prefix=STRIP1 --match-full-lines --strict-whitespace
+
+      STRIP1:File 'c/abs-path.c'
+ STRIP1-NEXT:Lines executed:100.00% of 1
+ STRIP1-NEXT:Creating 'abs-path.c.gcov'
+STRIP1-EMPTY:
+ STRIP1-NEXT:File 'h/a.h'
+ STRIP1-NEXT:Lines executed:0.00% of 1
+ STRIP1-NEXT:Creating 'a.h.gcov'
+
+STRIP1_C: 0:Source:c/abs-path.c
+STRIP1_H: 0:Source:h/a.h
+
+RUN: llvm-cov gcov -r -s /tmp/h abs-path.gcda | FileCheck %s --check-prefix=STRIP2
+
+STRIP2-NOT: File
+STRIP2:     File 'a.h'

diff  --git a/llvm/tools/llvm-cov/gcov.cpp b/llvm/tools/llvm-cov/gcov.cpp
index d99e792c68a9..858f4cee7904 100644
--- a/llvm/tools/llvm-cov/gcov.cpp
+++ b/llvm/tools/llvm-cov/gcov.cpp
@@ -131,6 +131,14 @@ int gcovMain(int argc, const char *argv[]) {
                               cl::desc("Preserve path components"));
   cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths));
 
+  cl::opt<bool> RelativeOnly(
+      "r", cl::Grouping,
+      cl::desc("Only dump files with relative paths or absolute paths with the "
+               "prefix specified by -s"));
+  cl::alias RelativeOnlyA("relative-only", cl::aliasopt(RelativeOnly));
+  cl::opt<std::string> SourcePrefix("s", cl::desc("Source prefix to elide"));
+  cl::alias SourcePrefixA("source-prefix", cl::aliasopt(SourcePrefix));
+
   cl::opt<bool> UseStdout("t", cl::Grouping, cl::init(false),
                           cl::desc("Print to stdout"));
   cl::alias UseStdoutA("stdout", cl::aliasopt(UseStdout));
@@ -157,7 +165,8 @@ int gcovMain(int argc, const char *argv[]) {
 
   GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
                         PreservePaths, UncondBranch, Intermediate, LongNames,
-                        NoOutput, UseStdout, HashFilenames);
+                        NoOutput, RelativeOnly, UseStdout, HashFilenames,
+                        SourcePrefix);
 
   for (const auto &SourceFile : SourceFiles)
     reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,


        


More information about the llvm-commits mailing list