/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/Statistic.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- Statistic.cpp - Easy way to expose stats information --------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file implements the 'Statistic' class, which is designed to be an easy |
11 | | // way to expose various success metrics from passes. These statistics are |
12 | | // printed at the end of a run, when the -stats command line option is enabled |
13 | | // 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 NumInstEliminated("GCSE", "Number of instructions killed"); |
19 | | // |
20 | | // Later, in the code: ++NumInstEliminated; |
21 | | // |
22 | | //===----------------------------------------------------------------------===// |
23 | | |
24 | | #include "llvm/ADT/Statistic.h" |
25 | | #include "llvm/ADT/StringExtras.h" |
26 | | #include "llvm/Support/CommandLine.h" |
27 | | #include "llvm/Support/Compiler.h" |
28 | | #include "llvm/Support/Debug.h" |
29 | | #include "llvm/Support/Format.h" |
30 | | #include "llvm/Support/ManagedStatic.h" |
31 | | #include "llvm/Support/Mutex.h" |
32 | | #include "llvm/Support/Timer.h" |
33 | | #include "llvm/Support/YAMLTraits.h" |
34 | | #include "llvm/Support/raw_ostream.h" |
35 | | #include <algorithm> |
36 | | #include <cstring> |
37 | | using namespace llvm; |
38 | | |
39 | | /// -stats - Command line option to cause transformations to emit stats about |
40 | | /// what they did. |
41 | | /// |
42 | | static cl::opt<bool> Stats("stats", |
43 | | cl::desc("Enable statistics output from program (available with Asserts)")); |
44 | | |
45 | | |
46 | | static cl::opt<bool> StatsAsJSON("stats-json", |
47 | | cl::desc("Display statistics as json data")); |
48 | | |
49 | | static bool Enabled; |
50 | | static bool PrintOnExit; |
51 | | |
52 | | namespace { |
53 | | /// StatisticInfo - This class is used in a ManagedStatic so that it is created |
54 | | /// on demand (when the first statistic is bumped) and destroyed only when |
55 | | /// llvm_shutdown is called. We print statistics from the destructor. |
56 | | class StatisticInfo { |
57 | | std::vector<const Statistic*> Stats; |
58 | | friend void llvm::PrintStatistics(); |
59 | | friend void llvm::PrintStatistics(raw_ostream &OS); |
60 | | friend void llvm::PrintStatisticsJSON(raw_ostream &OS); |
61 | | |
62 | | /// Sort statistics by debugtype,name,description. |
63 | | void sort(); |
64 | | public: |
65 | | StatisticInfo(); |
66 | | ~StatisticInfo(); |
67 | | |
68 | 0 | void addStatistic(const Statistic *S) { |
69 | 0 | Stats.push_back(S); |
70 | 0 | } |
71 | | }; |
72 | | } |
73 | | |
74 | | static ManagedStatic<StatisticInfo> StatInfo; |
75 | | static ManagedStatic<sys::SmartMutex<true> > StatLock; |
76 | | |
77 | | /// RegisterStatistic - The first time a statistic is bumped, this method is |
78 | | /// called. |
79 | 0 | void Statistic::RegisterStatistic() { |
80 | 0 | // If stats are enabled, inform StatInfo that this statistic should be |
81 | 0 | // printed. |
82 | 0 | sys::SmartScopedLock<true> Writer(*StatLock); |
83 | 0 | if (!Initialized0 ) { |
84 | 0 | if (Stats || 0 Enabled0 ) |
85 | 0 | StatInfo->addStatistic(this); |
86 | 0 |
|
87 | 0 | TsanHappensBefore(this); |
88 | 0 | sys::MemoryFence(); |
89 | 0 | // Remember we have been registered. |
90 | 0 | TsanIgnoreWritesBegin(); |
91 | 0 | Initialized = true; |
92 | 0 | TsanIgnoreWritesEnd(); |
93 | 0 | } |
94 | 0 | } |
95 | | |
96 | 6 | StatisticInfo::StatisticInfo() { |
97 | 6 | // Ensure timergroup lists are created first so they are destructed after us. |
98 | 6 | TimerGroup::ConstructTimerLists(); |
99 | 6 | } |
100 | | |
101 | | // Print information when destroyed, iff command line option is specified. |
102 | 6 | StatisticInfo::~StatisticInfo() { |
103 | 6 | if (::Stats || 6 PrintOnExit6 ) |
104 | 0 | llvm::PrintStatistics(); |
105 | 6 | } |
106 | | |
107 | 7 | void llvm::EnableStatistics(bool PrintOnExit) { |
108 | 7 | Enabled = true; |
109 | 7 | ::PrintOnExit = PrintOnExit; |
110 | 7 | } |
111 | | |
112 | 61 | bool llvm::AreStatisticsEnabled() { |
113 | 61 | return Enabled || Stats; |
114 | 61 | } |
115 | | |
116 | 6 | void StatisticInfo::sort() { |
117 | 6 | std::stable_sort(Stats.begin(), Stats.end(), |
118 | 0 | [](const Statistic *LHS, const Statistic *RHS) { |
119 | 0 | if (int Cmp = std::strcmp(LHS->getDebugType(), RHS->getDebugType())) |
120 | 0 | return Cmp < 0; |
121 | 0 |
|
122 | 0 | if (int 0 Cmp0 = std::strcmp(LHS->getName(), RHS->getName())) |
123 | 0 | return Cmp < 0; |
124 | 0 |
|
125 | 0 | return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0; |
126 | 0 | }); |
127 | 6 | } |
128 | | |
129 | 5 | void llvm::PrintStatistics(raw_ostream &OS) { |
130 | 5 | StatisticInfo &Stats = *StatInfo; |
131 | 5 | |
132 | 5 | // Figure out how long the biggest Value and Name fields are. |
133 | 5 | unsigned MaxDebugTypeLen = 0, MaxValLen = 0; |
134 | 5 | for (size_t i = 0, e = Stats.Stats.size(); i != e5 ; ++i0 ) { |
135 | 0 | MaxValLen = std::max(MaxValLen, |
136 | 0 | (unsigned)utostr(Stats.Stats[i]->getValue()).size()); |
137 | 0 | MaxDebugTypeLen = std::max(MaxDebugTypeLen, |
138 | 0 | (unsigned)std::strlen(Stats.Stats[i]->getDebugType())); |
139 | 0 | } |
140 | 5 | |
141 | 5 | Stats.sort(); |
142 | 5 | |
143 | 5 | // Print out the statistics header... |
144 | 5 | OS << "===" << std::string(73, '-') << "===\n" |
145 | 5 | << " ... Statistics Collected ...\n" |
146 | 5 | << "===" << std::string(73, '-') << "===\n\n"; |
147 | 5 | |
148 | 5 | // Print all of the statistics. |
149 | 5 | for (size_t i = 0, e = Stats.Stats.size(); i != e5 ; ++i0 ) |
150 | 0 | OS << format("%*u %-*s - %s\n", |
151 | 0 | MaxValLen, Stats.Stats[i]->getValue(), |
152 | 0 | MaxDebugTypeLen, Stats.Stats[i]->getDebugType(), |
153 | 0 | Stats.Stats[i]->getDesc()); |
154 | 5 | |
155 | 5 | OS << '\n'; // Flush the output stream. |
156 | 5 | OS.flush(); |
157 | 5 | } |
158 | | |
159 | 1 | void llvm::PrintStatisticsJSON(raw_ostream &OS) { |
160 | 1 | StatisticInfo &Stats = *StatInfo; |
161 | 1 | |
162 | 1 | Stats.sort(); |
163 | 1 | |
164 | 1 | // Print all of the statistics. |
165 | 1 | OS << "{\n"; |
166 | 1 | const char *delim = ""; |
167 | 0 | for (const Statistic *Stat : Stats.Stats) { |
168 | 0 | OS << delim; |
169 | 0 | assert(!yaml::needsQuotes(Stat->getDebugType()) && |
170 | 0 | "Statistic group/type name is simple."); |
171 | 0 | assert(!yaml::needsQuotes(Stat->getName()) && "Statistic name is simple"); |
172 | 0 | OS << "\t\"" << Stat->getDebugType() << '.' << Stat->getName() << "\": " |
173 | 0 | << Stat->getValue(); |
174 | 0 | delim = ",\n"; |
175 | 0 | } |
176 | 1 | // Print timers. |
177 | 1 | TimerGroup::printAllJSONValues(OS, delim); |
178 | 1 | |
179 | 1 | OS << "\n}\n"; |
180 | 1 | OS.flush(); |
181 | 1 | } |
182 | | |
183 | 0 | void llvm::PrintStatistics() { |
184 | | #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) |
185 | | StatisticInfo &Stats = *StatInfo; |
186 | | |
187 | | // Statistics not enabled? |
188 | | if (Stats.Stats.empty()) return; |
189 | | |
190 | | // Get the stream to write to. |
191 | | std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile(); |
192 | | if (StatsAsJSON) |
193 | | PrintStatisticsJSON(*OutStream); |
194 | | else |
195 | | PrintStatistics(*OutStream); |
196 | | |
197 | | #else |
198 | | // Check if the -stats option is set instead of checking |
199 | 0 | // !Stats.Stats.empty(). In release builds, Statistics operators |
200 | 0 | // do nothing, so stats are never Registered. |
201 | 0 | if (Stats0 ) { |
202 | 0 | // Get the stream to write to. |
203 | 0 | std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile(); |
204 | 0 | (*OutStream) << "Statistics are disabled. " |
205 | 0 | << "Build with asserts or with -DLLVM_ENABLE_STATS\n"; |
206 | 0 | } |
207 | 0 | #endif |
208 | 0 | } |