Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:09

0001 //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines the 'Statistic' class, which is designed to be an easy way
0011 /// to expose various metrics from passes.  These statistics are printed at the
0012 /// end of a run (from llvm_shutdown), when the -stats command line option is
0013 /// passed on the command line.
0014 ///
0015 /// This is useful for reporting information like the number of instructions
0016 /// simplified, optimized or removed by various transformations, like this:
0017 ///
0018 /// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
0019 ///
0020 /// Later, in the code: ++NumInstsKilled;
0021 ///
0022 /// NOTE: Statistics *must* be declared as global variables.
0023 ///
0024 //===----------------------------------------------------------------------===//
0025 
0026 #ifndef LLVM_ADT_STATISTIC_H
0027 #define LLVM_ADT_STATISTIC_H
0028 
0029 #include "llvm/Config/llvm-config.h"
0030 #include <atomic>
0031 #include <memory>
0032 #include <vector>
0033 
0034 // Determine whether statistics should be enabled. We must do it here rather
0035 // than in CMake because multi-config generators cannot determine this at
0036 // configure time.
0037 #if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
0038 #define LLVM_ENABLE_STATS 1
0039 #else
0040 #define LLVM_ENABLE_STATS 0
0041 #endif
0042 
0043 namespace llvm {
0044 
0045 class raw_ostream;
0046 class raw_fd_ostream;
0047 class StringRef;
0048 
0049 class TrackingStatistic {
0050 public:
0051   const char *const DebugType;
0052   const char *const Name;
0053   const char *const Desc;
0054 
0055   std::atomic<uint64_t> Value;
0056   std::atomic<bool> Initialized;
0057 
0058   constexpr TrackingStatistic(const char *DebugType, const char *Name,
0059                               const char *Desc)
0060       : DebugType(DebugType), Name(Name), Desc(Desc), Value(0),
0061         Initialized(false) {}
0062 
0063   const char *getDebugType() const { return DebugType; }
0064   const char *getName() const { return Name; }
0065   const char *getDesc() const { return Desc; }
0066 
0067   uint64_t getValue() const { return Value.load(std::memory_order_relaxed); }
0068 
0069   // Allow use of this class as the value itself.
0070   operator uint64_t() const { return getValue(); }
0071 
0072   const TrackingStatistic &operator=(uint64_t Val) {
0073     Value.store(Val, std::memory_order_relaxed);
0074     return init();
0075   }
0076 
0077   const TrackingStatistic &operator++() {
0078     Value.fetch_add(1, std::memory_order_relaxed);
0079     return init();
0080   }
0081 
0082   uint64_t operator++(int) {
0083     init();
0084     return Value.fetch_add(1, std::memory_order_relaxed);
0085   }
0086 
0087   const TrackingStatistic &operator--() {
0088     Value.fetch_sub(1, std::memory_order_relaxed);
0089     return init();
0090   }
0091 
0092   uint64_t operator--(int) {
0093     init();
0094     return Value.fetch_sub(1, std::memory_order_relaxed);
0095   }
0096 
0097   const TrackingStatistic &operator+=(uint64_t V) {
0098     if (V == 0)
0099       return *this;
0100     Value.fetch_add(V, std::memory_order_relaxed);
0101     return init();
0102   }
0103 
0104   const TrackingStatistic &operator-=(uint64_t V) {
0105     if (V == 0)
0106       return *this;
0107     Value.fetch_sub(V, std::memory_order_relaxed);
0108     return init();
0109   }
0110 
0111   void updateMax(uint64_t V) {
0112     uint64_t PrevMax = Value.load(std::memory_order_relaxed);
0113     // Keep trying to update max until we succeed or another thread produces
0114     // a bigger max than us.
0115     while (V > PrevMax && !Value.compare_exchange_weak(
0116                               PrevMax, V, std::memory_order_relaxed)) {
0117     }
0118     init();
0119   }
0120 
0121 protected:
0122   TrackingStatistic &init() {
0123     if (!Initialized.load(std::memory_order_acquire))
0124       RegisterStatistic();
0125     return *this;
0126   }
0127 
0128   void RegisterStatistic();
0129 };
0130 
0131 class NoopStatistic {
0132 public:
0133   NoopStatistic(const char * /*DebugType*/, const char * /*Name*/,
0134                 const char * /*Desc*/) {}
0135 
0136   uint64_t getValue() const { return 0; }
0137 
0138   // Allow use of this class as the value itself.
0139   operator uint64_t() const { return 0; }
0140 
0141   const NoopStatistic &operator=(uint64_t Val) { return *this; }
0142 
0143   const NoopStatistic &operator++() { return *this; }
0144 
0145   uint64_t operator++(int) { return 0; }
0146 
0147   const NoopStatistic &operator--() { return *this; }
0148 
0149   uint64_t operator--(int) { return 0; }
0150 
0151   const NoopStatistic &operator+=(const uint64_t &V) { return *this; }
0152 
0153   const NoopStatistic &operator-=(const uint64_t &V) { return *this; }
0154 
0155   void updateMax(uint64_t V) {}
0156 };
0157 
0158 #if LLVM_ENABLE_STATS
0159 using Statistic = TrackingStatistic;
0160 #else
0161 using Statistic = NoopStatistic;
0162 #endif
0163 
0164 // STATISTIC - A macro to make definition of statistics really simple.  This
0165 // automatically passes the DEBUG_TYPE of the file into the statistic.
0166 #define STATISTIC(VARNAME, DESC)                                               \
0167   static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}
0168 
0169 // ALWAYS_ENABLED_STATISTIC - A macro to define a statistic like STATISTIC but
0170 // it is enabled even if LLVM_ENABLE_STATS is off.
0171 #define ALWAYS_ENABLED_STATISTIC(VARNAME, DESC)                                \
0172   static llvm::TrackingStatistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}
0173 
0174 /// Enable the collection and printing of statistics.
0175 void EnableStatistics(bool DoPrintOnExit = true);
0176 
0177 /// Check if statistics are enabled.
0178 bool AreStatisticsEnabled();
0179 
0180 /// Return a stream to print our output on.
0181 std::unique_ptr<raw_ostream> CreateInfoOutputFile();
0182 
0183 /// Print statistics to the file returned by CreateInfoOutputFile().
0184 void PrintStatistics();
0185 
0186 /// Print statistics to the given output stream.
0187 void PrintStatistics(raw_ostream &OS);
0188 
0189 /// Print statistics in JSON format. This does include all global timers (\see
0190 /// Timer, TimerGroup). Note that the timers are cleared after printing and will
0191 /// not be printed in human readable form or in a second call of
0192 /// PrintStatisticsJSON().
0193 void PrintStatisticsJSON(raw_ostream &OS);
0194 
0195 /// Get the statistics. This can be used to look up the value of
0196 /// statistics without needing to parse JSON.
0197 ///
0198 /// This function does not prevent statistics being updated by other threads
0199 /// during it's execution. It will return the value at the point that it is
0200 /// read. However, it will prevent new statistics from registering until it
0201 /// completes.
0202 std::vector<std::pair<StringRef, uint64_t>> GetStatistics();
0203 
0204 /// Reset the statistics. This can be used to zero and de-register the
0205 /// statistics in order to measure a compilation.
0206 ///
0207 /// When this function begins to call destructors prior to returning, all
0208 /// statistics will be zero and unregistered. However, that might not remain the
0209 /// case by the time this function finishes returning. Whether update from other
0210 /// threads are lost or merely deferred until during the function return is
0211 /// timing sensitive.
0212 ///
0213 /// Callers who intend to use this to measure statistics for a single
0214 /// compilation should ensure that no compilations are in progress at the point
0215 /// this function is called and that only one compilation executes until calling
0216 /// GetStatistics().
0217 void ResetStatistics();
0218 
0219 } // end namespace llvm
0220 
0221 #endif // LLVM_ADT_STATISTIC_H