OSDN Git Service

Fix cmake's multi-config generators after r326738
[android-x86/external-llvm.git] / 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/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:
158   Statistic &init() {
159     if (!Initialized.load(std::memory_order_acquire))
160       RegisterStatistic();
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 /// \brief Enable the collection and printing of statistics.
173 void EnableStatistics(bool PrintOnExit = true);
174
175 /// \brief Check if statistics are enabled.
176 bool AreStatisticsEnabled();
177
178 /// \brief Return a file stream to print our output on.
179 std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
180
181 /// \brief Print statistics to the file returned by CreateInfoOutputFile().
182 void PrintStatistics();
183
184 /// \brief 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 /// \brief 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 } // end namespace llvm
203
204 #endif // LLVM_ADT_STATISTIC_H