1 //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
14 // This is useful for reporting information like the number of instructions
15 // simplified, optimized or removed by various transformations, like this:
17 // static Statistic NumInstsKilled("gcse", "Number of instructions killed");
19 // Later, in the code: ++NumInstsKilled;
21 // NOTE: Statistics *must* be declared as global variables.
23 //===----------------------------------------------------------------------===//
25 #ifndef LLVM_ADT_STATISTIC_H
26 #define LLVM_ADT_STATISTIC_H
28 #include "llvm/Config/llvm-config.h"
29 #include "llvm/Support/Compiler.h"
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
37 #if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
38 #define LLVM_ENABLE_STATS 1
49 const char *DebugType
;
52 std::atomic
<unsigned> Value
;
53 std::atomic
<bool> Initialized
;
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
; }
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
;
69 // Allow use of this class as the value itself.
70 operator unsigned() const { return getValue(); }
73 const Statistic
&operator=(unsigned Val
) {
74 Value
.store(Val
, std::memory_order_relaxed
);
78 const Statistic
&operator++() {
79 Value
.fetch_add(1, std::memory_order_relaxed
);
83 unsigned operator++(int) {
85 return Value
.fetch_add(1, std::memory_order_relaxed
);
88 const Statistic
&operator--() {
89 Value
.fetch_sub(1, std::memory_order_relaxed
);
93 unsigned operator--(int) {
95 return Value
.fetch_sub(1, std::memory_order_relaxed
);
98 const Statistic
&operator+=(unsigned V
) {
101 Value
.fetch_add(V
, std::memory_order_relaxed
);
105 const Statistic
&operator-=(unsigned V
) {
108 Value
.fetch_sub(V
, std::memory_order_relaxed
);
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
)) {
122 #else // Statistics are disabled in release builds.
124 const Statistic
&operator=(unsigned Val
) {
128 const Statistic
&operator++() {
132 unsigned operator++(int) {
136 const Statistic
&operator--() {
140 unsigned operator--(int) {
144 const Statistic
&operator+=(const unsigned &V
) {
148 const Statistic
&operator-=(const unsigned &V
) {
152 void updateMax(unsigned V
) {}
154 #endif // LLVM_ENABLE_STATS
158 if (!Initialized
.load(std::memory_order_acquire
))
163 void RegisterStatistic();
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}}
171 /// Enable the collection and printing of statistics.
172 void EnableStatistics(bool PrintOnExit
= true);
174 /// Check if statistics are enabled.
175 bool AreStatisticsEnabled();
177 /// Return a file stream to print our output on.
178 std::unique_ptr
<raw_fd_ostream
> CreateInfoOutputFile();
180 /// Print statistics to the file returned by CreateInfoOutputFile().
181 void PrintStatistics();
183 /// Print statistics to the given output stream.
184 void PrintStatistics(raw_ostream
&OS
);
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
);
192 /// Get the statistics. This can be used to look up the value of
193 /// statistics without needing to parse JSON.
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
199 const std::vector
<std::pair
<StringRef
, unsigned>> GetStatistics();
201 /// Reset the statistics. This can be used to zero and de-register the
202 /// statistics in order to measure a compilation.
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.
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
214 void ResetStatistics();
216 } // end namespace llvm
218 #endif // LLVM_ADT_STATISTIC_H