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/Valgrind.h" 31 32 namespace llvm { 33 class raw_ostream; 34 35 class Statistic { 36 public: 37 const char *Name; 38 const char *Desc; 39 volatile llvm::sys::cas_flag Value; 40 bool Initialized; 41 getValue()42 llvm::sys::cas_flag getValue() const { return Value; } getName()43 const char *getName() const { return Name; } getDesc()44 const char *getDesc() const { return Desc; } 45 46 /// construct - This should only be called for non-global statistics. construct(const char * name,const char * desc)47 void construct(const char *name, const char *desc) { 48 Name = name; Desc = desc; 49 Value = 0; Initialized = 0; 50 } 51 52 // Allow use of this class as the value itself. 53 operator unsigned() const { return Value; } 54 55 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 56 const Statistic &operator=(unsigned Val) { 57 Value = Val; 58 return init(); 59 } 60 61 const Statistic &operator++() { 62 // FIXME: This function and all those that follow carefully use an 63 // atomic operation to update the value safely in the presence of 64 // concurrent accesses, but not to read the return value, so the 65 // return value is not thread safe. 66 sys::AtomicIncrement(&Value); 67 return init(); 68 } 69 70 unsigned operator++(int) { 71 init(); 72 unsigned OldValue = Value; 73 sys::AtomicIncrement(&Value); 74 return OldValue; 75 } 76 77 const Statistic &operator--() { 78 sys::AtomicDecrement(&Value); 79 return init(); 80 } 81 82 unsigned operator--(int) { 83 init(); 84 unsigned OldValue = Value; 85 sys::AtomicDecrement(&Value); 86 return OldValue; 87 } 88 89 const Statistic &operator+=(const unsigned &V) { 90 if (!V) return *this; 91 sys::AtomicAdd(&Value, V); 92 return init(); 93 } 94 95 const Statistic &operator-=(const unsigned &V) { 96 if (!V) return *this; 97 sys::AtomicAdd(&Value, -V); 98 return init(); 99 } 100 101 const Statistic &operator*=(const unsigned &V) { 102 sys::AtomicMul(&Value, V); 103 return init(); 104 } 105 106 const Statistic &operator/=(const unsigned &V) { 107 sys::AtomicDiv(&Value, V); 108 return init(); 109 } 110 111 #else // Statistics are disabled in release builds. 112 113 const Statistic &operator=(unsigned Val) { 114 return *this; 115 } 116 117 const Statistic &operator++() { 118 return *this; 119 } 120 121 unsigned operator++(int) { 122 return 0; 123 } 124 125 const Statistic &operator--() { 126 return *this; 127 } 128 129 unsigned operator--(int) { 130 return 0; 131 } 132 133 const Statistic &operator+=(const unsigned &V) { 134 return *this; 135 } 136 137 const Statistic &operator-=(const unsigned &V) { 138 return *this; 139 } 140 141 const Statistic &operator*=(const unsigned &V) { 142 return *this; 143 } 144 145 const Statistic &operator/=(const unsigned &V) { 146 return *this; 147 } 148 149 #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 150 151 protected: init()152 Statistic &init() { 153 bool tmp = Initialized; 154 sys::MemoryFence(); 155 if (!tmp) RegisterStatistic(); 156 TsanHappensAfter(this); 157 return *this; 158 } 159 void RegisterStatistic(); 160 }; 161 162 // STATISTIC - A macro to make definition of statistics really simple. This 163 // automatically passes the DEBUG_TYPE of the file into the statistic. 164 #define STATISTIC(VARNAME, DESC) \ 165 static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 } 166 167 /// \brief Enable the collection and printing of statistics. 168 void EnableStatistics(); 169 170 /// \brief Check if statistics are enabled. 171 bool AreStatisticsEnabled(); 172 173 /// \brief Print statistics to the file returned by CreateInfoOutputFile(). 174 void PrintStatistics(); 175 176 /// \brief Print statistics to the given output stream. 177 void PrintStatistics(raw_ostream &OS); 178 179 } // End llvm namespace 180 181 #endif 182