LLVM API Documentation
00001 //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the 'Statistic' class, which is designed to be an easy way 00011 // to expose various metrics from passes. These statistics are printed at the 00012 // end of a run (from llvm_shutdown), when the -stats command line option is 00013 // passed on the command line. 00014 // 00015 // This is useful for reporting information like the number of instructions 00016 // simplified, optimized or removed by various transformations, like this: 00017 // 00018 // static Statistic NumInstsKilled("gcse", "Number of instructions killed"); 00019 // 00020 // Later, in the code: ++NumInstsKilled; 00021 // 00022 // NOTE: Statistics *must* be declared as global variables. 00023 // 00024 //===----------------------------------------------------------------------===// 00025 00026 #ifndef LLVM_ADT_STATISTIC_H 00027 #define LLVM_ADT_STATISTIC_H 00028 00029 #include "llvm/Support/Atomic.h" 00030 #include "llvm/Support/Valgrind.h" 00031 00032 namespace llvm { 00033 class raw_ostream; 00034 00035 class Statistic { 00036 public: 00037 const char *Name; 00038 const char *Desc; 00039 volatile llvm::sys::cas_flag Value; 00040 bool Initialized; 00041 00042 llvm::sys::cas_flag getValue() const { return Value; } 00043 const char *getName() const { return Name; } 00044 const char *getDesc() const { return Desc; } 00045 00046 /// construct - This should only be called for non-global statistics. 00047 void construct(const char *name, const char *desc) { 00048 Name = name; Desc = desc; 00049 Value = 0; Initialized = false; 00050 } 00051 00052 // Allow use of this class as the value itself. 00053 operator unsigned() const { return Value; } 00054 00055 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 00056 const Statistic &operator=(unsigned Val) { 00057 Value = Val; 00058 return init(); 00059 } 00060 00061 const Statistic &operator++() { 00062 // FIXME: This function and all those that follow carefully use an 00063 // atomic operation to update the value safely in the presence of 00064 // concurrent accesses, but not to read the return value, so the 00065 // return value is not thread safe. 00066 sys::AtomicIncrement(&Value); 00067 return init(); 00068 } 00069 00070 unsigned operator++(int) { 00071 init(); 00072 unsigned OldValue = Value; 00073 sys::AtomicIncrement(&Value); 00074 return OldValue; 00075 } 00076 00077 const Statistic &operator--() { 00078 sys::AtomicDecrement(&Value); 00079 return init(); 00080 } 00081 00082 unsigned operator--(int) { 00083 init(); 00084 unsigned OldValue = Value; 00085 sys::AtomicDecrement(&Value); 00086 return OldValue; 00087 } 00088 00089 const Statistic &operator+=(const unsigned &V) { 00090 if (!V) return *this; 00091 sys::AtomicAdd(&Value, V); 00092 return init(); 00093 } 00094 00095 const Statistic &operator-=(const unsigned &V) { 00096 if (!V) return *this; 00097 sys::AtomicAdd(&Value, -V); 00098 return init(); 00099 } 00100 00101 const Statistic &operator*=(const unsigned &V) { 00102 sys::AtomicMul(&Value, V); 00103 return init(); 00104 } 00105 00106 const Statistic &operator/=(const unsigned &V) { 00107 sys::AtomicDiv(&Value, V); 00108 return init(); 00109 } 00110 00111 #else // Statistics are disabled in release builds. 00112 00113 const Statistic &operator=(unsigned Val) { 00114 return *this; 00115 } 00116 00117 const Statistic &operator++() { 00118 return *this; 00119 } 00120 00121 unsigned operator++(int) { 00122 return 0; 00123 } 00124 00125 const Statistic &operator--() { 00126 return *this; 00127 } 00128 00129 unsigned operator--(int) { 00130 return 0; 00131 } 00132 00133 const Statistic &operator+=(const unsigned &V) { 00134 return *this; 00135 } 00136 00137 const Statistic &operator-=(const unsigned &V) { 00138 return *this; 00139 } 00140 00141 const Statistic &operator*=(const unsigned &V) { 00142 return *this; 00143 } 00144 00145 const Statistic &operator/=(const unsigned &V) { 00146 return *this; 00147 } 00148 00149 #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 00150 00151 protected: 00152 Statistic &init() { 00153 bool tmp = Initialized; 00154 sys::MemoryFence(); 00155 if (!tmp) RegisterStatistic(); 00156 TsanHappensAfter(this); 00157 return *this; 00158 } 00159 void RegisterStatistic(); 00160 }; 00161 00162 // STATISTIC - A macro to make definition of statistics really simple. This 00163 // automatically passes the DEBUG_TYPE of the file into the statistic. 00164 #define STATISTIC(VARNAME, DESC) \ 00165 static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 } 00166 00167 /// \brief Enable the collection and printing of statistics. 00168 void EnableStatistics(); 00169 00170 /// \brief Check if statistics are enabled. 00171 bool AreStatisticsEnabled(); 00172 00173 /// \brief Print statistics to the file returned by CreateInfoOutputFile(). 00174 void PrintStatistics(); 00175 00176 /// \brief Print statistics to the given output stream. 00177 void PrintStatistics(raw_ostream &OS); 00178 00179 } // End llvm namespace 00180 00181 #endif