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