[PATCH] llvm-cov: Added -a option for block data.

Justin Bogner mail at justinbogner.com
Mon Dec 2 15:12:41 PST 2013


Yuchen Wu <yuchenericwu at hotmail.com> writes:
> Minor update: Removed isTrivialBlock(). It is no longer necessary due
> to r195513.
 ...
> From 69e6db89483b170dc34eea0adbdaf28bde3b10e5 Mon Sep 17 00:00:00 2001
> From: Yuchen Wu <yuchen_wu at apple.com>
> Date: Wed, 20 Nov 2013 13:21:29 -0800
> Subject: [PATCH 06/10] llvm-cov: Added -a option for block data.
>
> Similar to gcov, llvm-cov will now print out the block count at the end
> of each block. Multiple blocks can end on the same line.
>
> One computational difference is by using -a, llvm-cov will no longer
> simply add the block counts together to form a line count. Instead, it
> will take the maximum of the block counts on that line. This has a
> similar effect to what gcov does, but generates more correct counts in
> certain scenarios.
> ---
>  include/llvm/Support/GCOV.h | 12 ++++++++++-
>  lib/IR/GCOV.cpp             | 49 +++++++++++++++++++++++++++++++++++----------
>  tools/llvm-cov/llvm-cov.cpp |  6 ++++--
>  3 files changed, 53 insertions(+), 14 deletions(-)
>
> diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
> index 3298132..c12b054 100644
> --- a/include/llvm/Support/GCOV.h
> +++ b/include/llvm/Support/GCOV.h
> @@ -37,6 +37,13 @@ namespace GCOV {
>    };
>  } // end GCOV namespace
>  
> +/// GCOVOptions - A struct for passing gcov options between functions.
> +struct GCOVOptions {
> +  GCOVOptions(bool A): AllBlocks(A) {}

Is 'A' really better than 'AllBlocks'?

> +
> +  bool AllBlocks;
> +};
> +
>  /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
>  /// read operations.
>  class GCOVBuffer {
> @@ -222,6 +229,7 @@ public:
>    bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
>    bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
>    StringRef getFilename() const { return Filename; }
> +  size_t getNumBlocks() const { return Blocks.size(); }
>    void dump() const;
>    void collectLineCounts(FileInfo &FI);
>  private:
> @@ -252,6 +260,7 @@ public:
>      DstEdges.push_back(Edge);
>    }
>    void addLine(uint32_t N) { Lines.push_back(N); }
> +  uint32_t getLastLine() const { return Lines.back(); }
>    void addCount(size_t Index, uint64_t N);
>    uint64_t getCount() const { return Counter; }
>    size_t getNumSrcEdges() const { return SrcEdges.size(); }
> @@ -282,7 +291,8 @@ public:
>    }
>    void setRunCount(uint32_t Runs) { RunCount = Runs; }
>    void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
> -  void print(StringRef gcnoFile, StringRef gcdaFile) const;
> +  void print(StringRef gcnoFile, StringRef gcdaFile,
> +             const GCOVOptions &Options) const;
>  private:
>    StringMap<LineData> LineInfo;
>    uint32_t RunCount;
> diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp
> index b26d303..26a6e79 100644
> --- a/lib/IR/GCOV.cpp
> +++ b/lib/IR/GCOV.cpp
> @@ -352,7 +352,8 @@ void GCOVBlock::dump() const {
>  // FileInfo implementation.
>  
>  /// print -  Print source files with collected line count information.
> -void FileInfo::print(StringRef gcnoFile, StringRef gcdaFile) const {
> +void FileInfo::print(StringRef gcnoFile, StringRef gcdaFile,
> +                     const GCOVOptions &Options) const {
>    for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
>           E = LineInfo.end(); I != E; ++I) {
>      StringRef Filename = I->first();
> @@ -375,16 +376,26 @@ void FileInfo::print(StringRef gcnoFile, StringRef gcdaFile) const {
>      OS << "        -:    0:Runs:" << RunCount << "\n";
>      OS << "        -:    0:Programs:" << ProgramCount << "\n";
>  
> -    const LineData &L = I->second;
> -    uint32_t i = 0;
> -    while (!AllLines.empty()) {
> -      LineData::const_iterator BlocksIt = L.find(i);
> -      if (BlocksIt != L.end()) {
> +    const LineData &Line = I->second;
> +    for (uint32_t i = 0; !AllLines.empty(); ++i) {
> +      LineData::const_iterator BlocksIt = Line.find(i);
> +
> +      // Add up the block counts to form line counts.
> +      if (BlocksIt != Line.end()) {

These are some nice cleanups, but please break them out into their own
patch.

>          const BlockVector &Blocks = BlocksIt->second;
>          uint64_t LineCount = 0;
>          for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
>                 I != E; ++I) {
> -          LineCount += (*I)->getCount();
> +          const GCOVBlock *Block = *I;
> +          // If -a option is enabled, only take the highest block count for
> +          // that line.
> +          if (Options.AllBlocks) {
> +            uint64_t BlockCount = Block->getCount();
> +            LineCount = LineCount > BlockCount ? LineCount : BlockCount;
> +          }
> +          // Otherwise, sum up all of the block counts.
> +          else
> +            LineCount += Block->getCount();

It's more readable to put these comments inside the if/else scopes, and
"If -a option is enabled" is a bit redundant with "if (Options.AllBlocks)"

>          }
>          if (LineCount == 0)
>            OS << "    #####:";
> @@ -394,11 +405,27 @@ void FileInfo::print(StringRef gcnoFile, StringRef gcdaFile) const {
>          OS << "        -:";
>        }
>        std::pair<StringRef, StringRef> P = AllLines.split('\n');
> -      if (AllLines != P.first)
> -        OS << format("%5u:", i+1) << P.first;
> -      OS << "\n";
> +      OS << format("%5u:", i+1) << P.first << "\n";

This looks like a behaviour change, but I don't see how it's related.

>        AllLines = P.second;
> -      ++i;
> +
> +      // If -a option is enabled, output the counts for each block at the last
> +      // line of the block.
> +      if (Options.AllBlocks && BlocksIt != Line.end()) {
> +        uint32_t BlockNo = 0;
> +        const BlockVector &Blocks = BlocksIt->second;
> +        for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
> +               I != E; ++I) {

The whitespace is a bit funny here. The I should line up under the B in
BlockVector.

> +          const GCOVBlock *Block = *I;
> +          if (Block->getLastLine() != i+1)
> +            continue;
> +
> +          if (Block->getCount() == 0)
> +            OS << "    $$$$$:";
> +          else
> +            OS << format("%9lu:", Block->getCount());
> +          OS << format("%5u-block  %u\n", i+1, BlockNo++);
> +        }
> +      }
>      }
>    }
>  }
> diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp
> index 7f4d53e..10af0ec 100644
> --- a/tools/llvm-cov/llvm-cov.cpp
> +++ b/tools/llvm-cov/llvm-cov.cpp
> @@ -30,6 +30,9 @@ InputGCNO("gcno", cl::desc("<input gcno file>"), cl::init(""));
>  static cl::opt<std::string>
>  InputGCDA("gcda", cl::desc("<input gcda file>"), cl::init(""));
>  
> +static cl::opt<bool>
> +AllBlocks("a", cl::init(false), cl::desc("display all block info"));
> +
>  //===----------------------------------------------------------------------===//
>  int main(int argc, char **argv) {
>    // Print a stack trace if we signal out.
> @@ -67,12 +70,11 @@ int main(int argc, char **argv) {
>      }
>    }
>  
> -
>    if (DumpGCOV)
>      GF.dump();
>  
>    FileInfo FI;
>    GF.collectLineCounts(FI);
> -  FI.print(InputGCNO, InputGCDA);
> +  FI.print(InputGCNO, InputGCDA, GCOVOptions(AllBlocks));
>    return 0;
>  }



More information about the llvm-commits mailing list