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 
     31 namespace llvm {
     32 class raw_ostream;
     33 
     34 class Statistic {
     35 public:
     36   const char *Name;
     37   const char *Desc;
     38   volatile llvm::sys::cas_flag Value;
     39   bool Initialized;
     40 
     41   llvm::sys::cas_flag getValue() const { return Value; }
     42   const char *getName() const { return Name; }
     43   const char *getDesc() const { return Desc; }
     44 
     45   /// construct - This should only be called for non-global statistics.
     46   void construct(const char *name, const char *desc) {
     47     Name = name; Desc = desc;
     48     Value = 0; Initialized = 0;
     49   }
     50 
     51   // Allow use of this class as the value itself.
     52   operator unsigned() const { return Value; }
     53   const Statistic &operator=(unsigned Val) {
     54     Value = Val;
     55     return init();
     56   }
     57 
     58   const Statistic &operator++() {
     59     // FIXME: This function and all those that follow carefully use an
     60     // atomic operation to update the value safely in the presence of
     61     // concurrent accesses, but not to read the return value, so the
     62     // return value is not thread safe.
     63     sys::AtomicIncrement(&Value);
     64     return init();
     65   }
     66 
     67   unsigned operator++(int) {
     68     init();
     69     unsigned OldValue = Value;
     70     sys::AtomicIncrement(&Value);
     71     return OldValue;
     72   }
     73 
     74   const Statistic &operator--() {
     75     sys::AtomicDecrement(&Value);
     76     return init();
     77   }
     78 
     79   unsigned operator--(int) {
     80     init();
     81     unsigned OldValue = Value;
     82     sys::AtomicDecrement(&Value);
     83     return OldValue;
     84   }
     85 
     86   const Statistic &operator+=(const unsigned &V) {
     87     if (!V) return *this;
     88     sys::AtomicAdd(&Value, V);
     89     return init();
     90   }
     91 
     92   const Statistic &operator-=(const unsigned &V) {
     93     if (!V) return *this;
     94     sys::AtomicAdd(&Value, -V);
     95     return init();
     96   }
     97 
     98   const Statistic &operator*=(const unsigned &V) {
     99     sys::AtomicMul(&Value, V);
    100     return init();
    101   }
    102 
    103   const Statistic &operator/=(const unsigned &V) {
    104     sys::AtomicDiv(&Value, V);
    105     return init();
    106   }
    107 
    108 protected:
    109   Statistic &init() {
    110     bool tmp = Initialized;
    111     sys::MemoryFence();
    112     if (!tmp) RegisterStatistic();
    113     return *this;
    114   }
    115   void RegisterStatistic();
    116 };
    117 
    118 // STATISTIC - A macro to make definition of statistics really simple.  This
    119 // automatically passes the DEBUG_TYPE of the file into the statistic.
    120 #define STATISTIC(VARNAME, DESC) \
    121   static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
    122 
    123 /// \brief Enable the collection and printing of statistics.
    124 void EnableStatistics();
    125 
    126 /// \brief Check if statistics are enabled.
    127 bool AreStatisticsEnabled();
    128 
    129 /// \brief Print statistics to the file returned by CreateInfoOutputFile().
    130 void PrintStatistics();
    131 
    132 /// \brief Print statistics to the given output stream.
    133 void PrintStatistics(raw_ostream &OS);
    134 
    135 } // End llvm namespace
    136 
    137 #endif
    138