Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/DebugCounter.cpp
Line
Count
Source (jump to first uncovered line)
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
104k
  explicit DebugCounterList(Mods &&... Ms) : Base(std::forward<Mods>(Ms)...) {}
20
21
private:
22
1
  void printOptionInfo(size_t GlobalWidth) const override {
23
1
    // This is a variant of from generic_parser_base::printOptionInfo.  Sadly,
24
1
    // it's not easy to make it more usable.  We could get it to print these as
25
1
    // options if we were a cl::opt and registered them, but lists don't have
26
1
    // options, nor does the parser for std::string.  The other mechanisms for
27
1
    // options are global and would pollute the global namespace with our
28
1
    // counters.  Rather than go that route, we have just overridden the
29
1
    // printing, which only a few things call anyway.
30
1
    outs() << "  -" << ArgStr;
31
1
    // All of the other options in CommandLine.cpp use ArgStr.size() + 6 for
32
1
    // 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
14
      const auto Info =
37
14
          CounterInstance.getCounterInfo(CounterInstance.getCounterId(Name));
38
14
      size_t NumSpaces = GlobalWidth - Info.first.size() - 8;
39
14
      outs() << "    =" << Info.first;
40
14
      outs().indent(NumSpaces) << " -   " << Info.second << '\n';
41
14
    }
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 cl::opt<bool> PrintDebugCounter(
53
    "print-debug-counter", cl::Hidden, cl::init(false), cl::Optional,
54
    cl::desc("Print out debug counter info after all counters accumulated"));
55
56
static ManagedStatic<DebugCounter> DC;
57
58
// Print information when destroyed, iff command line option is specified.
59
100k
DebugCounter::~DebugCounter() {
60
100k
  if (isCountingEnabled() && 
PrintDebugCounter0
)
61
0
    print(dbgs());
62
100k
}
63
64
1.55M
DebugCounter &DebugCounter::instance() { return *DC; }
65
66
// This is called by the command line parser when it sees a value for the
67
// debug-counter option defined above.
68
0
void DebugCounter::push_back(const std::string &Val) {
69
0
  if (Val.empty())
70
0
    return;
71
0
  // The strings should come in as counter=value
72
0
  auto CounterPair = StringRef(Val).split('=');
73
0
  if (CounterPair.second.empty()) {
74
0
    errs() << "DebugCounter Error: " << Val << " does not have an = in it\n";
75
0
    return;
76
0
  }
77
0
  // Now we have counter=value.
78
0
  // First, process value.
79
0
  int64_t CounterVal;
80
0
  if (CounterPair.second.getAsInteger(0, CounterVal)) {
81
0
    errs() << "DebugCounter Error: " << CounterPair.second
82
0
           << " is not a number\n";
83
0
    return;
84
0
  }
85
0
  // Now we need to see if this is the skip or the count, remove the suffix, and
86
0
  // add it to the counter values.
87
0
  if (CounterPair.first.endswith("-skip")) {
88
0
    auto CounterName = CounterPair.first.drop_back(5);
89
0
    unsigned CounterID = getCounterId(CounterName);
90
0
    if (!CounterID) {
91
0
      errs() << "DebugCounter Error: " << CounterName
92
0
             << " is not a registered counter\n";
93
0
      return;
94
0
    }
95
0
    enableAllCounters();
96
0
97
0
    CounterInfo &Counter = Counters[CounterID];
98
0
    Counter.Skip = CounterVal;
99
0
    Counter.IsSet = true;
100
0
  } else if (CounterPair.first.endswith("-count")) {
101
0
    auto CounterName = CounterPair.first.drop_back(6);
102
0
    unsigned CounterID = getCounterId(CounterName);
103
0
    if (!CounterID) {
104
0
      errs() << "DebugCounter Error: " << CounterName
105
0
             << " is not a registered counter\n";
106
0
      return;
107
0
    }
108
0
    enableAllCounters();
109
0
110
0
    CounterInfo &Counter = Counters[CounterID];
111
0
    Counter.StopAfter = CounterVal;
112
0
    Counter.IsSet = true;
113
0
  } else {
114
0
    errs() << "DebugCounter Error: " << CounterPair.first
115
0
           << " does not end with -skip or -count\n";
116
0
  }
117
0
}
118
119
0
void DebugCounter::print(raw_ostream &OS) const {
120
0
  SmallVector<StringRef, 16> CounterNames(RegisteredCounters.begin(),
121
0
                                          RegisteredCounters.end());
122
0
  sort(CounterNames.begin(), CounterNames.end());
123
0
124
0
  auto &Us = instance();
125
0
  OS << "Counters and values:\n";
126
0
  for (auto &CounterName : CounterNames) {
127
0
    unsigned CounterID = getCounterId(CounterName);
128
0
    OS << left_justify(RegisteredCounters[CounterID], 32) << ": {"
129
0
       << Us.Counters[CounterID].Count << "," << Us.Counters[CounterID].Skip
130
0
       << "," << Us.Counters[CounterID].StopAfter << "}\n";
131
0
  }
132
0
}
133
134
0
LLVM_DUMP_METHOD void DebugCounter::dump() const {
135
0
  print(dbgs());
136
0
}