LLVM API Documentation

Statistic.h
Go to the documentation of this file.
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