Statistic.h revision aa21e417f24fe9be4fd8db366766fb262c96703e
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
32namespace llvm {
33class raw_ostream;
34
35class Statistic {
36public:
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  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
109protected:
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.
126void EnableStatistics();
127
128/// \brief Check if statistics are enabled.
129bool AreStatisticsEnabled();
130
131/// \brief Print statistics to the file returned by CreateInfoOutputFile().
132void PrintStatistics();
133
134/// \brief Print statistics to the given output stream.
135void PrintStatistics(raw_ostream &OS);
136
137} // End llvm namespace
138
139#endif
140