• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getValue()47   unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
getDebugType()48   const char *getDebugType() const { return DebugType; }
getName()49   const char *getName() const { return Name; }
getDesc()50   const char *getDesc() const { return Desc; }
51 
52   /// construct - This should only be called for non-global statistics.
construct(const char * debugtype,const char * name,const char * desc)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 #else  // Statistics are disabled in release builds.
105 
106   const Statistic &operator=(unsigned Val) {
107     return *this;
108   }
109 
110   const Statistic &operator++() {
111     return *this;
112   }
113 
114   unsigned operator++(int) {
115     return 0;
116   }
117 
118   const Statistic &operator--() {
119     return *this;
120   }
121 
122   unsigned operator--(int) {
123     return 0;
124   }
125 
126   const Statistic &operator+=(const unsigned &V) {
127     return *this;
128   }
129 
130   const Statistic &operator-=(const unsigned &V) {
131     return *this;
132   }
133 
134 #endif  // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
135 
136 protected:
init()137   Statistic &init() {
138     bool tmp = Initialized;
139     sys::MemoryFence();
140     if (!tmp) RegisterStatistic();
141     TsanHappensAfter(this);
142     return *this;
143   }
144 
145   void RegisterStatistic();
146 };
147 
148 // STATISTIC - A macro to make definition of statistics really simple.  This
149 // automatically passes the DEBUG_TYPE of the file into the statistic.
150 #define STATISTIC(VARNAME, DESC)                                               \
151   static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false}
152 
153 /// \brief Enable the collection and printing of statistics.
154 void EnableStatistics(bool PrintOnExit = true);
155 
156 /// \brief Check if statistics are enabled.
157 bool AreStatisticsEnabled();
158 
159 /// \brief Return a file stream to print our output on.
160 std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
161 
162 /// \brief Print statistics to the file returned by CreateInfoOutputFile().
163 void PrintStatistics();
164 
165 /// \brief Print statistics to the given output stream.
166 void PrintStatistics(raw_ostream &OS);
167 
168 /// Print statistics in JSON format. This does include all global timers (\see
169 /// Timer, TimerGroup). Note that the timers are cleared after printing and will
170 /// not be printed in human readable form or in a second call of
171 /// PrintStatisticsJSON().
172 void PrintStatisticsJSON(raw_ostream &OS);
173 
174 } // end namespace llvm
175 
176 #endif // LLVM_ADT_STATISTIC_H
177