]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ADT/Statistic.h
Merge ^/head r326936 through r327149.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ADT / Statistic.h
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/Support/Atomic.h"
30 #include "llvm/Support/Compiler.h"
31 #include <atomic>
32 #include <memory>
33
34 namespace llvm {
35
36 class raw_ostream;
37 class raw_fd_ostream;
38
39 class Statistic {
40 public:
41   const char *DebugType;
42   const char *Name;
43   const char *Desc;
44   std::atomic<unsigned> Value;
45   bool Initialized;
46
47   unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
48   const char *getDebugType() const { return DebugType; }
49   const char *getName() const { return Name; }
50   const char *getDesc() const { return Desc; }
51
52   /// construct - This should only be called for non-global statistics.
53   void construct(const char *debugtype, const char *name, const char *desc) {
54     DebugType = debugtype;
55     Name = name;
56     Desc = desc;
57     Value = 0;
58     Initialized = false;
59   }
60
61   // Allow use of this class as the value itself.
62   operator unsigned() const { return getValue(); }
63
64 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
65    const Statistic &operator=(unsigned Val) {
66     Value.store(Val, std::memory_order_relaxed);
67     return init();
68   }
69
70   const Statistic &operator++() {
71     Value.fetch_add(1, std::memory_order_relaxed);
72     return init();
73   }
74
75   unsigned operator++(int) {
76     init();
77     return Value.fetch_add(1, std::memory_order_relaxed);
78   }
79
80   const Statistic &operator--() {
81     Value.fetch_sub(1, std::memory_order_relaxed);
82     return init();
83   }
84
85   unsigned operator--(int) {
86     init();
87     return Value.fetch_sub(1, std::memory_order_relaxed);
88   }
89
90   const Statistic &operator+=(unsigned V) {
91     if (V == 0)
92       return *this;
93     Value.fetch_add(V, std::memory_order_relaxed);
94     return init();
95   }
96
97   const Statistic &operator-=(unsigned V) {
98     if (V == 0)
99       return *this;
100     Value.fetch_sub(V, std::memory_order_relaxed);
101     return init();
102   }
103
104   void updateMax(unsigned V) {
105     unsigned PrevMax = Value.load(std::memory_order_relaxed);
106     // Keep trying to update max until we succeed or another thread produces
107     // a bigger max than us.
108     while (V > PrevMax && !Value.compare_exchange_weak(
109                               PrevMax, V, std::memory_order_relaxed)) {
110     }
111     init();
112   }
113
114 #else  // Statistics are disabled in release builds.
115
116   const Statistic &operator=(unsigned Val) {
117     return *this;
118   }
119
120   const Statistic &operator++() {
121     return *this;
122   }
123
124   unsigned operator++(int) {
125     return 0;
126   }
127
128   const Statistic &operator--() {
129     return *this;
130   }
131
132   unsigned operator--(int) {
133     return 0;
134   }
135
136   const Statistic &operator+=(const unsigned &V) {
137     return *this;
138   }
139
140   const Statistic &operator-=(const unsigned &V) {
141     return *this;
142   }
143
144   void updateMax(unsigned V) {}
145
146 #endif  // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
147
148 protected:
149   Statistic &init() {
150     bool tmp = Initialized;
151     sys::MemoryFence();
152     if (!tmp) RegisterStatistic();
153     TsanHappensAfter(this);
154     return *this;
155   }
156
157   void RegisterStatistic();
158 };
159
160 // STATISTIC - A macro to make definition of statistics really simple.  This
161 // automatically passes the DEBUG_TYPE of the file into the statistic.
162 #define STATISTIC(VARNAME, DESC)                                               \
163   static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false}
164
165 /// \brief Enable the collection and printing of statistics.
166 void EnableStatistics(bool PrintOnExit = true);
167
168 /// \brief Check if statistics are enabled.
169 bool AreStatisticsEnabled();
170
171 /// \brief Return a file stream to print our output on.
172 std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
173
174 /// \brief Print statistics to the file returned by CreateInfoOutputFile().
175 void PrintStatistics();
176
177 /// \brief Print statistics to the given output stream.
178 void PrintStatistics(raw_ostream &OS);
179
180 /// Print statistics in JSON format. This does include all global timers (\see
181 /// Timer, TimerGroup). Note that the timers are cleared after printing and will
182 /// not be printed in human readable form or in a second call of
183 /// PrintStatisticsJSON().
184 void PrintStatisticsJSON(raw_ostream &OS);
185
186 } // end namespace llvm
187
188 #endif // LLVM_ADT_STATISTIC_H