Coverage Report

Created: 2019-04-21 11:35

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