1 | //===- llvm/unittest/ADT/StatisticTest.cpp - Statistic unit tests ---------===// |
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 | #include "llvm/ADT/Statistic.h" |
10 | #include "llvm/Support/raw_ostream.h" |
11 | #include "gtest/gtest.h" |
12 | using namespace llvm; |
13 | |
14 | using OptionalStatistic = std::optional<std::pair<StringRef, uint64_t>>; |
15 | |
16 | namespace { |
17 | #define DEBUG_TYPE "unittest" |
18 | STATISTIC(Counter, "Counts things" ); |
19 | STATISTIC(Counter2, "Counts other things" ); |
20 | ALWAYS_ENABLED_STATISTIC(AlwaysCounter, "Counts things always" ); |
21 | |
22 | #if LLVM_ENABLE_STATS |
23 | static void |
24 | (const std::vector<std::pair<StringRef, uint64_t>> &Range, |
25 | OptionalStatistic &S1, OptionalStatistic &S2) { |
26 | for (const auto &S : Range) { |
27 | if (S.first == "Counter" ) |
28 | S1 = S; |
29 | if (S.first == "Counter2" ) |
30 | S2 = S; |
31 | } |
32 | } |
33 | #endif |
34 | |
35 | TEST(StatisticTest, Count) { |
36 | EnableStatistics(); |
37 | |
38 | Counter = 0; |
39 | EXPECT_EQ(Counter, 0ull); |
40 | Counter++; |
41 | Counter++; |
42 | Counter += (std::numeric_limits<uint64_t>::max() - 3); |
43 | #if LLVM_ENABLE_STATS |
44 | EXPECT_EQ(Counter, std::numeric_limits<uint64_t>::max() - 1); |
45 | #else |
46 | EXPECT_EQ(Counter, UINT64_C(0)); |
47 | #endif |
48 | |
49 | AlwaysCounter = 0; |
50 | EXPECT_EQ(AlwaysCounter, 0ull); |
51 | AlwaysCounter++; |
52 | ++AlwaysCounter; |
53 | EXPECT_EQ(AlwaysCounter, 2ull); |
54 | } |
55 | |
56 | TEST(StatisticTest, Assign) { |
57 | EnableStatistics(); |
58 | |
59 | Counter = 2; |
60 | #if LLVM_ENABLE_STATS |
61 | EXPECT_EQ(Counter, 2u); |
62 | #else |
63 | EXPECT_EQ(Counter, 0u); |
64 | #endif |
65 | |
66 | AlwaysCounter = 2; |
67 | EXPECT_EQ(AlwaysCounter, 2u); |
68 | } |
69 | |
70 | TEST(StatisticTest, API) { |
71 | EnableStatistics(); |
72 | // Reset beforehand to make sure previous tests don't effect this one. |
73 | ResetStatistics(); |
74 | |
75 | Counter = 0; |
76 | EXPECT_EQ(Counter, 0u); |
77 | Counter++; |
78 | Counter++; |
79 | #if LLVM_ENABLE_STATS |
80 | EXPECT_EQ(Counter, 2u); |
81 | #else |
82 | EXPECT_EQ(Counter, 0u); |
83 | #endif |
84 | |
85 | #if LLVM_ENABLE_STATS |
86 | { |
87 | const auto Range1 = GetStatistics(); |
88 | EXPECT_NE(Range1.begin(), Range1.end()); |
89 | EXPECT_EQ(Range1.begin() + 1, Range1.end()); |
90 | |
91 | OptionalStatistic S1; |
92 | OptionalStatistic S2; |
93 | extractCounters(Range: Range1, S1, S2); |
94 | |
95 | EXPECT_EQ(S1.has_value(), true); |
96 | EXPECT_EQ(S2.has_value(), false); |
97 | } |
98 | |
99 | // Counter2 will be registered when it's first touched. |
100 | Counter2++; |
101 | |
102 | { |
103 | const auto Range = GetStatistics(); |
104 | EXPECT_NE(Range.begin(), Range.end()); |
105 | EXPECT_EQ(Range.begin() + 2, Range.end()); |
106 | |
107 | OptionalStatistic S1; |
108 | OptionalStatistic S2; |
109 | extractCounters(Range, S1, S2); |
110 | |
111 | EXPECT_EQ(S1.has_value(), true); |
112 | EXPECT_EQ(S2.has_value(), true); |
113 | |
114 | EXPECT_EQ(S1->first, "Counter" ); |
115 | EXPECT_EQ(S1->second, 2u); |
116 | |
117 | EXPECT_EQ(S2->first, "Counter2" ); |
118 | EXPECT_EQ(S2->second, 1u); |
119 | } |
120 | #else |
121 | Counter2++; |
122 | auto Range = GetStatistics(); |
123 | EXPECT_EQ(Range.begin(), Range.end()); |
124 | #endif |
125 | |
126 | #if LLVM_ENABLE_STATS |
127 | // Check that resetting the statistics works correctly. |
128 | // It should empty the list and zero the counters. |
129 | ResetStatistics(); |
130 | { |
131 | auto Range = GetStatistics(); |
132 | EXPECT_EQ(Range.begin(), Range.end()); |
133 | EXPECT_EQ(Counter, 0u); |
134 | EXPECT_EQ(Counter2, 0u); |
135 | OptionalStatistic S1; |
136 | OptionalStatistic S2; |
137 | extractCounters(Range, S1, S2); |
138 | EXPECT_EQ(S1.has_value(), false); |
139 | EXPECT_EQ(S2.has_value(), false); |
140 | } |
141 | |
142 | // Now check that they successfully re-register and count. |
143 | Counter++; |
144 | Counter2++; |
145 | |
146 | { |
147 | auto Range = GetStatistics(); |
148 | EXPECT_EQ(Range.begin() + 2, Range.end()); |
149 | EXPECT_EQ(Counter, 1u); |
150 | EXPECT_EQ(Counter2, 1u); |
151 | |
152 | OptionalStatistic S1; |
153 | OptionalStatistic S2; |
154 | extractCounters(Range, S1, S2); |
155 | |
156 | EXPECT_EQ(S1.has_value(), true); |
157 | EXPECT_EQ(S2.has_value(), true); |
158 | |
159 | EXPECT_EQ(S1->first, "Counter" ); |
160 | EXPECT_EQ(S1->second, 1u); |
161 | |
162 | EXPECT_EQ(S2->first, "Counter2" ); |
163 | EXPECT_EQ(S2->second, 1u); |
164 | } |
165 | #else |
166 | // No need to test the output ResetStatistics(), there's nothing to reset so |
167 | // we can't tell if it failed anyway. |
168 | ResetStatistics(); |
169 | #endif |
170 | } |
171 | |
172 | } // end anonymous namespace |
173 | |