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