LCOV - code coverage report
Current view: top level - lib/Support - DebugCounter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 11 50 22.0 %
Date: 2018-10-20 13:21:21 Functions: 2 5 40.0 %
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             : 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             :   explicit DebugCounterList(Mods &&... Ms) : Base(std::forward<Mods>(Ms)...) {}
      20             : 
      21             : private:
      22           1 :   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           1 :     outs() << "  -" << ArgStr;
      31             :     // All of the other options in CommandLine.cpp use ArgStr.size() + 6 for
      32             :     // width, so we do the same.
      33           1 :     Option::printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6);
      34           1 :     const auto &CounterInstance = DebugCounter::instance();
      35          14 :     for (auto Name : CounterInstance) {
      36             :       const auto Info =
      37          26 :           CounterInstance.getCounterInfo(CounterInstance.getCounterId(Name));
      38          13 :       size_t NumSpaces = GlobalWidth - Info.first.size() - 8;
      39          13 :       outs() << "    =" << Info.first;
      40          13 :       outs().indent(NumSpaces) << " -   " << Info.second << '\n';
      41             :     }
      42           1 :   }
      43             : };
      44             : } // namespace
      45             : 
      46             : // Create our command line option.
      47             : static DebugCounterList DebugCounterOption(
      48             :     "debug-counter", cl::Hidden,
      49             :     cl::desc("Comma separated list of debug counter skip and count"),
      50             :     cl::CommaSeparated, cl::ZeroOrMore, cl::location(DebugCounter::instance()));
      51             : 
      52             : static ManagedStatic<DebugCounter> DC;
      53             : 
      54     1595430 : 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             :   int64_t 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             :   if (CounterPair.first.endswith("-skip")) {
      78             :     auto CounterName = CounterPair.first.drop_back(5);
      79           0 :     unsigned CounterID = getCounterId(CounterName);
      80           0 :     if (!CounterID) {
      81           0 :       errs() << "DebugCounter Error: " << CounterName
      82           0 :              << " is not a registered counter\n";
      83           0 :       return;
      84             :     }
      85             :     enableAllCounters();
      86             : 
      87           0 :     CounterInfo &Counter = Counters[CounterID];
      88           0 :     Counter.Skip = CounterVal;
      89           0 :     Counter.IsSet = true;
      90             :   } else if (CounterPair.first.endswith("-count")) {
      91             :     auto CounterName = CounterPair.first.drop_back(6);
      92           0 :     unsigned CounterID = getCounterId(CounterName);
      93           0 :     if (!CounterID) {
      94           0 :       errs() << "DebugCounter Error: " << CounterName
      95           0 :              << " is not a registered counter\n";
      96           0 :       return;
      97             :     }
      98             :     enableAllCounters();
      99             : 
     100           0 :     CounterInfo &Counter = Counters[CounterID];
     101           0 :     Counter.StopAfter = CounterVal;
     102           0 :     Counter.IsSet = true;
     103             :   } else {
     104           0 :     errs() << "DebugCounter Error: " << CounterPair.first
     105           0 :            << " does not end with -skip or -count\n";
     106             :   }
     107             : }
     108             : 
     109           0 : void DebugCounter::print(raw_ostream &OS) const {
     110           0 :   OS << "Counters and values:\n";
     111           0 :   for (const auto &KV : Counters)
     112           0 :     OS << left_justify(RegisteredCounters[KV.first], 32) << ": {"
     113           0 :        << KV.second.Count << "," << KV.second.Skip << ","
     114           0 :        << KV.second.StopAfter << "}\n";
     115           0 : }
     116             : 
     117           0 : LLVM_DUMP_METHOD void DebugCounter::dump() const {
     118           0 :   print(dbgs());
     119           0 : }

Generated by: LCOV version 1.13