1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
79769ab22265b313171d201b5928688524a01bd87Misha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
9fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//
10fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner// This file defines the 'Statistic' class, which is designed to be an easy way
11ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// to expose various metrics from passes.  These statistics are printed at the
12ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// end of a run (from llvm_shutdown), when the -stats command line option is
13ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// passed on the command line.
14fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//
15fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner// This is useful for reporting information like the number of instructions
16fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner// simplified, optimized or removed by various transformations, like this:
17fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//
18ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
19fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//
20a0031cc08c73717341e53c9d5c6c9daa4fcdf5f7Brian Gaeke// Later, in the code: ++NumInstsKilled;
21fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//
22ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner// NOTE: Statistics *must* be declared as global variables.
23ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner//
24fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner//===----------------------------------------------------------------------===//
25fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner
26551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#ifndef LLVM_ADT_STATISTIC_H
27551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#define LLVM_ADT_STATISTIC_H
28fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner
291f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Atomic.h"
30aa21e417f24fe9be4fd8db366766fb262c96703eNick Lewycky#include "llvm/Support/Valgrind.h"
3192915e31e988c1b89a07c035029dc2f289afb789Owen Anderson
32d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
336ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregorclass raw_ostream;
34d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
350a3615246fe194f64e5d4afea5943542545819fcChris Lattnerclass Statistic {
36ecb27687587d04475097596c53349b631f7ef42dChris Lattnerpublic:
37fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner  const char *Name;
3896ef1b90c8f3a6649993bb7ab10db3510f12e80aChris Lattner  const char *Desc;
395ec56cc43895b8b78ef2480d54982e3866d9d07aOwen Anderson  volatile llvm::sys::cas_flag Value;
4092915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  bool Initialized;
41fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner
425ec56cc43895b8b78ef2480d54982e3866d9d07aOwen Anderson  llvm::sys::cas_flag getValue() const { return Value; }
43975f05852d15c98540b50de7df704d67e5a794cdChris Lattner  const char *getName() const { return Name; }
44975f05852d15c98540b50de7df704d67e5a794cdChris Lattner  const char *getDesc() const { return Desc; }
450a3615246fe194f64e5d4afea5943542545819fcChris Lattner
460a3615246fe194f64e5d4afea5943542545819fcChris Lattner  /// construct - This should only be called for non-global statistics.
470a3615246fe194f64e5d4afea5943542545819fcChris Lattner  void construct(const char *name, const char *desc) {
480a3615246fe194f64e5d4afea5943542545819fcChris Lattner    Name = name; Desc = desc;
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value = 0; Initialized = false;
500a3615246fe194f64e5d4afea5943542545819fcChris Lattner  }
510a3615246fe194f64e5d4afea5943542545819fcChris Lattner
52975f05852d15c98540b50de7df704d67e5a794cdChris Lattner  // Allow use of this class as the value itself.
53ac0b6ae358944ae8b2b5a11dc08f52c3ed89f2daChris Lattner  operator unsigned() const { return Value; }
54fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
55fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
56fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung   const Statistic &operator=(unsigned Val) {
5792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    Value = Val;
5892915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
5992915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
60b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
6192915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator++() {
6227da66db3e3d61e9320c8562d9504f939d884598Dan Gohman    // FIXME: This function and all those that follow carefully use an
6327da66db3e3d61e9320c8562d9504f939d884598Dan Gohman    // atomic operation to update the value safely in the presence of
6427da66db3e3d61e9320c8562d9504f939d884598Dan Gohman    // concurrent accesses, but not to read the return value, so the
6527da66db3e3d61e9320c8562d9504f939d884598Dan Gohman    // return value is not thread safe.
6692915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicIncrement(&Value);
6792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
6892915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
69b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
7092915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  unsigned operator++(int) {
7192915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    init();
7292915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    unsigned OldValue = Value;
7392915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicIncrement(&Value);
7492915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return OldValue;
7592915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
76b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
7792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator--() {
7892915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicDecrement(&Value);
7992915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
8092915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
81b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
8292915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  unsigned operator--(int) {
8392915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    init();
8492915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    unsigned OldValue = Value;
8592915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicDecrement(&Value);
8692915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return OldValue;
8792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
88b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
8992915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator+=(const unsigned &V) {
908cc4769108272d309038a657e42b7fcbc5bd94f3Andrew Trick    if (!V) return *this;
9192915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicAdd(&Value, V);
9292915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
9392915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
94b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
9592915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator-=(const unsigned &V) {
968cc4769108272d309038a657e42b7fcbc5bd94f3Andrew Trick    if (!V) return *this;
9792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicAdd(&Value, -V);
9892915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
9992915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
100b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
10192915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator*=(const unsigned &V) {
10292915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicMul(&Value, V);
10392915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
10492915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
105b35e4e84727ff5ba3621b39caa622baef431ca45Andrew Trick
10692915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  const Statistic &operator/=(const unsigned &V) {
10792915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::AtomicDiv(&Value, V);
10892915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    return init();
10992915e31e988c1b89a07c035029dc2f289afb789Owen Anderson  }
1103a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
111fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung#else  // Statistics are disabled in release builds.
112fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
113fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator=(unsigned Val) {
114fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
115fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
116fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
117fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator++() {
118fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
119fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
120fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
121fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  unsigned operator++(int) {
122fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return 0;
123fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
124fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
125fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator--() {
126fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
127fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
128fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
129fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  unsigned operator--(int) {
130fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return 0;
131fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
132fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
133fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator+=(const unsigned &V) {
134fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
135fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
136fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
137fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator-=(const unsigned &V) {
138fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
139fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
140fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
141fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator*=(const unsigned &V) {
142fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
143fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
144fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
145fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  const Statistic &operator/=(const unsigned &V) {
146fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung    return *this;
147fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung  }
148fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
149fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung#endif  // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
150fa785cb22d50c657eb08c762d627cd6aa96982f3Jan Wen Voung
1513d3a429acb1de79eb15575ed4d90a0a951fda576John Criswellprotected:
1520a3615246fe194f64e5d4afea5943542545819fcChris Lattner  Statistic &init() {
15392915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    bool tmp = Initialized;
15492915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    sys::MemoryFence();
15592915e31e988c1b89a07c035029dc2f289afb789Owen Anderson    if (!tmp) RegisterStatistic();
156aa21e417f24fe9be4fd8db366766fb262c96703eNick Lewycky    TsanHappensAfter(this);
157975f05852d15c98540b50de7df704d67e5a794cdChris Lattner    return *this;
158975f05852d15c98540b50de7df704d67e5a794cdChris Lattner  }
159975f05852d15c98540b50de7df704d67e5a794cdChris Lattner  void RegisterStatistic();
160fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner};
1613a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
162ecb27687587d04475097596c53349b631f7ef42dChris Lattner// STATISTIC - A macro to make definition of statistics really simple.  This
163ecb27687587d04475097596c53349b631f7ef42dChris Lattner// automatically passes the DEBUG_TYPE of the file into the statistic.
164ecb27687587d04475097596c53349b631f7ef42dChris Lattner#define STATISTIC(VARNAME, DESC) \
1658e1cddc11dd8be5855a43e31d8db20b00c54ee03Matthijs Kooijman  static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
166fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner
1676ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor/// \brief Enable the collection and printing of statistics.
1686ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregorvoid EnableStatistics();
1696ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor
1700aa00f91100fb031cd9cde2562cdc029f4fb26d5Daniel Dunbar/// \brief Check if statistics are enabled.
1710aa00f91100fb031cd9cde2562cdc029f4fb26d5Daniel Dunbarbool AreStatisticsEnabled();
1720aa00f91100fb031cd9cde2562cdc029f4fb26d5Daniel Dunbar
1736ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor/// \brief Print statistics to the file returned by CreateInfoOutputFile().
1746ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregorvoid PrintStatistics();
1756ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor
1766ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor/// \brief Print statistics to the given output stream.
1776ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregorvoid PrintStatistics(raw_ostream &OS);
1786ce57922bb8d550d91c8133d1fd27dd3eaf24c22Douglas Gregor
179d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
180d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
181fa10fdf5eb9305d8af2f4c63264400bb17e6aa3fChris Lattner#endif
182