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