Statistic.h revision 360784
1254721Semaste//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===// 2254721Semaste// 3254721Semaste// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4254721Semaste// See https://llvm.org/LICENSE.txt for license information. 5254721Semaste// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste// 9254721Semaste// This file defines the 'Statistic' class, which is designed to be an easy way 10254721Semaste// to expose various metrics from passes. These statistics are printed at the 11254721Semaste// end of a run (from llvm_shutdown), when the -stats command line option is 12254721Semaste// passed on the command line. 13254721Semaste// 14254721Semaste// This is useful for reporting information like the number of instructions 15254721Semaste// simplified, optimized or removed by various transformations, like this: 16254721Semaste// 17254721Semaste// static Statistic NumInstsKilled("gcse", "Number of instructions killed"); 18254721Semaste// 19254721Semaste// Later, in the code: ++NumInstsKilled; 20254721Semaste// 21254721Semaste// NOTE: Statistics *must* be declared as global variables. 22254721Semaste// 23254721Semaste//===----------------------------------------------------------------------===// 24254721Semaste 25254721Semaste#ifndef LLVM_ADT_STATISTIC_H 26254721Semaste#define LLVM_ADT_STATISTIC_H 27254721Semaste 28254721Semaste#include "llvm/Config/llvm-config.h" 29254721Semaste#include "llvm/Support/Compiler.h" 30254721Semaste#include <atomic> 31254721Semaste#include <memory> 32254721Semaste#include <vector> 33254721Semaste 34254721Semaste// Determine whether statistics should be enabled. We must do it here rather 35254721Semaste// than in CMake because multi-config generators cannot determine this at 36254721Semaste// configure time. 37254721Semaste#if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS 38254721Semaste#define LLVM_ENABLE_STATS 1 39254721Semaste#endif 40254721Semaste 41254721Semastenamespace llvm { 42254721Semaste 43254721Semasteclass raw_ostream; 44254721Semasteclass raw_fd_ostream; 45254721Semasteclass StringRef; 46254721Semaste 47254721Semasteclass StatisticBase { 48254721Semastepublic: 49254721Semaste const char *DebugType; 50254721Semaste const char *Name; 51254721Semaste const char *Desc; 52254721Semaste 53254721Semaste StatisticBase(const char *DebugType, const char *Name, const char *Desc) 54254721Semaste : DebugType(DebugType), Name(Name), Desc(Desc) {} 55254721Semaste 56254721Semaste const char *getDebugType() const { return DebugType; } 57254721Semaste const char *getName() const { return Name; } 58254721Semaste const char *getDesc() const { return Desc; } 59254721Semaste}; 60254721Semaste 61254721Semasteclass TrackingStatistic : public StatisticBase { 62254721Semastepublic: 63254721Semaste std::atomic<unsigned> Value; 64254721Semaste std::atomic<bool> Initialized; 65254721Semaste 66254721Semaste TrackingStatistic(const char *DebugType, const char *Name, const char *Desc) 67254721Semaste : StatisticBase(DebugType, Name, Desc), Value(0), Initialized(false) {} 68254721Semaste 69254721Semaste unsigned getValue() const { return Value.load(std::memory_order_relaxed); } 70254721Semaste 71254721Semaste // Allow use of this class as the value itself. 72254721Semaste operator unsigned() const { return getValue(); } 73254721Semaste 74254721Semaste const TrackingStatistic &operator=(unsigned Val) { 75254721Semaste Value.store(Val, std::memory_order_relaxed); 76254721Semaste return init(); 77254721Semaste } 78254721Semaste 79254721Semaste const TrackingStatistic &operator++() { 80254721Semaste Value.fetch_add(1, std::memory_order_relaxed); 81254721Semaste return init(); 82254721Semaste } 83254721Semaste 84254721Semaste unsigned operator++(int) { 85254721Semaste init(); 86254721Semaste return Value.fetch_add(1, std::memory_order_relaxed); 87254721Semaste } 88254721Semaste 89254721Semaste const TrackingStatistic &operator--() { 90254721Semaste Value.fetch_sub(1, std::memory_order_relaxed); 91254721Semaste return init(); 92254721Semaste } 93254721Semaste 94254721Semaste unsigned operator--(int) { 95254721Semaste init(); 96254721Semaste return Value.fetch_sub(1, std::memory_order_relaxed); 97254721Semaste } 98254721Semaste 99254721Semaste const TrackingStatistic &operator+=(unsigned V) { 100254721Semaste if (V == 0) 101254721Semaste return *this; 102254721Semaste Value.fetch_add(V, std::memory_order_relaxed); 103254721Semaste return init(); 104254721Semaste } 105254721Semaste 106254721Semaste const TrackingStatistic &operator-=(unsigned V) { 107254721Semaste if (V == 0) 108254721Semaste return *this; 109254721Semaste Value.fetch_sub(V, std::memory_order_relaxed); 110254721Semaste return init(); 111254721Semaste } 112254721Semaste 113254721Semaste void updateMax(unsigned V) { 114254721Semaste unsigned PrevMax = Value.load(std::memory_order_relaxed); 115254721Semaste // Keep trying to update max until we succeed or another thread produces 116254721Semaste // a bigger max than us. 117254721Semaste while (V > PrevMax && !Value.compare_exchange_weak( 118254721Semaste PrevMax, V, std::memory_order_relaxed)) { 119254721Semaste } 120254721Semaste init(); 121254721Semaste } 122254721Semaste 123254721Semasteprotected: 124254721Semaste TrackingStatistic &init() { 125254721Semaste if (!Initialized.load(std::memory_order_acquire)) 126254721Semaste RegisterStatistic(); 127254721Semaste return *this; 128254721Semaste } 129254721Semaste 130254721Semaste void RegisterStatistic(); 131254721Semaste}; 132254721Semaste 133254721Semasteclass NoopStatistic : public StatisticBase { 134254721Semastepublic: 135254721Semaste using StatisticBase::StatisticBase; 136254721Semaste 137254721Semaste unsigned getValue() const { return 0; } 138254721Semaste 139254721Semaste // Allow use of this class as the value itself. 140254721Semaste operator unsigned() const { return 0; } 141254721Semaste 142254721Semaste const NoopStatistic &operator=(unsigned Val) { return *this; } 143254721Semaste 144254721Semaste const NoopStatistic &operator++() { return *this; } 145254721Semaste 146254721Semaste unsigned operator++(int) { return 0; } 147254721Semaste 148254721Semaste const NoopStatistic &operator--() { return *this; } 149254721Semaste 150254721Semaste unsigned operator--(int) { return 0; } 151254721Semaste 152254721Semaste const NoopStatistic &operator+=(const unsigned &V) { return *this; } 153254721Semaste 154254721Semaste const NoopStatistic &operator-=(const unsigned &V) { return *this; } 155254721Semaste 156254721Semaste void updateMax(unsigned V) {} 157254721Semaste}; 158254721Semaste 159254721Semaste#if LLVM_ENABLE_STATS 160254721Semasteusing Statistic = TrackingStatistic; 161254721Semaste#else 162254721Semasteusing Statistic = NoopStatistic; 163254721Semaste#endif 164254721Semaste 165254721Semaste// STATISTIC - A macro to make definition of statistics really simple. This 166254721Semaste// automatically passes the DEBUG_TYPE of the file into the statistic. 167254721Semaste#define STATISTIC(VARNAME, DESC) \ 168254721Semaste static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC} 169254721Semaste 170254721Semaste// ALWAYS_ENABLED_STATISTIC - A macro to define a statistic like STATISTIC but 171254721Semaste// it is enabled even if LLVM_ENABLE_STATS is off. 172254721Semaste#define ALWAYS_ENABLED_STATISTIC(VARNAME, DESC) \ 173254721Semaste static llvm::TrackingStatistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC} 174254721Semaste 175254721Semaste/// Enable the collection and printing of statistics. 176254721Semastevoid EnableStatistics(bool DoPrintOnExit = true); 177254721Semaste 178254721Semaste/// Check if statistics are enabled. 179254721Semastebool AreStatisticsEnabled(); 180254721Semaste 181254721Semaste/// Return a file stream to print our output on. 182254721Semastestd::unique_ptr<raw_fd_ostream> CreateInfoOutputFile(); 183254721Semaste 184254721Semaste/// Print statistics to the file returned by CreateInfoOutputFile(). 185254721Semastevoid PrintStatistics(); 186254721Semaste 187254721Semaste/// Print statistics to the given output stream. 188254721Semastevoid PrintStatistics(raw_ostream &OS); 189254721Semaste 190254721Semaste/// Print statistics in JSON format. This does include all global timers (\see 191254721Semaste/// Timer, TimerGroup). Note that the timers are cleared after printing and will 192254721Semaste/// not be printed in human readable form or in a second call of 193254721Semaste/// PrintStatisticsJSON(). 194254721Semastevoid PrintStatisticsJSON(raw_ostream &OS); 195254721Semaste 196254721Semaste/// Get the statistics. This can be used to look up the value of 197254721Semaste/// statistics without needing to parse JSON. 198254721Semaste/// 199254721Semaste/// This function does not prevent statistics being updated by other threads 200254721Semaste/// during it's execution. It will return the value at the point that it is 201254721Semaste/// read. However, it will prevent new statistics from registering until it 202254721Semaste/// completes. 203254721Semasteconst std::vector<std::pair<StringRef, unsigned>> GetStatistics(); 204254721Semaste 205254721Semaste/// Reset the statistics. This can be used to zero and de-register the 206254721Semaste/// statistics in order to measure a compilation. 207254721Semaste/// 208254721Semaste/// When this function begins to call destructors prior to returning, all 209254721Semaste/// statistics will be zero and unregistered. However, that might not remain the 210254721Semaste/// case by the time this function finishes returning. Whether update from other 211254721Semaste/// threads are lost or merely deferred until during the function return is 212254721Semaste/// timing sensitive. 213254721Semaste/// 214254721Semaste/// Callers who intend to use this to measure statistics for a single 215254721Semaste/// compilation should ensure that no compilations are in progress at the point 216254721Semaste/// this function is called and that only one compilation executes until calling 217254721Semaste/// GetStatistics(). 218254721Semastevoid ResetStatistics(); 219254721Semaste 220254721Semaste} // end namespace llvm 221254721Semaste 222254721Semaste#endif // LLVM_ADT_STATISTIC_H 223254721Semaste