4343#ifndef LLVM_SUPPORT_DEBUGCOUNTER_H
4444#define LLVM_SUPPORT_DEBUGCOUNTER_H
4545
46+ #include " llvm/ADT/ArrayRef.h"
4647#include " llvm/ADT/DenseMap.h"
4748#include " llvm/ADT/StringRef.h"
4849#include " llvm/ADT/UniqueVector.h"
@@ -55,6 +56,19 @@ class raw_ostream;
5556
5657class DebugCounter {
5758public:
59+ struct Chunk {
60+ int64_t Begin;
61+ int64_t End;
62+ void print (llvm::raw_ostream &OS);
63+ bool contains (int64_t Idx) { return Idx >= Begin && Idx <= End; }
64+ };
65+
66+ static void printChunks (raw_ostream &OS, ArrayRef<Chunk>);
67+
68+ // / Return true on parsing error and print the error message on the
69+ // / llvm::errs()
70+ static bool parseChunks (StringRef Str, SmallVector<Chunk> &Res);
71+
5872 // / Returns a reference to the singleton instance.
5973 static DebugCounter &instance ();
6074
@@ -69,29 +83,12 @@ class DebugCounter {
6983 static unsigned registerCounter (StringRef Name, StringRef Desc) {
7084 return instance ().addCounter (std::string (Name), std::string (Desc));
7185 }
86+ static bool shouldExecuteImpl (unsigned CounterName);
87+
7288 inline static bool shouldExecute (unsigned CounterName) {
7389 if (!isCountingEnabled ())
7490 return true ;
75-
76- auto &Us = instance ();
77- auto Result = Us.Counters .find (CounterName);
78- if (Result != Us.Counters .end ()) {
79- auto &CounterInfo = Result->second ;
80- ++CounterInfo.Count ;
81-
82- // We only execute while the Skip is not smaller than Count,
83- // and the StopAfter + Skip is larger than Count.
84- // Negative counters always execute.
85- if (CounterInfo.Skip < 0 )
86- return true ;
87- if (CounterInfo.Skip >= CounterInfo.Count )
88- return false ;
89- if (CounterInfo.StopAfter < 0 )
90- return true ;
91- return CounterInfo.StopAfter + CounterInfo.Skip >= CounterInfo.Count ;
92- }
93- // Didn't find the counter, should we warn?
94- return true ;
91+ return shouldExecuteImpl (CounterName);
9592 }
9693
9794 // Return true if a given counter had values set (either programatically or on
@@ -101,18 +98,25 @@ class DebugCounter {
10198 return instance ().Counters [ID].IsSet ;
10299 }
103100
104- // Return the Count for a counter. This only works for set counters.
105- static int64_t getCounterValue (unsigned ID) {
101+ struct CounterState {
102+ int64_t Count;
103+ uint64_t ChunkIdx;
104+ };
105+
106+ // Return the state of a counter. This only works for set counters.
107+ static CounterState getCounterState (unsigned ID) {
106108 auto &Us = instance ();
107109 auto Result = Us.Counters .find (ID);
108110 assert (Result != Us.Counters .end () && " Asking about a non-set counter" );
109- return Result->second .Count ;
111+ return { Result->second .Count , Result-> second . CurrChunkIdx } ;
110112 }
111113
112- // Set a registered counter to a given Count value .
113- static void setCounterValue (unsigned ID, int64_t Count ) {
114+ // Set a registered counter to a given state .
115+ static void setCounterState (unsigned ID, CounterState State ) {
114116 auto &Us = instance ();
115- Us.Counters [ID].Count = Count;
117+ auto &Counter = Us.Counters [ID];
118+ Counter.Count = State.Count ;
119+ Counter.CurrChunkIdx = State.ChunkIdx ;
116120 }
117121
118122 // Dump or print the current counter set into llvm::dbgs().
@@ -152,11 +156,11 @@ class DebugCounter {
152156#ifdef NDEBUG
153157 return false ;
154158#else
155- return instance ().Enabled ;
159+ return instance ().Enabled || instance (). ShouldPrintCounter ;
156160#endif
157161 }
158162
159- private :
163+ protected :
160164 unsigned addCounter (const std::string &Name, const std::string &Desc) {
161165 unsigned Result = RegisteredCounters.insert (Name);
162166 Counters[Result] = {};
@@ -166,17 +170,22 @@ class DebugCounter {
166170 // Struct to store counter info.
167171 struct CounterInfo {
168172 int64_t Count = 0 ;
169- int64_t Skip = 0 ;
170- int64_t StopAfter = -1 ;
173+ uint64_t CurrChunkIdx = 0 ;
171174 bool IsSet = false ;
172175 std::string Desc;
176+ SmallVector<Chunk> Chunks;
173177 };
178+
174179 DenseMap<unsigned , CounterInfo> Counters;
175180 CounterVector RegisteredCounters;
176181
177182 // Whether we should do DebugCounting at all. DebugCounters aren't
178183 // thread-safe, so this should always be false in multithreaded scenarios.
179184 bool Enabled = false ;
185+
186+ bool ShouldPrintCounter = false ;
187+
188+ bool BreakOnLast = false ;
180189};
181190
182191#define DEBUG_COUNTER (VARNAME, COUNTERNAME, DESC ) \
0 commit comments