Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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