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 32namespace llvm { 33class raw_ostream; 34 35class Statistic { 36public: 37 const char *Name; 38 const char *Desc; 39 volatile llvm::sys::cas_flag Value; 40 bool Initialized; 41 42 llvm::sys::cas_flag getValue() const { return Value; } 43 const char *getName() const { return Name; } 44 const char *getDesc() const { return Desc; } 45 46 /// construct - This should only be called for non-global statistics. 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 151protected: 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. 168void EnableStatistics(); 169 170/// \brief Check if statistics are enabled. 171bool AreStatisticsEnabled(); 172 173/// \brief Print statistics to the file returned by CreateInfoOutputFile(). 174void PrintStatistics(); 175 176/// \brief Print statistics to the given output stream. 177void PrintStatistics(raw_ostream &OS); 178 179} // End llvm namespace 180 181#endif 182