LLVM: lib/Support/DebugCounter.cpp Source File (original) (raw)
2
4
8
9using namespace llvm;
10
11namespace llvm {
12
19
21 if (Chunks.empty()) {
22 OS << "empty";
23 } else {
24 bool IsFirst = true;
25 for (auto E : Chunks) {
26 if (!IsFirst)
27 OS << ':';
28 else
29 IsFirst = false;
30 E.print(OS);
31 }
32 }
33}
34
37
38 auto ConsumeInt = [&]() -> int64_t {
40 Remaining.take_until([](char c) { return c < '0' || c > '9'; });
41 int64_t Res;
42 if (Number.getAsInteger(10, Res)) {
43 errs() << "Failed to parse int at : " << Remaining << "\n";
44 return -1;
45 }
47 return Res;
48 };
49
50 while (1) {
51 int64_t Num = ConsumeInt();
52 if (Num == -1)
53 return true;
54 if (!Chunks.empty() && Num <= Chunks[Chunks.size() - 1].End) {
55 errs() << "Expected Chunks to be in increasing order " << Num
56 << " <= " << Chunks[Chunks.size() - 1].End << "\n";
57 return true;
58 }
61 int64_t Num2 = ConsumeInt();
62 if (Num2 == -1)
63 return true;
64 if (Num >= Num2) {
65 errs() << "Expected " << Num << " < " << Num2 << " in " << Num << "-"
66 << Num2 << "\n";
67 return true;
68 }
69
71 } else {
73 }
76 continue;
77 }
78 if (Remaining.empty())
79 break;
80 errs() << "Failed to parse at : " << Remaining;
81 return true;
82 }
83 return false;
84}
85
86}
87
88namespace {
89
90
91
92class DebugCounterList : public cl::list<std::string, DebugCounter> {
93private:
95
96public:
97 template <class... Mods>
98 explicit DebugCounterList(Mods &&... Ms) : Base(std::forward(Ms)...) {}
99
100private:
101 void printOptionInfo(size_t GlobalWidth) const override {
102
103
104
105
106
107
108
109 outs() << " -" << ArgStr;
110
111
112 Option::printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6);
114 for (const auto &Entry : CounterInstance) {
115 const auto &[Name, Desc] = CounterInstance.getCounterDesc(Entry.second);
116 size_t NumSpaces = GlobalWidth - Name.size() - 8;
119 }
120 }
121};
122
123
124
125
126
128 DebugCounterList DebugCounterOption{
130 cl::desc("Comma separated list of debug counter skip and count"),
132 cl::opt<bool, true> PrintDebugCounter{
133 "print-debug-counter",
138 cl::desc("Print out debug counter info after all counters accumulated"),
141 activateAllCounters();
142 })};
143 cl::opt<bool, true> PrintDebugCounterQueries{
144 "print-debug-counter-queries",
147 cl::location(this->ShouldPrintCounterQueries),
149 cl::desc("Print out each query of an enabled debug counter")};
150 cl::opt<bool, true> BreakOnLastCount{
151 "debug-counter-break-on-last",
156 cl::desc("Insert a break point on the last enabled count of a "
157 "chunks list")};
158
159 DebugCounterOwner() {
160
161
162 (void)dbgs();
163 }
164
165
166 ~DebugCounterOwner() {
167 if (ShouldPrintCounter)
169 }
170};
171
172}
173
174
175
176
178
180
182
183
184
186 if (Val.empty())
187 return;
188
189
191 if (CounterPair.second.empty()) {
192 errs() << "DebugCounter Error: " << Val << " does not have an = in it\n";
193 return;
194 }
195 StringRef CounterName = CounterPair.first;
197
198 if (parseChunks(CounterPair.second, Chunks)) {
199 return;
200 }
201
203 if (!Counter) {
204 errs() << "DebugCounter Error: " << CounterName
205 << " is not a registered counter\n";
206 return;
207 }
208
209 Counter->Active = Counter->IsSet = true;
210 Counter->Chunks = std::move(Chunks);
211}
212
215 sort(CounterNames);
216
217 OS << "Counters and values:\n";
218 for (StringRef CounterName : CounterNames) {
220 OS << left_justify(C->Name, 32) << ": {" << C->Count << ",";
222 OS << "}\n";
223 }
224}
225
227 int64_t CurrCount = Info.Count++;
228 uint64_t CurrIdx = Info.CurrChunkIdx;
229
230 if (Info.Chunks.empty())
231 return true;
232 if (CurrIdx >= Info.Chunks.size())
233 return false;
234
235 bool Res = Info.Chunks[CurrIdx].contains(CurrCount);
236 if (BreakOnLast && CurrIdx == (Info.Chunks.size() - 1) &&
237 CurrCount == Info.Chunks[CurrIdx].End) {
239 }
240 if (CurrCount > Info.Chunks[CurrIdx].End) {
241 Info.CurrChunkIdx++;
242
243
244 if (Info.CurrChunkIdx < Info.Chunks.size() &&
245 CurrCount == Info.Chunks[Info.CurrChunkIdx].Begin)
246 return true;
247 }
248 return Res;
249}
250
253 bool Res = Us.handleCounterIncrement(Counter);
254 if (Us.ShouldPrintCounterQueries && Counter.IsSet) {
255 dbgs() << "DebugCounter " << Counter.Name << "=" << (Counter.Count - 1)
256 << (Res ? " execute" : " skip") << "\n";
257 }
258 return Res;
259}
260
261#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
265#endif
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_BUILTIN_DEBUGTRAP
LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to an expression which causes the pro...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static ManagedStatic< DebugCounterOwner > Owner
Definition DebugCounter.cpp:177
This file provides an implementation of debug counters.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
Struct to store counter info.
CounterInfo * getCounterInfo(StringRef Name) const
static LLVM_ABI void printChunks(raw_ostream &OS, ArrayRef< Chunk >)
Definition DebugCounter.cpp:20
bool handleCounterIncrement(CounterInfo &Info)
Definition DebugCounter.cpp:226
LLVM_ABI void push_back(const std::string &)
Definition DebugCounter.cpp:185
static LLVM_ABI bool parseChunks(StringRef Str, SmallVector< Chunk > &Res)
Return true on parsing error and print the error message on the llvm::errs()
Definition DebugCounter.cpp:35
static LLVM_ABI bool shouldExecuteImpl(CounterInfo &Counter)
Definition DebugCounter.cpp:251
static LLVM_ABI DebugCounter & instance()
Returns a reference to the singleton instance.
Definition DebugCounter.cpp:181
LLVM_ABI void print(raw_ostream &OS) const
Definition DebugCounter.cpp:213
LLVM_DUMP_METHOD void dump() const
Definition DebugCounter.cpp:262
MapVector< StringRef, CounterInfo * > Counters
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef take_until(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
cb< typename detail::callback_traits< F >::result_type, typename detail::callback_traits< F >::arg_type > callback(F CB)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
void initDebugCounterOptions()
Definition DebugCounter.cpp:179
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
Implement std::hash so that hash_code can be used in STL containers.
LLVM_ABI void print(llvm::raw_ostream &OS)
Definition DebugCounter.cpp:13