[llvm] r321871 - [llvm-cov] Multi-threaded implementation of prepareFileReports method.

Max Moroz via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 08:15:07 PST 2018


Author: dor1s
Date: Fri Jan  5 08:15:07 2018
New Revision: 321871

URL: http://llvm.org/viewvc/llvm-project?rev=321871&view=rev
Log:
[llvm-cov] Multi-threaded implementation of prepareFileReports method.

Summary:
Local testing has demonstrated a great speed improvement, compare the following:

1) Existing version:
```
$ time llvm-cov show -format=html -output-dir=report -instr-profile=... ...
The tool has been launched:                            00:00:00
Loading coverage data:                                 00:00:00
Get unique source files:                               00:00:33
Creating an index out of the source files:             00:00:34
Going into prepareFileReports:                         00:00:34
Going to emit summary information for each file:       00:28:55 <-- 28:21 min!
Going to emit links to files with no function:         00:28:55
Launching 32 threads for generating HTML files:        00:28:55

real  37m43.651s
user  112m5.540s
sys   7m39.872s
```

2) Multi-threaded version with 32 CPUs:
```
$ time llvm-cov show -format=html -output-dir=report -instr-profile=... ...
The tool has been launched:                            00:00:00
Loading coverage data:                                 00:00:00
Get unique source files:                               00:00:38
Creating an index out of the source files:             00:00:40
Going into prepareFileReports:                         00:00:40
Preparing file reports using 32 threads:               00:00:40
# Creating thread tasks for the following number of files: 16422
Going to emit summary information for each file:       00:01:57 <-- 1:17 min!
Going to emit links to files with no function:         00:01:58
Launching 32 threads for generating HTML files:        00:01:58

real  11m2.044s
user  134m48.124s
sys   7m53.388s
```

Reviewers: vsk, morehouse

Reviewed By: vsk

Subscribers: Dor1s, llvm-commits, kcc

Differential Revision: https://reviews.llvm.org/D41206

Added:
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/abs.h
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.cc
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.h
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.cc
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.covmapping
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.profdata
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/pow.h
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.cc
    llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.h
    llvm/trunk/test/tools/llvm-cov/multithreaded-report.test
Modified:
    llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
    llvm/trunk/tools/llvm-cov/CoverageReport.cpp
    llvm/trunk/tools/llvm-cov/CoverageReport.h
    llvm/trunk/tools/llvm-cov/CoverageSummaryInfo.h
    llvm/trunk/tools/llvm-cov/CoverageViewOptions.h

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/abs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/abs.h?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/abs.h (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/abs.h Fri Jan  5 08:15:07 2018
@@ -0,0 +1,7 @@
+template<typename T>
+T abs(T x) {
+  if (x < 0) {
+    return -x;
+  }
+  return x;
+}

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.cc?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.cc (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.cc Fri Jan  5 08:15:07 2018
@@ -0,0 +1,15 @@
+#include "abs.h"
+#include "bytes.h"
+#include "pow.h"
+
+bool loopBytes() {
+  uint64_t totalInt = 0;
+  double totalFloat = 0;
+  for (uint8_t i = 1; i != 0; ++i) {
+    double a = logarithm(i);
+    a = abs(a);
+    totalInt += abs(pow(i, static_cast<uint8_t>(a)));
+    totalFloat += pow(static_cast<decltype(a)>(i), a);
+  }
+  return totalInt > totalFloat;
+}

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.h?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.h (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/bytes.h Fri Jan  5 08:15:07 2018
@@ -0,0 +1,8 @@
+#include <cmath>
+#include <cstdint>
+
+inline double logarithm(uint8_t v) {
+  return log(v);
+}
+
+bool loopBytes();

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.cc?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.cc (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.cc Fri Jan  5 08:15:07 2018
@@ -0,0 +1,15 @@
+#include "bytes.h"
+#include "words.h"
+
+int main() {
+  bool result = false;
+  if (loopBytes())
+    result |= true;
+  if (loopWords())
+    result |= true;
+
+  if (result)
+    return 0;
+
+  return result;
+}

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.covmapping
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.covmapping?rev=321871&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.covmapping (added) and llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.covmapping Fri Jan  5 08:15:07 2018 differ

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.profdata
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.profdata?rev=321871&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.profdata (added) and llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/main.profdata Fri Jan  5 08:15:07 2018 differ

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/pow.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/pow.h?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/pow.h (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/pow.h Fri Jan  5 08:15:07 2018
@@ -0,0 +1,11 @@
+template<typename T>
+T pow(T b, T p) {
+  if (!p)
+    return 1;
+
+  while (--p) {
+    b *= b;
+  }
+
+  return b;
+}

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.cc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.cc?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.cc (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.cc Fri Jan  5 08:15:07 2018
@@ -0,0 +1,15 @@
+#include "abs.h"
+#include "bytes.h"
+#include "pow.h"
+
+bool loopWords() {
+  uint64_t totalInt = 0;
+  double totalFloat = 0;
+  for (uint16_t i = 1; i != 0; ++i) {
+    double a = logarithm(i);
+    a = abs(a);
+    totalInt += abs(pow(i, static_cast<uint16_t>(a)));
+    totalFloat += pow(static_cast<decltype(a)>(i), a);
+  }
+  return totalInt > totalFloat;
+}

Added: llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.h?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.h (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/multithreaded_report/words.h Fri Jan  5 08:15:07 2018
@@ -0,0 +1,8 @@
+#include <cmath>
+#include <cstdint>
+
+inline double logarithm(uint16_t v) {
+  return log(v);
+}
+
+bool loopWords();

Added: llvm/trunk/test/tools/llvm-cov/multithreaded-report.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/multithreaded-report.test?rev=321871&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/multithreaded-report.test (added)
+++ llvm/trunk/test/tools/llvm-cov/multithreaded-report.test Fri Jan  5 08:15:07 2018
@@ -0,0 +1,93 @@
+# Test "report" command with and without multiple threads.
+RUN: llvm-cov report -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.1.report
+
+RUN: llvm-cov report -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.2.report
+
+RUN: diff %t.1.report %t.2.report
+
+# Test "export" command with and without multiple threads.
+RUN: llvm-cov export -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.1.json
+
+RUN: llvm-cov export -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.2.json
+
+RUN: diff %t.1.json %t.2.json
+
+# Test "show" command with and without multiple threads, single text file.
+RUN: llvm-cov show -format=text -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.1.text
+
+RUN: llvm-cov show -format=text -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.2.text
+
+RUN: diff %t.1.text %t.2.text
+
+# Test "show" command with and without multiple threads, single HTML file.
+RUN: llvm-cov show -format=html -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.1.html
+
+RUN: llvm-cov show -format=html -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping > %t.2.html
+
+RUN: diff %t.1.html %t.2.html 
+
+# Test "show" command with and without multiple threads, text directory.
+RUN: llvm-cov show -format=text -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping -o %t.1.text_dir
+
+RUN: llvm-cov show -format=text -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping -o %t.2.text_dir
+
+RUN: diff -r %t.1.text_dir %t.2.text_dir
+
+# Test "show" command with and without multiple threads, HTML directory.
+RUN: llvm-cov show -format=html -num-threads=1 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping -o %t.1.html_dir
+
+RUN: llvm-cov show -format=html -num-threads=10 \
+RUN:   -path-equivalence=/tmp,%S/Inputs \
+RUN:   -instr-profile %S/Inputs/multithreaded_report/main.profdata \
+RUN:   %S/Inputs/multithreaded_report/main.covmapping -o %t.2.html_dir
+
+RUN: diff -r %t.1.html_dir %t.2.html_dir
+
+
+Instructions for regenerating the test:
+
+# cd %S/Inputs/multithreaded_report
+
+cp -r . /tmp/multithreaded_report
+
+clang++ -std=c++11 -mllvm -enable-name-compression=false \
+    -fprofile-instr-generate -fcoverage-mapping \
+    /tmp/multithreaded_report/*.cc -o main
+
+LLVM_PROFILE_FILE="main.profraw" ./main
+llvm-profdata merge main.profraw -o main.profdata
+llvm-cov convert-for-testing ./main -o ./main.covmapping
+rm main main.profraw

Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=321871&r1=321870&r2=321871&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Fri Jan  5 08:15:07 2018
@@ -33,8 +33,8 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/Threading.h"
 #include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/Threading.h"
 #include "llvm/Support/ToolOutputFile.h"
 
 #include <functional>
@@ -637,6 +637,12 @@ int CodeCoverageTool::run(Command Cmd, i
       "summary-only", cl::Optional,
       cl::desc("Export only summary information for each source file"));
 
+  cl::opt<unsigned> NumThreads(
+      "num-threads", cl::init(0),
+      cl::desc("Number of merge threads to use (default: autodetect)"));
+  cl::alias NumThreadsA("j", cl::desc("Alias for --num-threads"),
+                        cl::aliasopt(NumThreads));
+
   auto commandLineParser = [&, this](int argc, const char **argv) -> int {
     cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
     ViewOpts.Debug = DebugDump;
@@ -750,6 +756,7 @@ int CodeCoverageTool::run(Command Cmd, i
     ViewOpts.ShowRegionSummary = RegionSummary;
     ViewOpts.ShowInstantiationSummary = InstantiationSummary;
     ViewOpts.ExportSummaryOnly = SummaryOnly;
+    ViewOpts.NumThreads = NumThreads;
 
     return 0;
   };
@@ -809,12 +816,6 @@ int CodeCoverageTool::doShow(int argc, c
       "project-title", cl::Optional,
       cl::desc("Set project title for the coverage report"));
 
-  cl::opt<unsigned> NumThreads(
-      "num-threads", cl::init(0),
-      cl::desc("Number of merge threads to use (default: autodetect)"));
-  cl::alias NumThreadsA("j", cl::desc("Alias for --num-threads"),
-                        cl::aliasopt(NumThreads));
-
   auto Err = commandLineParser(argc, argv);
   if (Err)
     return Err;
@@ -911,6 +912,8 @@ int CodeCoverageTool::doShow(int argc, c
       (SourceFiles.size() != 1) || ViewOpts.hasOutputDirectory() ||
       (ViewOpts.Format == CoverageViewOptions::OutputFormat::HTML);
 
+  auto NumThreads = ViewOpts.NumThreads;
+
   // If NumThreads is not specified, auto-detect a good default.
   if (NumThreads == 0)
     NumThreads =

Modified: llvm/trunk/tools/llvm-cov/CoverageReport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageReport.cpp?rev=321871&r1=321870&r2=321871&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageReport.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CoverageReport.cpp Fri Jan  5 08:15:07 2018
@@ -16,6 +16,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/Threading.h"
 #include <numeric>
 
 using namespace llvm;
@@ -319,42 +321,60 @@ void CoverageReport::renderFunctionRepor
   }
 }
 
+void CoverageReport::prepareSingleFileReport(const StringRef Filename,
+    const coverage::CoverageMapping *Coverage,
+    const CoverageViewOptions &Options, const unsigned LCP,
+    FileCoverageSummary *FileReport, const CoverageFilter *Filters) {
+  for (const auto &Group : Coverage->getInstantiationGroups(Filename)) {
+    std::vector<FunctionCoverageSummary> InstantiationSummaries;
+    for (const coverage::FunctionRecord *F : Group.getInstantiations()) {
+      if (!Filters->matches(*Coverage, *F))
+        continue;
+      auto InstantiationSummary = FunctionCoverageSummary::get(*Coverage, *F);
+      FileReport->addInstantiation(InstantiationSummary);
+      InstantiationSummaries.push_back(InstantiationSummary);
+    }
+    if (InstantiationSummaries.empty())
+      continue;
+
+    auto GroupSummary =
+        FunctionCoverageSummary::get(Group, InstantiationSummaries);
+
+    if (Options.Debug)
+      outs() << "InstantiationGroup: " << GroupSummary.Name << " with "
+             << "size = " << Group.size() << "\n";
+
+    FileReport->addFunction(GroupSummary);
+  }
+}
+
 std::vector<FileCoverageSummary> CoverageReport::prepareFileReports(
     const coverage::CoverageMapping &Coverage, FileCoverageSummary &Totals,
     ArrayRef<std::string> Files, const CoverageViewOptions &Options,
     const CoverageFilter &Filters) {
-  std::vector<FileCoverageSummary> FileReports;
   unsigned LCP = getRedundantPrefixLen(Files);
+  auto NumThreads = Options.NumThreads;
 
-  for (StringRef Filename : Files) {
-    FileCoverageSummary Summary(Filename.drop_front(LCP));
-
-    for (const auto &Group : Coverage.getInstantiationGroups(Filename)) {
-      std::vector<FunctionCoverageSummary> InstantiationSummaries;
-      for (const coverage::FunctionRecord *F : Group.getInstantiations()) {
-        if (!Filters.matches(Coverage, *F))
-          continue;
-        auto InstantiationSummary = FunctionCoverageSummary::get(Coverage, *F);
-        Summary.addInstantiation(InstantiationSummary);
-        Totals.addInstantiation(InstantiationSummary);
-        InstantiationSummaries.push_back(InstantiationSummary);
-      }
-      if (InstantiationSummaries.empty())
-        continue;
-
-      auto GroupSummary =
-          FunctionCoverageSummary::get(Group, InstantiationSummaries);
+  // If NumThreads is not specified, auto-detect a good default.
+  if (NumThreads == 0)
+    NumThreads =
+        std::max(1U, std::min(llvm::heavyweight_hardware_concurrency(),
+                              unsigned(Files.size())));
 
-      if (Options.Debug)
-        outs() << "InstantiationGroup: " << GroupSummary.Name << " with "
-               << "size = " << Group.size() << "\n";
+  ThreadPool Pool(NumThreads);
 
-      Summary.addFunction(GroupSummary);
-      Totals.addFunction(GroupSummary);
-    }
+  std::vector<FileCoverageSummary> FileReports;
+  FileReports.reserve(Files.size());
 
-    FileReports.push_back(Summary);
+  for (StringRef Filename : Files) {
+    FileReports.emplace_back(Filename.drop_front(LCP));
+    Pool.async(&CoverageReport::prepareSingleFileReport, Filename,
+               &Coverage, Options, LCP, &FileReports.back(), &Filters);
   }
+  Pool.wait();
+
+  for (const auto &FileReport : FileReports)
+    Totals += FileReport;
 
   return FileReports;
 }

Modified: llvm/trunk/tools/llvm-cov/CoverageReport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageReport.h?rev=321871&r1=321870&r2=321871&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageReport.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageReport.h Fri Jan  5 08:15:07 2018
@@ -44,6 +44,14 @@ public:
                      const CoverageViewOptions &Options,
                      const CoverageFilter &Filters = CoverageFiltersMatchAll());
 
+  static void
+  prepareSingleFileReport(const StringRef Filename,
+                          const coverage::CoverageMapping *Coverage,
+                          const CoverageViewOptions &Options,
+                          const unsigned LCP,
+                          FileCoverageSummary *FileReport,
+                          const CoverageFilter *Filters);
+
   /// Render file reports for every unique file in the coverage mapping.
   void renderFileReports(raw_ostream &OS) const;
 

Modified: llvm/trunk/tools/llvm-cov/CoverageSummaryInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageSummaryInfo.h?rev=321871&r1=321870&r2=321871&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageSummaryInfo.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageSummaryInfo.h Fri Jan  5 08:15:07 2018
@@ -116,6 +116,12 @@ public:
   FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
       : Executed(Executed), NumFunctions(NumFunctions) {}
 
+  FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {
+    Executed += RHS.Executed;
+    NumFunctions += RHS.NumFunctions;
+    return *this;
+  }
+
   void addFunction(bool Covered) {
     if (Covered)
       ++Executed;
@@ -176,6 +182,14 @@ struct FileCoverageSummary {
       : Name(Name), RegionCoverage(), LineCoverage(), FunctionCoverage(),
         InstantiationCoverage() {}
 
+  FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
+    RegionCoverage += RHS.RegionCoverage;
+    LineCoverage += RHS.LineCoverage;
+    FunctionCoverage += RHS.FunctionCoverage;
+    InstantiationCoverage += RHS.InstantiationCoverage;
+    return *this;
+  }
+
   void addFunction(const FunctionCoverageSummary &Function) {
     RegionCoverage += Function.RegionCoverage;
     LineCoverage += Function.LineCoverage;

Modified: llvm/trunk/tools/llvm-cov/CoverageViewOptions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageViewOptions.h?rev=321871&r1=321870&r2=321871&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageViewOptions.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageViewOptions.h Fri Jan  5 08:15:07 2018
@@ -39,6 +39,7 @@ struct CoverageViewOptions {
   uint32_t TabSize;
   std::string ProjectTitle;
   std::string CreatedTimeStr;
+  unsigned NumThreads;
 
   /// \brief Change the output's stream color if the colors are enabled.
   ColoredRawOstream colored_ostream(raw_ostream &OS,




More information about the llvm-commits mailing list