Statistic.h revision 27da66db3e3d61e9320c8562d9504f939d884598
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/System/Atomic.h"
30
31namespace llvm {
32class raw_ostream;
33
34class Statistic {
35public:
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    sys::AtomicAdd(&Value, V);
88    return init();
89  }
90
91  const Statistic &operator-=(const unsigned &V) {
92    sys::AtomicAdd(&Value, -V);
93    return init();
94  }
95
96  const Statistic &operator*=(const unsigned &V) {
97    sys::AtomicMul(&Value, V);
98    return init();
99  }
100
101  const Statistic &operator/=(const unsigned &V) {
102    sys::AtomicDiv(&Value, V);
103    return init();
104  }
105
106protected:
107  Statistic &init() {
108    bool tmp = Initialized;
109    sys::MemoryFence();
110    if (!tmp) RegisterStatistic();
111    return *this;
112  }
113  void RegisterStatistic();
114};
115
116// STATISTIC - A macro to make definition of statistics really simple.  This
117// automatically passes the DEBUG_TYPE of the file into the statistic.
118#define STATISTIC(VARNAME, DESC) \
119  static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
120
121/// \brief Enable the collection and printing of statistics.
122void EnableStatistics();
123
124/// \brief Print statistics to the file returned by CreateInfoOutputFile().
125void PrintStatistics();
126
127/// \brief Print statistics to the given output stream.
128void PrintStatistics(raw_ostream &OS);
129
130} // End llvm namespace
131
132#endif
133