• 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 class raw_ostream;
36 class raw_fd_ostream;
37 
38 class Statistic {
39 public:
40   const char *DebugType;
41   const char *Name;
42   const char *Desc;
43   std::atomic<unsigned> Value;
44   bool Initialized;
45 
getValue()46   unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
getDebugType()47   const char *getDebugType() const { return DebugType; }
getName()48   const char *getName() const { return Name; }
getDesc()49   const char *getDesc() const { return Desc; }
50 
51   /// construct - This should only be called for non-global statistics.
construct(const char * debugtype,const char * name,const char * desc)52   void construct(const char *debugtype, const char *name, const char *desc) {
53     DebugType = debugtype;
54     Name = name;
55     Desc = desc;
56     Value = 0;
57     Initialized = false;
58   }
59 
60   // Allow use of this class as the value itself.
61   operator unsigned() const { return getValue(); }
62 
63 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
64    const Statistic &operator=(unsigned Val) {
65     Value.store(Val, std::memory_order_relaxed);
66     return init();
67   }
68 
69   const Statistic &operator++() {
70     Value.fetch_add(1, std::memory_order_relaxed);
71     return init();
72   }
73 
74   unsigned operator++(int) {
75     init();
76     return Value.fetch_add(1, std::memory_order_relaxed);
77   }
78 
79   const Statistic &operator--() {
80     Value.fetch_sub(1, std::memory_order_relaxed);
81     return init();
82   }
83 
84   unsigned operator--(int) {
85     init();
86     return Value.fetch_sub(1, std::memory_order_relaxed);
87   }
88 
89   const Statistic &operator+=(unsigned V) {
90     if (V == 0)
91       return *this;
92     Value.fetch_add(V, std::memory_order_relaxed);
93     return init();
94   }
95 
96   const Statistic &operator-=(unsigned V) {
97     if (V == 0)
98       return *this;
99     Value.fetch_sub(V, std::memory_order_relaxed);
100     return init();
101   }
102 
103 #else  // Statistics are disabled in release builds.
104 
105   const Statistic &operator=(unsigned Val) {
106     return *this;
107   }
108 
109   const Statistic &operator++() {
110     return *this;
111   }
112 
113   unsigned operator++(int) {
114     return 0;
115   }
116 
117   const Statistic &operator--() {
118     return *this;
119   }
120 
121   unsigned operator--(int) {
122     return 0;
123   }
124 
125   const Statistic &operator+=(const unsigned &V) {
126     return *this;
127   }
128 
129   const Statistic &operator-=(const unsigned &V) {
130     return *this;
131   }
132 
133 #endif  // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
134 
135 protected:
init()136   Statistic &init() {
137     bool tmp = Initialized;
138     sys::MemoryFence();
139     if (!tmp) RegisterStatistic();
140     TsanHappensAfter(this);
141     return *this;
142   }
143   void RegisterStatistic();
144 };
145 
146 // STATISTIC - A macro to make definition of statistics really simple.  This
147 // automatically passes the DEBUG_TYPE of the file into the statistic.
148 #define STATISTIC(VARNAME, DESC)                                               \
149   static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, 0}
150 
151 /// \brief Enable the collection and printing of statistics.
152 void EnableStatistics();
153 
154 /// \brief Check if statistics are enabled.
155 bool AreStatisticsEnabled();
156 
157 /// \brief Return a file stream to print our output on.
158 std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
159 
160 /// \brief Print statistics to the file returned by CreateInfoOutputFile().
161 void PrintStatistics();
162 
163 /// \brief Print statistics to the given output stream.
164 void PrintStatistics(raw_ostream &OS);
165 
166 /// Print statistics in JSON format.
167 void PrintStatisticsJSON(raw_ostream &OS);
168 
169 } // end llvm namespace
170 
171 #endif // LLVM_ADT_STATISTIC_H
172