LLVM  8.0.1
Statistic.h
Go to the documentation of this file.
1 //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the 'Statistic' class, which is designed to be an easy way
11 // to expose various metrics from passes. These statistics are printed at the
12 // end of a run (from llvm_shutdown), when the -stats command line option is
13 // passed on the command line.
14 //
15 // This is useful for reporting information like the number of instructions
16 // simplified, optimized or removed by various transformations, like this:
17 //
18 // static Statistic NumInstsKilled("gcse", "Number of instructions killed");
19 //
20 // Later, in the code: ++NumInstsKilled;
21 //
22 // NOTE: Statistics *must* be declared as global variables.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 #ifndef LLVM_ADT_STATISTIC_H
27 #define LLVM_ADT_STATISTIC_H
28 
29 #include "llvm/Config/llvm-config.h"
30 #include "llvm/Support/Compiler.h"
31 #include <atomic>
32 #include <memory>
33 #include <vector>
34 
35 // Determine whether statistics should be enabled. We must do it here rather
36 // than in CMake because multi-config generators cannot determine this at
37 // configure time.
38 #if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
39 #define LLVM_ENABLE_STATS 1
40 #endif
41 
42 namespace llvm {
43 
44 class raw_ostream;
45 class raw_fd_ostream;
46 class StringRef;
47 
48 class Statistic {
49 public:
50  const char *DebugType;
51  const char *Name;
52  const char *Desc;
53  std::atomic<unsigned> Value;
54  std::atomic<bool> Initialized;
55 
56  unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
57  const char *getDebugType() const { return DebugType; }
58  const char *getName() const { return Name; }
59  const char *getDesc() const { return Desc; }
60 
61  /// construct - This should only be called for non-global statistics.
62  void construct(const char *debugtype, const char *name, const char *desc) {
63  DebugType = debugtype;
64  Name = name;
65  Desc = desc;
66  Value = 0;
67  Initialized = false;
68  }
69 
70  // Allow use of this class as the value itself.
71  operator unsigned() const { return getValue(); }
72 
73 #if LLVM_ENABLE_STATS
74  const Statistic &operator=(unsigned Val) {
75  Value.store(Val, std::memory_order_relaxed);
76  return init();
77  }
78 
79  const Statistic &operator++() {
80  Value.fetch_add(1, std::memory_order_relaxed);
81  return init();
82  }
83 
84  unsigned operator++(int) {
85  init();
86  return Value.fetch_add(1, std::memory_order_relaxed);
87  }
88 
89  const Statistic &operator--() {
90  Value.fetch_sub(1, std::memory_order_relaxed);
91  return init();
92  }
93 
94  unsigned operator--(int) {
95  init();
96  return Value.fetch_sub(1, std::memory_order_relaxed);
97  }
98 
99  const Statistic &operator+=(unsigned V) {
100  if (V == 0)
101  return *this;
102  Value.fetch_add(V, std::memory_order_relaxed);
103  return init();
104  }
105 
106  const Statistic &operator-=(unsigned V) {
107  if (V == 0)
108  return *this;
109  Value.fetch_sub(V, std::memory_order_relaxed);
110  return init();
111  }
112 
113  void updateMax(unsigned V) {
114  unsigned PrevMax = Value.load(std::memory_order_relaxed);
115  // Keep trying to update max until we succeed or another thread produces
116  // a bigger max than us.
117  while (V > PrevMax && !Value.compare_exchange_weak(
118  PrevMax, V, std::memory_order_relaxed)) {
119  }
120  init();
121  }
122 
123 #else // Statistics are disabled in release builds.
124 
125  const Statistic &operator=(unsigned Val) {
126  return *this;
127  }
128 
129  const Statistic &operator++() {
130  return *this;
131  }
132 
133  unsigned operator++(int) {
134  return 0;
135  }
136 
137  const Statistic &operator--() {
138  return *this;
139  }
140 
141  unsigned operator--(int) {
142  return 0;
143  }
144 
145  const Statistic &operator+=(const unsigned &V) {
146  return *this;
147  }
148 
149  const Statistic &operator-=(const unsigned &V) {
150  return *this;
151  }
152 
153  void updateMax(unsigned V) {}
154 
155 #endif // LLVM_ENABLE_STATS
156 
157 protected:
159  if (!Initialized.load(std::memory_order_acquire))
161  return *this;
162  }
163 
164  void RegisterStatistic();
165 };
166 
167 // STATISTIC - A macro to make definition of statistics really simple. This
168 // automatically passes the DEBUG_TYPE of the file into the statistic.
169 #define STATISTIC(VARNAME, DESC) \
170  static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, {false}}
171 
172 /// Enable the collection and printing of statistics.
173 void EnableStatistics(bool PrintOnExit = true);
174 
175 /// Check if statistics are enabled.
176 bool AreStatisticsEnabled();
177 
178 /// Return a file stream to print our output on.
179 std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
180 
181 /// Print statistics to the file returned by CreateInfoOutputFile().
182 void PrintStatistics();
183 
184 /// Print statistics to the given output stream.
185 void PrintStatistics(raw_ostream &OS);
186 
187 /// Print statistics in JSON format. This does include all global timers (\see
188 /// Timer, TimerGroup). Note that the timers are cleared after printing and will
189 /// not be printed in human readable form or in a second call of
190 /// PrintStatisticsJSON().
191 void PrintStatisticsJSON(raw_ostream &OS);
192 
193 /// Get the statistics. This can be used to look up the value of
194 /// statistics without needing to parse JSON.
195 ///
196 /// This function does not prevent statistics being updated by other threads
197 /// during it's execution. It will return the value at the point that it is
198 /// read. However, it will prevent new statistics from registering until it
199 /// completes.
200 const std::vector<std::pair<StringRef, unsigned>> GetStatistics();
201 
202 /// Reset the statistics. This can be used to zero and de-register the
203 /// statistics in order to measure a compilation.
204 ///
205 /// When this function begins to call destructors prior to returning, all
206 /// statistics will be zero and unregistered. However, that might not remain the
207 /// case by the time this function finishes returning. Whether update from other
208 /// threads are lost or merely deferred until during the function return is
209 /// timing sensitive.
210 ///
211 /// Callers who intend to use this to measure statistics for a single
212 /// compilation should ensure that no compilations are in progress at the point
213 /// this function is called and that only one compilation executes until calling
214 /// GetStatistics().
215 void ResetStatistics();
216 
217 } // end namespace llvm
218 
219 #endif // LLVM_ADT_STATISTIC_H
static bool PrintOnExit
Definition: Statistic.cpp:52
std::atomic< unsigned > Value
Definition: Statistic.h:53
unsigned operator++(int)
Definition: Statistic.h:84
const Statistic & operator=(unsigned Val)
Definition: Statistic.h:74
void EnableStatistics(bool PrintOnExit=true)
Enable the collection and printing of statistics.
Definition: Statistic.cpp:129
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void construct(const char *debugtype, const char *name, const char *desc)
construct - This should only be called for non-global statistics.
Definition: Statistic.h:62
void updateMax(unsigned V)
Definition: Statistic.h:113
void RegisterStatistic()
RegisterStatistic - The first time a statistic is bumped, this method is called.
Definition: Statistic.cpp:94
void ResetStatistics()
Reset the statistics.
Definition: Statistic.cpp:266
const Statistic & operator+=(unsigned V)
Definition: Statistic.h:99
const char * getDebugType() const
Definition: Statistic.h:57
const Statistic & operator++()
Definition: Statistic.h:79
const Statistic & operator--()
Definition: Statistic.h:89
std::unique_ptr< raw_fd_ostream > CreateInfoOutputFile()
Return a file stream to print our output on.
Definition: Timer.cpp:55
const std::vector< std::pair< StringRef, unsigned > > GetStatistics()
Get the statistics.
Definition: Statistic.cpp:257
void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
Definition: Statistic.cpp:203
const Statistic & operator-=(unsigned V)
Definition: Statistic.h:106
unsigned getValue() const
Definition: Statistic.h:56
const char * DebugType
Definition: Statistic.h:50
const char * getDesc() const
Definition: Statistic.h:59
Statistic & init()
Definition: Statistic.h:158
const char * Name
Definition: Statistic.h:51
const char * getName() const
Definition: Statistic.h:58
const char * Desc
Definition: Statistic.h:52
void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
Definition: Statistic.cpp:229
std::atomic< bool > Initialized
Definition: Statistic.h:54
static const char * name
unsigned operator--(int)
Definition: Statistic.h:94
bool AreStatisticsEnabled()
Check if statistics are enabled.
Definition: Statistic.cpp:134