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