[PATCH] llvm-cov: Print coverage summary to STDOUT.
Justin Bogner
mail at justinbogner.com
Thu Dec 12 18:48:38 PST 2013
Yuchen Wu <yuchenericwu at hotmail.com> writes:
> From 6eb0174daa640ae4b655408e6e35087f3284e7a6 Mon Sep 17 00:00:00 2001
> From: Yuchen Wu <yuchen_wu at apple.com>
> Date: Thu, 12 Dec 2013 12:21:11 -0800
> Subject: [PATCH 3/5] llvm-cov: Print coverage summary to STDOUT.
>
> File summaries will now be optionally outputted which will give line,
> branching and call coverage info. Unfortunately, clang's current
> instrumentation does not give enough information to deduce function
> calls, something that gcc is able to do. Thus, no calls are always
> outputted to be consistent with gcov output.
>
> Also updated tests.
> ---
> include/llvm/Support/GCOV.h | 16 ++++++++-
> lib/IR/GCOV.cpp | 42 +++++++++++++++++++----
> test/tools/llvm-cov/Inputs/test_-b.output | 13 +++++++
> test/tools/llvm-cov/Inputs/test_no_options.output | 8 +++++
> test/tools/llvm-cov/llvm-cov.test | 4 +--
> 5 files changed, 74 insertions(+), 9 deletions(-)
> create mode 100644 test/tools/llvm-cov/Inputs/test_-b.output
> create mode 100644 test/tools/llvm-cov/Inputs/test_no_options.output
>
> diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
> index c3018f1..42fdcff 100644
> --- a/include/llvm/Support/GCOV.h
> +++ b/include/llvm/Support/GCOV.h
> @@ -350,6 +350,19 @@ class FileInfo {
> BlockLines Blocks;
> FunctionLines Functions;
> };
> +
> + struct GCOVSummary {
> + GCOVSummary() :
> + LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
> + BranchesTaken(0) {}
> +
> + uint32_t LogicalLines;
> + uint32_t LinesExec;
> +
> + uint32_t Branches;
> + uint32_t BranchesExec;
> + uint32_t BranchesTaken;
> + };
> public:
> FileInfo(const GCOVOptions &Options) :
> Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
> @@ -369,7 +382,8 @@ public:
> void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
> uint32_t LineIndex, uint32_t &BlockNo) const;
> void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
> - uint32_t LineIndex, uint32_t &EdgeNo) const;
> + GCOVSummary &Summary, uint32_t LineIndex,
> + uint32_t &EdgeNo) const;
> private:
> const GCOVOptions &Options;
> StringMap<LineData> LineInfo;
> diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp
> index 7902f04..fc626ca 100644
> --- a/lib/IR/GCOV.cpp
> +++ b/lib/IR/GCOV.cpp
> @@ -430,6 +430,7 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
> OS << " -: 0:Programs:" << ProgramCount << "\n";
>
> const LineData &Line = I->second;
> + GCOVSummary Summary;
> for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
> if (Options.BranchInfo) {
> FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
> @@ -461,10 +462,14 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
> LineCount += Block->getCount();
> }
> }
> +
> if (LineCount == 0)
> OS << " #####:";
> - else
> + else {
> OS << format("%9" PRIu64 ":", LineCount);
> + ++Summary.LinesExec;
> + }
> + ++Summary.LogicalLines;
>
> std::pair<StringRef, StringRef> P = AllLines.split('\n');
> OS << format("%5u:", LineIndex+1) << P.first << "\n";
> @@ -482,10 +487,31 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
> if (Options.AllBlocks)
> printBlockInfo(OS, *Block, LineIndex, BlockNo);
> if (Options.BranchInfo)
> - printBranchInfo(OS, *Block, LineIndex, EdgeNo);
> + printBranchInfo(OS, *Block, Summary, LineIndex, EdgeNo);
> }
> }
> }
> +
> + // FIXME: There is no way to detect calls given current instrumentation.
> + outs() << "File '" << Filename << "'\n";
> + outs() << format("Lines executed:%.2lf%% of %u\n",
> + double(Summary.LinesExec)*100/Summary.LogicalLines,
> + Summary.LogicalLines);
> + if (Options.BranchInfo) {
> + if (Summary.Branches) {
> + outs() << format("Branches executed:%.2lf%% of %u\n",
> + double(Summary.BranchesExec)*100/Summary.Branches,
> + Summary.Branches);
> + outs() << format("Taken at least once:%.2lf%% of %u\n",
> + double(Summary.BranchesTaken)*100/Summary.Branches,
> + Summary.Branches);
> + } else {
> + outs() << "No branches\n";
> + }
> + outs() << "No calls\n"; // to be consistent with gcov
> + }
> + outs() << Filename << ":creating '" << CovFilename << "'\n";
> + outs() << "\n";
Might as well pull this out into a "printSummary" function.
> }
> }
>
> @@ -496,18 +522,18 @@ void FileInfo::printFunctionSummary(raw_fd_ostream &OS,
> I != E; ++I) {
> const GCOVFunction *Func = *I;
> uint64_t EntryCount = Func->getEntryCount();
> - uint32_t BlocksExecuted = 0;
> + uint32_t BlocksExec = 0;
Why rename this?
> for (GCOVFunction::BlockIterator I = Func->block_begin(),
> E = Func->block_end(); I != E; ++I) {
> const GCOVBlock *Block = *I;
> if (Block->getNumDstEdges() && Block->getCount())
> - ++BlocksExecuted;
> + ++BlocksExec;
> }
>
> OS << "function " << Func->getName() << " called " << EntryCount
> << " returned " << safeDiv(Func->getExitCount()*100, EntryCount)
> << "% blocks executed "
> - << safeDiv(BlocksExecuted*100, Func->getNumBlocks()-1) << "%\n";
> + << safeDiv(BlocksExec*100, Func->getNumBlocks()-1) << "%\n";
> }
> }
>
> @@ -523,7 +549,8 @@ void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
>
> /// printBranchInfo - Print branch probabilities.
> void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
> - uint32_t LineIndex, uint32_t &EdgeNo) const {
> + GCOVSummary &Summary, uint32_t LineIndex,
> + uint32_t &EdgeNo) const {
> size_t NumEdges = Block.getNumDstEdges();
> if (NumEdges > 1) {
> // Print conditional branch info.
> @@ -534,6 +561,9 @@ void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
> const GCOVEdge *Edge = *I;
> BranchCounts.push_back(Edge->Count);
> TotalCounts += Edge->Count;
> + if (Block.getCount()) ++Summary.BranchesExec;
> + if (Edge->Count) ++Summary.BranchesTaken;
> + ++Summary.Branches;
> }
>
> for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(),
> diff --git a/test/tools/llvm-cov/Inputs/test_-b.output b/test/tools/llvm-cov/Inputs/test_-b.output
> new file mode 100644
> index 0000000..4003ce8
> --- /dev/null
> +++ b/test/tools/llvm-cov/Inputs/test_-b.output
> @@ -0,0 +1,13 @@
> +File 'test.cpp'
> +Lines executed:84.21% of 38
> +Branches executed:100.00% of 15
> +Taken at least once:86.67% of 15
> +No calls
> +test.cpp:creating 'test.cpp.gcov'
> +
> +File './test.h'
> +Lines executed:100.00% of 1
> +No branches
> +No calls
> +./test.h:creating './test.h.gcov'
> +
> diff --git a/test/tools/llvm-cov/Inputs/test_no_options.output b/test/tools/llvm-cov/Inputs/test_no_options.output
> new file mode 100644
> index 0000000..93ea726
> --- /dev/null
> +++ b/test/tools/llvm-cov/Inputs/test_no_options.output
> @@ -0,0 +1,8 @@
> +File 'test.cpp'
> +Lines executed:84.21% of 38
> +test.cpp:creating 'test.cpp.gcov'
> +
> +File './test.h'
> +Lines executed:100.00% of 1
> +./test.h:creating './test.h.gcov'
> +
> diff --git a/test/tools/llvm-cov/llvm-cov.test b/test/tools/llvm-cov/llvm-cov.test
> index 02b8a3d..da39307 100644
> --- a/test/tools/llvm-cov/llvm-cov.test
> +++ b/test/tools/llvm-cov/llvm-cov.test
> @@ -5,7 +5,7 @@ RUN: mkdir %t
> RUN: cd %t
> RUN: cp %p/Inputs/test* .
>
> -RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda
> +RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda | diff test_no_options.output -
> RUN: diff -aub test_no_options.cpp.gcov test.cpp.gcov
> RUN: diff -aub test_no_options.h.gcov test.h.gcov
>
> @@ -13,7 +13,7 @@ RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a
> RUN: diff -aub test_-a.cpp.gcov test.cpp.gcov
> RUN: diff -aub test_-a.h.gcov test.h.gcov
>
> -RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a -b
> +RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a -b | diff test_-b.output -
> RUN: diff -aub test_-a_-b.cpp.gcov test.cpp.gcov
> RUN: diff -aub test_-a_-b.h.gcov test.h.gcov
More information about the llvm-commits
mailing list