xref: /llvm-project/llvm/unittests/ADT/StatisticTest.cpp (revision b1df3a2c0b6a42570042934cb79ca0e4359f863b)
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
extractCounters(const std::vector<std::pair<StringRef,uint64_t>> & Range,OptionalStatistic & S1,OptionalStatistic & S2)24 extractCounters(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 
TEST(StatisticTest,Count)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 
TEST(StatisticTest,Assign)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 
TEST(StatisticTest,API)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(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