Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file defines the 'Statistic' class, which is designed to be an easy way
  11. /// to expose various metrics from passes.  These statistics are printed at the
  12. /// end of a run (from llvm_shutdown), when the -stats command line option is
  13. /// passed on the command line.
  14. ///
  15. /// This is useful for reporting information like the number of instructions
  16. /// simplified, optimized or removed by various transformations, like this:
  17. ///
  18. /// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
  19. ///
  20. /// Later, in the code: ++NumInstsKilled;
  21. ///
  22. /// NOTE: Statistics *must* be declared as global variables.
  23. ///
  24. //===----------------------------------------------------------------------===//
  25.  
  26. #ifndef LLVM_ADT_STATISTIC_H
  27. #define LLVM_ADT_STATISTIC_H
  28.  
  29. #include "llvm/Config/llvm-config.h"
  30. #include "llvm/Support/Compiler.h"
  31. #include <atomic>
  32. #include <memory>
  33. #include <vector>
  34.  
  35. // Determine whether statistics should be enabled. We must do it here rather
  36. // than in CMake because multi-config generators cannot determine this at
  37. // configure time.
  38. #if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
  39. #define LLVM_ENABLE_STATS 1
  40. #else
  41. #define LLVM_ENABLE_STATS 0
  42. #endif
  43.  
  44. namespace llvm {
  45.  
  46. class raw_ostream;
  47. class raw_fd_ostream;
  48. class StringRef;
  49.  
  50. class TrackingStatistic {
  51. public:
  52.   const char *const DebugType;
  53.   const char *const Name;
  54.   const char *const Desc;
  55.  
  56.   std::atomic<uint64_t> Value;
  57.   std::atomic<bool> Initialized;
  58.  
  59.   constexpr TrackingStatistic(const char *DebugType, const char *Name,
  60.                               const char *Desc)
  61.       : DebugType(DebugType), Name(Name), Desc(Desc), Value(0),
  62.         Initialized(false) {}
  63.  
  64.   const char *getDebugType() const { return DebugType; }
  65.   const char *getName() const { return Name; }
  66.   const char *getDesc() const { return Desc; }
  67.  
  68.   uint64_t getValue() const { return Value.load(std::memory_order_relaxed); }
  69.  
  70.   // Allow use of this class as the value itself.
  71.   operator uint64_t() const { return getValue(); }
  72.  
  73.   const TrackingStatistic &operator=(uint64_t Val) {
  74.     Value.store(Val, std::memory_order_relaxed);
  75.     return init();
  76.   }
  77.  
  78.   const TrackingStatistic &operator++() {
  79.     Value.fetch_add(1, std::memory_order_relaxed);
  80.     return init();
  81.   }
  82.  
  83.   uint64_t operator++(int) {
  84.     init();
  85.     return Value.fetch_add(1, std::memory_order_relaxed);
  86.   }
  87.  
  88.   const TrackingStatistic &operator--() {
  89.     Value.fetch_sub(1, std::memory_order_relaxed);
  90.     return init();
  91.   }
  92.  
  93.   uint64_t operator--(int) {
  94.     init();
  95.     return Value.fetch_sub(1, std::memory_order_relaxed);
  96.   }
  97.  
  98.   const TrackingStatistic &operator+=(uint64_t V) {
  99.     if (V == 0)
  100.       return *this;
  101.     Value.fetch_add(V, std::memory_order_relaxed);
  102.     return init();
  103.   }
  104.  
  105.   const TrackingStatistic &operator-=(uint64_t V) {
  106.     if (V == 0)
  107.       return *this;
  108.     Value.fetch_sub(V, std::memory_order_relaxed);
  109.     return init();
  110.   }
  111.  
  112.   void updateMax(uint64_t V) {
  113.     uint64_t PrevMax = Value.load(std::memory_order_relaxed);
  114.     // Keep trying to update max until we succeed or another thread produces
  115.     // a bigger max than us.
  116.     while (V > PrevMax && !Value.compare_exchange_weak(
  117.                               PrevMax, V, std::memory_order_relaxed)) {
  118.     }
  119.     init();
  120.   }
  121.  
  122. protected:
  123.   TrackingStatistic &init() {
  124.     if (!Initialized.load(std::memory_order_acquire))
  125.       RegisterStatistic();
  126.     return *this;
  127.   }
  128.  
  129.   void RegisterStatistic();
  130. };
  131.  
  132. class NoopStatistic {
  133. public:
  134.   NoopStatistic(const char * /*DebugType*/, const char * /*Name*/,
  135.                 const char * /*Desc*/) {}
  136.  
  137.   uint64_t getValue() const { return 0; }
  138.  
  139.   // Allow use of this class as the value itself.
  140.   operator uint64_t() const { return 0; }
  141.  
  142.   const NoopStatistic &operator=(uint64_t Val) { return *this; }
  143.  
  144.   const NoopStatistic &operator++() { return *this; }
  145.  
  146.   uint64_t operator++(int) { return 0; }
  147.  
  148.   const NoopStatistic &operator--() { return *this; }
  149.  
  150.   uint64_t operator--(int) { return 0; }
  151.  
  152.   const NoopStatistic &operator+=(const uint64_t &V) { return *this; }
  153.  
  154.   const NoopStatistic &operator-=(const uint64_t &V) { return *this; }
  155.  
  156.   void updateMax(uint64_t V) {}
  157. };
  158.  
  159. #if LLVM_ENABLE_STATS
  160. using Statistic = TrackingStatistic;
  161. #else
  162. using Statistic = NoopStatistic;
  163. #endif
  164.  
  165. // STATISTIC - A macro to make definition of statistics really simple.  This
  166. // automatically passes the DEBUG_TYPE of the file into the statistic.
  167. #define STATISTIC(VARNAME, DESC)                                               \
  168.   static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}
  169.  
  170. // ALWAYS_ENABLED_STATISTIC - A macro to define a statistic like STATISTIC but
  171. // it is enabled even if LLVM_ENABLE_STATS is off.
  172. #define ALWAYS_ENABLED_STATISTIC(VARNAME, DESC)                                \
  173.   static llvm::TrackingStatistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}
  174.  
  175. /// Enable the collection and printing of statistics.
  176. void EnableStatistics(bool DoPrintOnExit = true);
  177.  
  178. /// Check if statistics are enabled.
  179. bool AreStatisticsEnabled();
  180.  
  181. /// Return a file stream to print our output on.
  182. std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
  183.  
  184. /// Print statistics to the file returned by CreateInfoOutputFile().
  185. void PrintStatistics();
  186.  
  187. /// Print statistics to the given output stream.
  188. void PrintStatistics(raw_ostream &OS);
  189.  
  190. /// Print statistics in JSON format. This does include all global timers (\see
  191. /// Timer, TimerGroup). Note that the timers are cleared after printing and will
  192. /// not be printed in human readable form or in a second call of
  193. /// PrintStatisticsJSON().
  194. void PrintStatisticsJSON(raw_ostream &OS);
  195.  
  196. /// Get the statistics. This can be used to look up the value of
  197. /// statistics without needing to parse JSON.
  198. ///
  199. /// This function does not prevent statistics being updated by other threads
  200. /// during it's execution. It will return the value at the point that it is
  201. /// read. However, it will prevent new statistics from registering until it
  202. /// completes.
  203. std::vector<std::pair<StringRef, uint64_t>> GetStatistics();
  204.  
  205. /// Reset the statistics. This can be used to zero and de-register the
  206. /// statistics in order to measure a compilation.
  207. ///
  208. /// When this function begins to call destructors prior to returning, all
  209. /// statistics will be zero and unregistered. However, that might not remain the
  210. /// case by the time this function finishes returning. Whether update from other
  211. /// threads are lost or merely deferred until during the function return is
  212. /// timing sensitive.
  213. ///
  214. /// Callers who intend to use this to measure statistics for a single
  215. /// compilation should ensure that no compilations are in progress at the point
  216. /// this function is called and that only one compilation executes until calling
  217. /// GetStatistics().
  218. void ResetStatistics();
  219.  
  220. } // end namespace llvm
  221.  
  222. #endif // LLVM_ADT_STATISTIC_H
  223.