4444
4545#include " llvm/ADT/ArrayRef.h"
4646#include " llvm/ADT/DenseMap.h"
47+ #include " llvm/ADT/MapVector.h"
4748#include " llvm/ADT/StringRef.h"
48- #include " llvm/ADT/UniqueVector.h"
4949#include " llvm/Support/Compiler.h"
5050#include " llvm/Support/Debug.h"
5151#include < string>
@@ -63,6 +63,29 @@ class DebugCounter {
6363 bool contains (int64_t Idx) const { return Idx >= Begin && Idx <= End; }
6464 };
6565
66+ // / Struct to store counter info.
67+ class CounterInfo {
68+ friend class DebugCounter ;
69+
70+ // / Whether counting should be enabled, either due to -debug-counter or
71+ // / -print-debug-counter.
72+ bool Active = false ;
73+ // / Whether chunks for the counter are set (differs from Active in that
74+ // / -print-debug-counter uses Active=true, IsSet=false).
75+ bool IsSet = false ;
76+
77+ int64_t Count = 0 ;
78+ uint64_t CurrChunkIdx = 0 ;
79+ StringRef Name;
80+ StringRef Desc;
81+ SmallVector<Chunk> Chunks;
82+
83+ public:
84+ CounterInfo (StringRef Name, StringRef Desc) : Name(Name), Desc(Desc) {
85+ DebugCounter::registerCounter (this );
86+ }
87+ };
88+
6689 LLVM_ABI static void printChunks (raw_ostream &OS, ArrayRef<Chunk>);
6790
6891 // / Return true on parsing error and print the error message on the
@@ -75,48 +98,46 @@ class DebugCounter {
7598 // Used by the command line option parser to push a new value it parsed.
7699 LLVM_ABI void push_back (const std::string &);
77100
78- // Register a counter with the specified name .
101+ // Register a counter with the specified counter information .
79102 //
80103 // FIXME: Currently, counter registration is required to happen before command
81104 // line option parsing. The main reason to register counters is to produce a
82105 // nice list of them on the command line, but i'm not sure this is worth it.
83- static unsigned registerCounter (StringRef Name, StringRef Desc ) {
84- return instance ().addCounter (std::string (Name), std::string (Desc) );
106+ static void registerCounter (CounterInfo *Info ) {
107+ instance ().addCounter (Info );
85108 }
86- LLVM_ABI static bool shouldExecuteImpl (unsigned CounterName );
109+ LLVM_ABI static bool shouldExecuteImpl (CounterInfo &Counter );
87110
88- inline static bool shouldExecute (unsigned CounterName) {
89- if (!isCountingEnabled ())
111+ inline static bool shouldExecute (CounterInfo &Counter) {
112+ // Compile to nothing when debugging is off
113+ #ifdef NDEBUG
114+ return true ;
115+ #else
116+ if (!Counter.Active )
90117 return true ;
91- return shouldExecuteImpl (CounterName);
118+ return shouldExecuteImpl (Counter);
119+ #endif
92120 }
93121
94122 // Return true if a given counter had values set (either programatically or on
95123 // the command line). This will return true even if those values are
96124 // currently in a state where the counter will always execute.
97- static bool isCounterSet (unsigned ID) {
98- return instance ().Counters [ID].IsSet ;
99- }
125+ static bool isCounterSet (CounterInfo &Info) { return Info.IsSet ; }
100126
101127 struct CounterState {
102128 int64_t Count;
103129 uint64_t ChunkIdx;
104130 };
105131
106132 // Return the state of a counter. This only works for set counters.
107- static CounterState getCounterState (unsigned ID) {
108- auto &Us = instance ();
109- auto Result = Us.Counters .find (ID);
110- assert (Result != Us.Counters .end () && " Asking about a non-set counter" );
111- return {Result->second .Count , Result->second .CurrChunkIdx };
133+ static CounterState getCounterState (CounterInfo &Info) {
134+ return {Info.Count , Info.CurrChunkIdx };
112135 }
113136
114137 // Set a registered counter to a given state.
115- static void setCounterState (unsigned ID, CounterState State) {
116- auto &Us = instance ();
117- auto &Counter = Us.Counters [ID];
118- Counter.Count = State.Count ;
119- Counter.CurrChunkIdx = State.ChunkIdx ;
138+ static void setCounterState (CounterInfo &Info, CounterState State) {
139+ Info.Count = State.Count ;
140+ Info.CurrChunkIdx = State.ChunkIdx ;
120141 }
121142
122143#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -126,66 +147,38 @@ class DebugCounter {
126147
127148 LLVM_ABI void print (raw_ostream &OS) const ;
128149
129- // Get the counter ID for a given named counter, or return 0 if none is found.
130- unsigned getCounterId (const std::string &Name) const {
131- return RegisteredCounters.idFor (Name);
150+ // Get the counter info for a given named counter,
151+ // or return null if none is found.
152+ CounterInfo *getCounterInfo (StringRef Name) const {
153+ return Counters.lookup (Name);
132154 }
133155
134156 // Return the number of registered counters.
135- unsigned int getNumCounters () const { return RegisteredCounters .size (); }
157+ unsigned int getNumCounters () const { return Counters .size (); }
136158
137- // Return the name and description of the counter with the given ID .
138- std::pair<std::string, std::string> getCounterInfo ( unsigned ID ) const {
139- return {RegisteredCounters[ID], Counters. lookup (ID). Desc };
159+ // Return the name and description of the counter with the given info .
160+ std::pair<StringRef, StringRef> getCounterDesc (CounterInfo *Info ) const {
161+ return {Info-> Name , Info-> Desc };
140162 }
141163
142164 // Iterate through the registered counters
143- using CounterVector = UniqueVector<std::string>;
144- CounterVector::const_iterator begin () const {
145- return RegisteredCounters.begin ();
165+ MapVector<StringRef, CounterInfo *>::const_iterator begin () const {
166+ return Counters.begin ();
167+ }
168+ MapVector<StringRef, CounterInfo *>::const_iterator end () const {
169+ return Counters.end ();
146170 }
147- CounterVector::const_iterator end () const { return RegisteredCounters.end (); }
148-
149- // Force-enables counting all DebugCounters.
150- //
151- // Since DebugCounters are incompatible with threading (not only do they not
152- // make sense, but we'll also see data races), this should only be used in
153- // contexts where we're certain we won't spawn threads.
154- static void enableAllCounters () { instance ().Enabled = true ; }
155171
156- static bool isCountingEnabled () {
157- // Compile to nothing when debugging is off
158- #ifdef NDEBUG
159- return false ;
160- #else
161- return instance ().Enabled ;
162- #endif
172+ void activateAllCounters () {
173+ for (auto &[_, Counter] : Counters)
174+ Counter->Active = true ;
163175 }
164176
165177protected:
166- unsigned addCounter (const std::string &Name, const std::string &Desc) {
167- unsigned Result = RegisteredCounters.insert (Name);
168- auto &C = Counters[Result];
169- C = {};
170- C.Desc = Desc;
171- return Result;
172- }
173- // Struct to store counter info.
174- struct CounterInfo {
175- int64_t Count = 0 ;
176- uint64_t CurrChunkIdx = 0 ;
177- bool IsSet = false ;
178- std::string Desc;
179- SmallVector<Chunk> Chunks;
180- };
178+ void addCounter (CounterInfo *Info) { Counters[Info->Name ] = Info; }
181179 bool handleCounterIncrement (CounterInfo &Info);
182180
183- DenseMap<unsigned , CounterInfo> Counters;
184- CounterVector RegisteredCounters;
185-
186- // Whether we should do DebugCounting at all. DebugCounters aren't
187- // thread-safe, so this should always be false in multithreaded scenarios.
188- bool Enabled = false ;
181+ MapVector<StringRef, CounterInfo *> Counters;
189182
190183 bool ShouldPrintCounter = false ;
191184
@@ -195,8 +188,7 @@ class DebugCounter {
195188};
196189
197190#define DEBUG_COUNTER (VARNAME, COUNTERNAME, DESC ) \
198- static const unsigned VARNAME = \
199- DebugCounter::registerCounter (COUNTERNAME, DESC)
191+ static DebugCounter::CounterInfo VARNAME (COUNTERNAME, DESC)
200192
201193} // namespace llvm
202194#endif
0 commit comments