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