1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===// 2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The LLVM Compiler Infrastructure 4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source 6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details. 7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file defines the 'Statistic' class, which is designed to be an easy way 11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// to expose various metrics from passes. These statistics are printed at the 12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// end of a run (from llvm_shutdown), when the -stats command line option is 13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// passed on the command line. 14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This is useful for reporting information like the number of instructions 16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// simplified, optimized or removed by various transformations, like this: 17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// static Statistic NumInstsKilled("gcse", "Number of instructions killed"); 19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Later, in the code: ++NumInstsKilled; 21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// NOTE: Statistics *must* be declared as global variables. 23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_ADT_STATISTIC_H 27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_ADT_STATISTIC_H 28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Atomic.h" 30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Compiler.h" 31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <atomic> 32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <memory> 33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm { 35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass raw_ostream; 37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass raw_fd_ostream; 38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Statistic { 40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *DebugType; 42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *Name; 43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *Desc; 44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::atomic<unsigned> Value; 45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool Initialized; 46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getValue() const { return Value.load(std::memory_order_relaxed); } 48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *getDebugType() const { return DebugType; } 49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *getName() const { return Name; } 50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const char *getDesc() const { return Desc; } 51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// construct - This should only be called for non-global statistics. 53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void construct(const char *debugtype, const char *name, const char *desc) { 54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DebugType = debugtype; 55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Name = name; 56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Desc = desc; 57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value = 0; 58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Initialized = false; 59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Allow use of this class as the value itself. 62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot operator unsigned() const { return getValue(); } 63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator=(unsigned Val) { 66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value.store(Val, std::memory_order_relaxed); 67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return init(); 68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator++() { 71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value.fetch_add(1, std::memory_order_relaxed); 72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return init(); 73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned operator++(int) { 76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot init(); 77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Value.fetch_add(1, std::memory_order_relaxed); 78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator--() { 81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value.fetch_sub(1, std::memory_order_relaxed); 82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return init(); 83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned operator--(int) { 86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot init(); 87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Value.fetch_sub(1, std::memory_order_relaxed); 88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator+=(unsigned V) { 91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (V == 0) 92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value.fetch_add(V, std::memory_order_relaxed); 94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return init(); 95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator-=(unsigned V) { 98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (V == 0) 99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Value.fetch_sub(V, std::memory_order_relaxed); 101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return init(); 102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void updateMax(unsigned V) { 105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned PrevMax = Value.load(std::memory_order_relaxed); 106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Keep trying to update max until we succeed or another thread produces 107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // a bigger max than us. 108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot while (V > PrevMax && !Value.compare_exchange_weak( 109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PrevMax, V, std::memory_order_relaxed)) { 110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot init(); 112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#else // Statistics are disabled in release builds. 115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator=(unsigned Val) { 117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator++() { 121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned operator++(int) { 125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return 0; 126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator--() { 129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned operator--(int) { 133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return 0; 134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator+=(const unsigned &V) { 137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Statistic &operator-=(const unsigned &V) { 141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void updateMax(unsigned V) {} 145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) 147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected: 149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Statistic &init() { 150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool tmp = Initialized; 151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot sys::MemoryFence(); 152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot if (!tmp) RegisterStatistic(); 153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot TsanHappensAfter(this); 154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return *this; 155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void RegisterStatistic(); 158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// STATISTIC - A macro to make definition of statistics really simple. This 161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// automatically passes the DEBUG_TYPE of the file into the statistic. 162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define STATISTIC(VARNAME, DESC) \ 163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false} 164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Enable the collection and printing of statistics. 166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotvoid EnableStatistics(bool PrintOnExit = true); 167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Check if statistics are enabled. 169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotbool AreStatisticsEnabled(); 170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Return a file stream to print our output on. 172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotstd::unique_ptr<raw_fd_ostream> CreateInfoOutputFile(); 173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Print statistics to the file returned by CreateInfoOutputFile(). 175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotvoid PrintStatistics(); 176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Print statistics to the given output stream. 178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotvoid PrintStatistics(raw_ostream &OS); 179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Print statistics in JSON format. This does include all global timers (\see 181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Timer, TimerGroup). Note that the timers are cleared after printing and will 182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// not be printed in human readable form or in a second call of 183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// PrintStatisticsJSON(). 184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotvoid PrintStatisticsJSON(raw_ostream &OS); 185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm 187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_ADT_STATISTIC_H 189