LLVM  16.0.0git
DebugCounter.cpp
Go to the documentation of this file.
2 
3 #include "DebugOptions.h"
4 
6 #include "llvm/Support/Format.h"
7 
8 using namespace llvm;
9 
10 namespace {
11 // This class overrides the default list implementation of printing so we
12 // can pretty print the list of debug counter options. This type of
13 // dynamic option is pretty rare (basically this and pass lists).
14 class DebugCounterList : public cl::list<std::string, DebugCounter> {
15 private:
17 
18 public:
19  template <class... Mods>
20  explicit DebugCounterList(Mods &&... Ms) : Base(std::forward<Mods>(Ms)...) {}
21 
22 private:
23  void printOptionInfo(size_t GlobalWidth) const override {
24  // This is a variant of from generic_parser_base::printOptionInfo. Sadly,
25  // it's not easy to make it more usable. We could get it to print these as
26  // options if we were a cl::opt and registered them, but lists don't have
27  // options, nor does the parser for std::string. The other mechanisms for
28  // options are global and would pollute the global namespace with our
29  // counters. Rather than go that route, we have just overridden the
30  // printing, which only a few things call anyway.
31  outs() << " -" << ArgStr;
32  // All of the other options in CommandLine.cpp use ArgStr.size() + 6 for
33  // width, so we do the same.
34  Option::printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6);
35  const auto &CounterInstance = DebugCounter::instance();
36  for (const auto &Name : CounterInstance) {
37  const auto Info =
38  CounterInstance.getCounterInfo(CounterInstance.getCounterId(Name));
39  size_t NumSpaces = GlobalWidth - Info.first.size() - 8;
40  outs() << " =" << Info.first;
41  outs().indent(NumSpaces) << " - " << Info.second << '\n';
42  }
43  }
44 };
45 
46 // All global objects associated to the DebugCounter, including the DebugCounter
47 // itself, are owned by a single global instance of the DebugCounterOwner
48 // struct. This makes it easier to control the order in which constructors and
49 // destructors are run.
50 struct DebugCounterOwner {
51  DebugCounter DC;
52  DebugCounterList DebugCounterOption{
53  "debug-counter", cl::Hidden,
54  cl::desc("Comma separated list of debug counter skip and count"),
56  cl::opt<bool> PrintDebugCounter{
57  "print-debug-counter", cl::Hidden, cl::init(false), cl::Optional,
58  cl::desc("Print out debug counter info after all counters accumulated")};
59 
60  DebugCounterOwner() {
61  // Our destructor uses the debug stream. By referencing it here, we
62  // ensure that its destructor runs after our destructor.
63  (void)dbgs();
64  }
65 
66  // Print information when destroyed, iff command line option is specified.
67  ~DebugCounterOwner() {
68  if (DC.isCountingEnabled() && PrintDebugCounter)
69  DC.print(dbgs());
70  }
71 };
72 
73 } // anonymous namespace
74 
76 
78  static DebugCounterOwner O;
79  return O.DC;
80 }
81 
82 // This is called by the command line parser when it sees a value for the
83 // debug-counter option defined above.
84 void DebugCounter::push_back(const std::string &Val) {
85  if (Val.empty())
86  return;
87  // The strings should come in as counter=value
88  auto CounterPair = StringRef(Val).split('=');
89  if (CounterPair.second.empty()) {
90  errs() << "DebugCounter Error: " << Val << " does not have an = in it\n";
91  return;
92  }
93  // Now we have counter=value.
94  // First, process value.
95  int64_t CounterVal;
96  if (CounterPair.second.getAsInteger(0, CounterVal)) {
97  errs() << "DebugCounter Error: " << CounterPair.second
98  << " is not a number\n";
99  return;
100  }
101  // Now we need to see if this is the skip or the count, remove the suffix, and
102  // add it to the counter values.
103  if (CounterPair.first.endswith("-skip")) {
104  auto CounterName = CounterPair.first.drop_back(5);
105  unsigned CounterID = getCounterId(std::string(CounterName));
106  if (!CounterID) {
107  errs() << "DebugCounter Error: " << CounterName
108  << " is not a registered counter\n";
109  return;
110  }
112 
113  CounterInfo &Counter = Counters[CounterID];
114  Counter.Skip = CounterVal;
115  Counter.IsSet = true;
116  } else if (CounterPair.first.endswith("-count")) {
117  auto CounterName = CounterPair.first.drop_back(6);
118  unsigned CounterID = getCounterId(std::string(CounterName));
119  if (!CounterID) {
120  errs() << "DebugCounter Error: " << CounterName
121  << " is not a registered counter\n";
122  return;
123  }
125 
126  CounterInfo &Counter = Counters[CounterID];
127  Counter.StopAfter = CounterVal;
128  Counter.IsSet = true;
129  } else {
130  errs() << "DebugCounter Error: " << CounterPair.first
131  << " does not end with -skip or -count\n";
132  }
133 }
134 
136  SmallVector<StringRef, 16> CounterNames(RegisteredCounters.begin(),
137  RegisteredCounters.end());
138  sort(CounterNames);
139 
140  auto &Us = instance();
141  OS << "Counters and values:\n";
142  for (auto &CounterName : CounterNames) {
143  unsigned CounterID = getCounterId(std::string(CounterName));
144  OS << left_justify(RegisteredCounters[CounterID], 32) << ": {"
145  << Us.Counters[CounterID].Count << "," << Us.Counters[CounterID].Skip
146  << "," << Us.Counters[CounterID].StopAfter << "}\n";
147  }
148 }
149 
151  print(dbgs());
152 }
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::DebugCounter::enableAllCounters
static void enableAllCounters()
Definition: DebugCounter.h:148
llvm::cl::location
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:467
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::cl::CommaSeparated
@ CommaSeparated
Definition: CommandLine.h:166
llvm::DebugCounter
Definition: DebugCounter.h:56
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
DebugOptions.h
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
Format.h
llvm::DebugCounter::instance
static DebugCounter & instance()
Returns a reference to the singleton instance.
Definition: DebugCounter.cpp:77
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
CommandLine.h
llvm::outs
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
Definition: raw_ostream.cpp:883
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1657
llvm::cl::opt< bool >
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:264
llvm::DebugCounter::push_back
void push_back(const std::string &)
Definition: DebugCounter.cpp:84
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
llvm::UniqueVector::end
iterator end()
Return an iterator to the end of the vector.
Definition: UniqueVector.h:81
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::initDebugCounterOptions
void initDebugCounterOptions()
Definition: DebugCounter.cpp:75
llvm::left_justify
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
Definition: Format.h:145
llvm::DebugCounter::print
void print(raw_ostream &OS) const
Definition: DebugCounter.cpp:135
llvm::cl::Optional
@ Optional
Definition: CommandLine.h:116
std
Definition: BitVector.h:851
llvm::DebugCounter::getCounterId
unsigned getCounterId(const std::string &Name) const
Definition: DebugCounter.h:124
DebugCounter.h
llvm::UniqueVector::begin
iterator begin()
Return an iterator to the start of the vector.
Definition: UniqueVector.h:75
llvm::DebugCounter::isCountingEnabled
static bool isCountingEnabled()
Definition: DebugCounter.h:150
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:494
llvm::cl::desc
Definition: CommandLine.h:413
llvm::DebugCounter::dump
LLVM_DUMP_METHOD void dump() const
Definition: DebugCounter.cpp:150
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::cl::list
Definition: CommandLine.h:1648