LCOV - code coverage report
Current view: top level - lib/Support - DebugCounter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 17 56 30.4 %
Date: 2017-09-14 15:23:50 Functions: 5 9 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "llvm/Support/DebugCounter.h"
       2             : #include "llvm/Support/CommandLine.h"
       3             : #include "llvm/Support/Format.h"
       4             : #include "llvm/Support/ManagedStatic.h"
       5             : #include "llvm/Support/Options.h"
       6             : 
       7             : using namespace llvm;
       8             : 
       9             : namespace {
      10             : // This class overrides the default list implementation of printing so we
      11             : // can pretty print the list of debug counter options.  This type of
      12             : // dynamic option is pretty rare (basically this and pass lists).
      13       72306 : class DebugCounterList : public cl::list<std::string, DebugCounter> {
      14             : private:
      15             :   using Base = cl::list<std::string, DebugCounter>;
      16             : 
      17             : public:
      18             :   template <class... Mods>
      19       72306 :   explicit DebugCounterList(Mods &&... Ms) : Base(std::forward<Mods>(Ms)...) {}
      20             : 
      21             : private:
      22          23 :   void printOptionInfo(size_t GlobalWidth) const override {
      23             :     // This is a variant of from generic_parser_base::printOptionInfo.  Sadly,
      24             :     // it's not easy to make it more usable.  We could get it to print these as
      25             :     // options if we were a cl::opt and registered them, but lists don't have
      26             :     // options, nor does the parser for std::string.  The other mechanisms for
      27             :     // options are global and would pollute the global namespace with our
      28             :     // counters.  Rather than go that route, we have just overridden the
      29             :     // printing, which only a few things call anyway.
      30          23 :     outs() << "  -" << ArgStr;
      31             :     // All of the other options in CommandLine.cpp use ArgStr.size() + 6 for
      32             :     // width, so we do the same.
      33          46 :     Option::printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6);
      34          23 :     const auto &CounterInstance = DebugCounter::instance();
      35         368 :     for (auto Name : CounterInstance) {
      36             :       const auto Info =
      37         184 :           CounterInstance.getCounterInfo(CounterInstance.getCounterId(Name));
      38          92 :       size_t NumSpaces = GlobalWidth - Info.first.size() - 8;
      39         184 :       outs() << "    =" << Info.first;
      40         276 :       outs().indent(NumSpaces) << " -   " << Info.second << '\n';
      41             :     }
      42          23 :   }
      43             : };
      44             : } // namespace
      45             : 
      46             : // Create our command line option.
      47       72306 : static DebugCounterList DebugCounterOption(
      48             :     "debug-counter",
      49      216918 :     cl::desc("Comma separated list of debug counter skip and count"),
      50      289224 :     cl::CommaSeparated, cl::ZeroOrMore, cl::location(DebugCounter::instance()));
      51             : 
      52             : static ManagedStatic<DebugCounter> DC;
      53             : 
      54      361860 : DebugCounter &DebugCounter::instance() { return *DC; }
      55             : 
      56             : // This is called by the command line parser when it sees a value for the
      57             : // debug-counter option defined above.
      58           0 : void DebugCounter::push_back(const std::string &Val) {
      59           0 :   if (Val.empty())
      60           0 :     return;
      61             :   // The strings should come in as counter=value
      62           0 :   auto CounterPair = StringRef(Val).split('=');
      63           0 :   if (CounterPair.second.empty()) {
      64           0 :     errs() << "DebugCounter Error: " << Val << " does not have an = in it\n";
      65           0 :     return;
      66             :   }
      67             :   // Now we have counter=value.
      68             :   // First, process value.
      69             :   long CounterVal;
      70           0 :   if (CounterPair.second.getAsInteger(0, CounterVal)) {
      71           0 :     errs() << "DebugCounter Error: " << CounterPair.second
      72           0 :            << " is not a number\n";
      73           0 :     return;
      74             :   }
      75             :   // Now we need to see if this is the skip or the count, remove the suffix, and
      76             :   // add it to the counter values.
      77           0 :   if (CounterPair.first.endswith("-skip")) {
      78           0 :     auto CounterName = CounterPair.first.drop_back(5);
      79           0 :     unsigned CounterID = RegisteredCounters.idFor(CounterName);
      80           0 :     if (!CounterID) {
      81           0 :       errs() << "DebugCounter Error: " << CounterName
      82           0 :              << " is not a registered counter\n";
      83           0 :       return;
      84             :     }
      85             : 
      86           0 :     auto Res = Counters.insert({CounterID, {0, -1}});
      87           0 :     Res.first->second.first = CounterVal;
      88           0 :   } else if (CounterPair.first.endswith("-count")) {
      89           0 :     auto CounterName = CounterPair.first.drop_back(6);
      90           0 :     unsigned CounterID = RegisteredCounters.idFor(CounterName);
      91           0 :     if (!CounterID) {
      92           0 :       errs() << "DebugCounter Error: " << CounterName
      93           0 :              << " is not a registered counter\n";
      94           0 :       return;
      95             :     }
      96             : 
      97           0 :     auto Res = Counters.insert({CounterID, {0, -1}});
      98           0 :     Res.first->second.second = CounterVal;
      99             :   } else {
     100           0 :     errs() << "DebugCounter Error: " << CounterPair.first
     101           0 :            << " does not end with -skip or -count\n";
     102             :   }
     103             : }
     104             : 
     105           0 : void DebugCounter::print(raw_ostream &OS) const {
     106           0 :   OS << "Counters and values:\n";
     107           0 :   for (const auto &KV : Counters)
     108           0 :     OS << left_justify(RegisteredCounters[KV.first], 32) << ": {"
     109           0 :        << KV.second.first << "," << KV.second.second << "}\n";
     110           0 : }
     111             : 
     112           0 : LLVM_DUMP_METHOD void DebugCounter::dump() const {
     113           0 :   print(dbgs());
     114      216918 : }

Generated by: LCOV version 1.13