Home | History | Annotate | Download | only in ADT
      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 
     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 
    151 protected:
    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