llvm.org GIT mirror llvm / a3170b6
Re-commit: Make STATISTIC() values available programmatically Summary: It can be useful for tools to be able to retrieve the values of variables declared via STATISTIC() directly without having to emit them and parse them back. Use cases include: * Needing to report specific statistics to a test harness * Wanting to post-process statistics. For example, to produce a percentage of functions that were fully selected by GlobalISel Make this possible by adding llvm::GetStatistics() which returns an iterator_range that can be used to inspect the statistics that have been touched during execution. When statistics are disabled (NDEBUG and not LLVM_ENABLE_STATISTICS) this method will return an empty range. This patch doesn't address the effect of multiple compilations within the same process. In such situations, the statistics will be cumulative for all compilations up to the GetStatistics() call. Reviewers: qcolombet, rtereshin, aditya_nandakumar, bogner Reviewed By: rtereshin, bogner Subscribers: llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D43901 This re-commit fixes a missing include of <vector> which it seems clang didn't mind but G++ and MSVC objected to. It seems that, clang was ok with std::vector only being forward declared at the point of use since it was fully defined eventually but G++/MSVC both rejected it at the point of use. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326738 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 2 years ago
6 changed file(s) with 155 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
880880 set(LLVM_DEFINITIONS "${result}" PARENT_SCOPE)
881881 endfunction()
882882 get_compile_definitions()
883
884 # The default for LLVM_ENABLE_STATS depends on whether NDEBUG is defined or not.
885 # LLVM_ENABLE_ASSERTIONS controls that so re-use it as the default.
886 option(LLVM_ENABLE_STATS "Enable statistics collection" ${LLVM_ENABLE_ASSERTIONS})
2525 #ifndef LLVM_ADT_STATISTIC_H
2626 #define LLVM_ADT_STATISTIC_H
2727
28 #include "llvm/Config/llvm-config.h"
2829 #include "llvm/Support/Compiler.h"
2930 #include
3031 #include
32 #include
3133
3234 namespace llvm {
3335
3436 class raw_ostream;
3537 class raw_fd_ostream;
38 class StringRef;
3639
3740 class Statistic {
3841 public:
5962 // Allow use of this class as the value itself.
6063 operator unsigned() const { return getValue(); }
6164
62 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
65 #if LLVM_ENABLE_STATS
6366 const Statistic &operator=(unsigned Val) {
6467 Value.store(Val, std::memory_order_relaxed);
6568 return init();
141144
142145 void updateMax(unsigned V) {}
143146
144 #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
147 #endif // LLVM_ENABLE_STATS
145148
146149 protected:
147150 Statistic &init() {
179182 /// PrintStatisticsJSON().
180183 void PrintStatisticsJSON(raw_ostream &OS);
181184
185 /// \brief Get the statistics. This can be used to look up the value of
186 /// statistics without needing to parse JSON.
187 ///
188 /// This function does not prevent statistics being updated by other threads
189 /// during it's execution. It will return the value at the point that it is
190 /// read. However, it will prevent new statistics from registering until it
191 /// completes.
192 const std::vector> GetStatistics();
193
182194 } // end namespace llvm
183195
184196 #endif // LLVM_ADT_STATISTIC_H
7676 /* LLVM version string */
7777 #define LLVM_VERSION_STRING "${PACKAGE_VERSION}"
7878
79 /* Whether LLVM records statistics for use with GetStatistics(),
80 * PrintStatistics() or PrintStatisticsJSON()
81 */
82 #cmakedefine01 LLVM_ENABLE_STATS
83
7984 #endif
5151 static bool PrintOnExit;
5252
5353 namespace {
54 /// StatisticInfo - This class is used in a ManagedStatic so that it is created
55 /// on demand (when the first statistic is bumped) and destroyed only when
56 /// llvm_shutdown is called. We print statistics from the destructor.
54 /// This class is used in a ManagedStatic so that it is created on demand (when
55 /// the first statistic is bumped) and destroyed only when llvm_shutdown is
56 /// called. We print statistics from the destructor.
57 /// This class is also used to look up statistic values from applications that
58 /// use LLVM.
5759 class StatisticInfo {
5860 std::vector Stats;
61
5962 friend void llvm::PrintStatistics();
6063 friend void llvm::PrintStatistics(raw_ostream &OS);
6164 friend void llvm::PrintStatisticsJSON(raw_ostream &OS);
6366 /// Sort statistics by debugtype,name,description.
6467 void sort();
6568 public:
69 using const_iterator = std::vector::const_iterator;
70
6671 StatisticInfo();
6772 ~StatisticInfo();
6873
6974 void addStatistic(const Statistic *S) {
7075 Stats.push_back(S);
7176 }
77
78 const_iterator begin() const { return Stats.begin(); }
79 const_iterator end() const { return Stats.end(); }
80 iterator_range statistics() const {
81 return {begin(), end()};
82 }
7283 };
73 }
84 } // end anonymous namespace
7485
7586 static ManagedStatic StatInfo;
7687 static ManagedStatic > StatLock;
179190 }
180191
181192 void llvm::PrintStatistics() {
182 #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
193 #if LLVM_ENABLE_STATS
183194 StatisticInfo &Stats = *StatInfo;
184195
185196 // Statistics not enabled?
204215 }
205216 #endif
206217 }
218
219 const std::vector> llvm::GetStatistics() {
220 sys::SmartScopedLock Reader(*StatLock);
221 std::vector> ReturnStats;
222
223 for (const auto &Stat : StatInfo->statistics())
224 ReturnStats.emplace_back(Stat->getName(), Stat->getValue());
225 return ReturnStats;
226 }
5555 SparseBitVectorTest.cpp
5656 SparseMultiSetTest.cpp
5757 SparseSetTest.cpp
58 StatisticTest.cpp
5859 StringExtrasTest.cpp
5960 StringMapTest.cpp
6061 StringRefTest.cpp
0 //===- llvm/unittest/ADT/StatisticTest.cpp - Statistic unit tests ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/Statistic.h"
10 #include "llvm/Support/raw_ostream.h"
11 #include "gtest/gtest.h"
12 using namespace llvm;
13
14 namespace {
15 #define DEBUG_TYPE "unittest"
16 STATISTIC(Counter, "Counts things");
17 STATISTIC(Counter2, "Counts other things");
18
19 TEST(StatisticTest, Count) {
20 EnableStatistics();
21
22 Counter = 0;
23 EXPECT_EQ(Counter, 0u);
24 Counter++;
25 Counter++;
26 #if LLVM_ENABLE_STATS
27 EXPECT_EQ(Counter, 2u);
28 #else
29 EXPECT_EQ(Counter, 0u);
30 #endif
31 }
32
33 TEST(StatisticTest, Assign) {
34 EnableStatistics();
35
36 Counter = 2;
37 #if LLVM_ENABLE_STATS
38 EXPECT_EQ(Counter, 2u);
39 #else
40 EXPECT_EQ(Counter, 0u);
41 #endif
42 }
43
44 TEST(StatisticTest, API) {
45 EnableStatistics();
46
47 Counter = 0;
48 EXPECT_EQ(Counter, 0u);
49 Counter++;
50 Counter++;
51 #if LLVM_ENABLE_STATS
52 EXPECT_EQ(Counter, 2u);
53 #else
54 EXPECT_EQ(Counter, 0u);
55 #endif
56
57 #if LLVM_ENABLE_STATS
58 const auto Range1 = GetStatistics();
59 EXPECT_NE(Range1.begin(), Range1.end());
60 EXPECT_EQ(Range1.begin() + 1, Range1.end());
61
62 Optional> S1;
63 Optional> S2;
64 for (const auto &S : Range1) {
65 if (std::string(S.first) == "Counter")
66 S1 = S;
67 if (std::string(S.first) == "Counter2")
68 S2 = S;
69 }
70
71 EXPECT_NE(S1.hasValue(), false);
72 EXPECT_EQ(S2.hasValue(), false);
73
74 // Counter2 will be registered when it's first touched.
75 Counter2++;
76
77 const auto Range2 = GetStatistics();
78 EXPECT_NE(Range2.begin(), Range2.end());
79 EXPECT_EQ(Range2.begin() + 2, Range2.end());
80
81 S1 = None;
82 S2 = None;
83 for (const auto &S : Range2) {
84 if (std::string(S.first) == "Counter")
85 S1 = S;
86 if (std::string(S.first) == "Counter2")
87 S2 = S;
88 }
89
90 EXPECT_NE(S1.hasValue(), false);
91 EXPECT_NE(S2.hasValue(), false);
92
93 EXPECT_EQ(S1->first, "Counter");
94 EXPECT_EQ(S1->second, 2u);
95
96 EXPECT_EQ(S2->first, "Counter2");
97 EXPECT_EQ(S2->second, 1u);
98 #else
99 Counter2++;
100 auto &Range = GetStatistics();
101 EXPECT_EQ(Range.begin(), Range.end());
102 #endif
103 }
104
105 } // end anonymous namespace