LLVM 22.0.0git
Timer.h
Go to the documentation of this file.
1//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- 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#ifndef LLVM_SUPPORT_TIMER_H
10#define LLVM_SUPPORT_TIMER_H
11
12#include "llvm/ADT/StringMap.h"
13#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Mutex.h"
17#include <cassert>
18#include <memory>
19#include <string>
20#include <vector>
21
22namespace llvm {
23
24class TimerGlobals;
25class TimerGroup;
26class raw_ostream;
27
29 double WallTime = 0.0; ///< Wall clock time elapsed in seconds.
30 double UserTime = 0.0; ///< User time elapsed.
31 double SystemTime = 0.0; ///< System time elapsed.
32 ssize_t MemUsed = 0; ///< Memory allocated (in bytes).
33 uint64_t InstructionsExecuted = 0; ///< Number of instructions executed
34public:
35 TimeRecord() = default;
36
37 /// Get the current time and memory usage. If Start is true we get the memory
38 /// usage before the time, otherwise we get time before memory usage. This
39 /// matters if the time to get the memory usage is significant and shouldn't
40 /// be counted as part of a duration.
41 LLVM_ABI static TimeRecord getCurrentTime(bool Start = true);
42
43 double getProcessTime() const { return UserTime + SystemTime; }
44 double getUserTime() const { return UserTime; }
45 double getSystemTime() const { return SystemTime; }
46 double getWallTime() const { return WallTime; }
47 ssize_t getMemUsed() const { return MemUsed; }
48 uint64_t getInstructionsExecuted() const { return InstructionsExecuted; }
49
50 bool operator<(const TimeRecord &T) const {
51 // Sort by Wall Time elapsed, as it is the only thing really accurate
52 return WallTime < T.WallTime;
53 }
54
55 void operator+=(const TimeRecord &RHS) {
56 WallTime += RHS.WallTime;
57 UserTime += RHS.UserTime;
58 SystemTime += RHS.SystemTime;
59 MemUsed += RHS.MemUsed;
60 InstructionsExecuted += RHS.InstructionsExecuted;
61 }
62 void operator-=(const TimeRecord &RHS) {
63 WallTime -= RHS.WallTime;
64 UserTime -= RHS.UserTime;
65 SystemTime -= RHS.SystemTime;
66 MemUsed -= RHS.MemUsed;
67 InstructionsExecuted -= RHS.InstructionsExecuted;
68 }
70 TimeRecord R = *this;
71 R -= RHS;
72 return R;
73 }
74 // Feel free to add operator+ if you need it
75
76 /// Print the current time record to \p OS, with a breakdown showing
77 /// contributions to the \p Total time record.
78 LLVM_ABI void print(const TimeRecord &Total, raw_ostream &OS) const;
79};
80
81/// This class is used to track the amount of time spent between invocations of
82/// its startTimer()/stopTimer() methods. Given appropriate OS support it can
83/// also keep track of the RSS of the program at various points. By default,
84/// the Timer will print the amount of time it has captured to standard error
85/// when the last timer is destroyed, otherwise it is printed when its
86/// TimerGroup is destroyed. Timers do not print their information if they are
87/// never started.
88class Timer {
89 TimeRecord Time; ///< The total time captured.
90 TimeRecord StartTime; ///< The time startTimer() was last called.
91 std::string Name; ///< The name of this time variable.
92 std::string Description; ///< Description of this time variable.
93 bool Running = false; ///< Is the timer currently running?
94 bool Triggered = false; ///< Has the timer ever been triggered?
95 TimerGroup *TG = nullptr; ///< The TimerGroup this Timer is in.
96
97 Timer **Prev = nullptr; ///< Pointer to \p Next of previous timer in group.
98 Timer *Next = nullptr; ///< Next timer in the group.
99public:
100 explicit Timer(StringRef TimerName, StringRef TimerDescription) {
101 init(TimerName, TimerDescription);
102 }
103 Timer(StringRef TimerName, StringRef TimerDescription, TimerGroup &tg) {
104 init(TimerName, TimerDescription, tg);
105 }
106 Timer(const Timer &RHS) {
107 assert(!RHS.TG && "Can only copy uninitialized timers");
108 }
109 const Timer &operator=(const Timer &T) {
110 assert(!TG && !T.TG && "Can only assign uninit timers");
111 return *this;
112 }
114
115 /// Create an uninitialized timer, client must use 'init'.
116 explicit Timer() = default;
117 LLVM_ABI void init(StringRef TimerName, StringRef TimerDescription);
118 LLVM_ABI void init(StringRef TimerName, StringRef TimerDescription,
119 TimerGroup &tg);
120
121 const std::string &getName() const { return Name; }
122 const std::string &getDescription() const { return Description; }
123 bool isInitialized() const { return TG != nullptr; }
124
125 /// Check if the timer is currently running.
126 bool isRunning() const { return Running; }
127
128 /// Check if startTimer() has ever been called on this timer.
129 bool hasTriggered() const { return Triggered; }
130
131 /// Start the timer running. Time between calls to startTimer/stopTimer is
132 /// counted by the Timer class. Note that these calls must be correctly
133 /// paired.
134 LLVM_ABI void startTimer();
135
136 /// Stop the timer.
137 LLVM_ABI void stopTimer();
138
139 /// Clear the timer state.
140 LLVM_ABI void clear();
141
142 /// Stop the timer and start another timer.
143 LLVM_ABI void yieldTo(Timer &);
144
145 /// Return the duration for which this timer has been running.
146 TimeRecord getTotalTime() const { return Time; }
147
148private:
149 friend class TimerGroup;
150};
151
152/// The TimeRegion class is used as a helper class to call the startTimer() and
153/// stopTimer() methods of the Timer class. When the object is constructed, it
154/// starts the timer specified as its argument. When it is destroyed, it stops
155/// the relevant timer. This makes it easy to time a region of code.
156class TimeRegion {
157 Timer *T;
158 TimeRegion(const TimeRegion &) = delete;
159
160public:
161 explicit TimeRegion(Timer &t) : T(&t) {
162 T->startTimer();
163 }
164 explicit TimeRegion(Timer *t) : T(t) {
165 if (T) T->startTimer();
166 }
168 if (T) T->stopTimer();
169 }
170};
171
172/// This class is basically a combination of TimeRegion and Timer. It allows
173/// you to declare a new timer, AND specify the region to time, all in one
174/// statement. All timers with the same name are merged. This is primarily
175/// used for debugging and for hunting performance problems.
176struct NamedRegionTimer : TimeRegion {
177 LLVM_ABI explicit NamedRegionTimer(StringRef Name, StringRef Description,
178 StringRef GroupName,
179 StringRef GroupDescription,
180 bool Enabled = true);
181
182 // Create or get a TimerGroup stored in the same global map owned by
183 // NamedRegionTimer.
185 StringRef GroupDescription);
186};
187
188/// The TimerGroup class is used to group together related timers into a single
189/// report that is printed when the TimerGroup is destroyed. It is illegal to
190/// destroy a TimerGroup object before all of the Timers in it are gone. A
191/// TimerGroup can be specified for a newly created timer in its constructor.
192class TimerGroup {
193 struct PrintRecord {
194 TimeRecord Time;
195 std::string Name;
196 std::string Description;
197
198 PrintRecord(const PrintRecord &Other) = default;
199 PrintRecord &operator=(const PrintRecord &Other) = default;
200 PrintRecord(const TimeRecord &Time, const std::string &Name,
201 const std::string &Description)
202 : Time(Time), Name(Name), Description(Description) {}
203
204 bool operator <(const PrintRecord &Other) const {
205 return Time < Other.Time;
206 }
207 };
208 std::string Name;
209 std::string Description;
210 Timer *FirstTimer = nullptr; ///< First timer in the group.
211 std::vector<PrintRecord> TimersToPrint;
212 bool PrintOnExit;
213
214 TimerGroup **Prev; ///< Pointer to Next field of previous timergroup in list.
215 TimerGroup *Next; ///< Pointer to next timergroup in list.
216 TimerGroup(const TimerGroup &TG) = delete;
217 void operator=(const TimerGroup &TG) = delete;
218
219 friend class TimerGlobals;
220 explicit TimerGroup(StringRef Name, StringRef Description,
221 sys::SmartMutex<true> &lock, bool PrintOnExit);
222
223public:
224 LLVM_ABI explicit TimerGroup(StringRef Name, StringRef Description,
225 bool PrintOnExit = true);
226
227 LLVM_ABI explicit TimerGroup(StringRef Name, StringRef Description,
228 const StringMap<TimeRecord> &Records,
229 bool PrintOnExit = true);
230
232
233 void setName(StringRef NewName, StringRef NewDescription) {
234 Name.assign(NewName.begin(), NewName.end());
235 Description.assign(NewDescription.begin(), NewDescription.end());
236 }
237
238 /// Print any started timers in this group, optionally resetting timers after
239 /// printing them.
240 LLVM_ABI void print(raw_ostream &OS, bool ResetAfterPrint = false);
241
242 /// Clear all timers in this group.
243 LLVM_ABI void clear();
244
245 /// This static method prints all timers.
246 LLVM_ABI static void printAll(raw_ostream &OS);
247
248 /// Clear out all timers. This is mostly used to disable automatic
249 /// printing on shutdown, when timers have already been printed explicitly
250 /// using \c printAll or \c printJSONValues.
251 LLVM_ABI static void clearAll();
252
253 LLVM_ABI const char *printJSONValues(raw_ostream &OS, const char *delim);
254
255 /// Prints all timers as JSON key/value pairs.
256 LLVM_ABI static const char *printAllJSONValues(raw_ostream &OS,
257 const char *delim);
258
259 /// Ensure global objects required for statistics printing are initialized.
260 /// This function is used by the Statistic code to ensure correct order of
261 /// global constructors and destructors.
262 LLVM_ABI static void constructForStatistics();
263
264 /// This makes the timer globals unmanaged, and lets the user manage the
265 /// lifetime.
266 LLVM_ABI static void *acquireTimerGlobals();
267
268private:
269 friend class Timer;
271 void addTimer(Timer &T);
272 void removeTimer(Timer &T);
273 void prepareToPrintList(bool reset_time = false);
274 void PrintQueuedTimers(raw_ostream &OS);
275 void printJSONValue(raw_ostream &OS, const PrintRecord &R,
276 const char *suffix, double Value);
277};
278
279} // end namespace llvm
280
281#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
#define LLVM_ABI
Definition Compiler.h:213
#define T
static bool Enabled
Definition Statistic.cpp:46
Value * RHS
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
iterator begin() const
Definition StringRef.h:112
iterator end() const
Definition StringRef.h:114
double getUserTime() const
Definition Timer.h:44
double getProcessTime() const
Definition Timer.h:43
TimeRecord()=default
static LLVM_ABI TimeRecord getCurrentTime(bool Start=true)
Get the current time and memory usage.
Definition Timer.cpp:128
double getWallTime() const
Definition Timer.h:46
TimeRecord operator-(const TimeRecord &RHS) const
Definition Timer.h:69
ssize_t getMemUsed() const
Definition Timer.h:47
void operator-=(const TimeRecord &RHS)
Definition Timer.h:62
void operator+=(const TimeRecord &RHS)
Definition Timer.h:55
double getSystemTime() const
Definition Timer.h:45
bool operator<(const TimeRecord &T) const
Definition Timer.h:50
LLVM_ABI void print(const TimeRecord &Total, raw_ostream &OS) const
Print the current time record to OS, with a breakdown showing contributions to the Total time record.
Definition Timer.cpp:186
uint64_t getInstructionsExecuted() const
Definition Timer.h:48
TimeRegion(Timer &t)
Definition Timer.h:161
TimeRegion(Timer *t)
Definition Timer.h:164
The TimerGroup class is used to group together related timers into a single report that is printed wh...
Definition Timer.h:192
static LLVM_ABI void printAll(raw_ostream &OS)
This static method prints all timers.
Definition Timer.cpp:444
void setName(StringRef NewName, StringRef NewDescription)
Definition Timer.h:233
LLVM_ABI void print(raw_ostream &OS, bool ResetAfterPrint=false)
Print any started timers in this group, optionally resetting timers after printing them.
Definition Timer.cpp:426
friend class Timer
Definition Timer.h:269
static LLVM_ABI void clearAll()
Clear out all timers.
Definition Timer.cpp:451
LLVM_ABI void clear()
Clear all timers in this group.
Definition Timer.cpp:438
LLVM_ABI friend void PrintStatisticsJSON(raw_ostream &OS)
Print statistics in JSON format.
friend class TimerGlobals
Definition Timer.h:219
LLVM_ABI ~TimerGroup()
Definition Timer.cpp:300
static LLVM_ABI void * acquireTimerGlobals()
This makes the timer globals unmanaged, and lets the user manage the lifetime.
Definition Timer.cpp:574
static LLVM_ABI const char * printAllJSONValues(raw_ostream &OS, const char *delim)
Prints all timers as JSON key/value pairs.
Definition Timer.cpp:491
LLVM_ABI const char * printJSONValues(raw_ostream &OS, const char *delim)
Definition Timer.cpp:464
static LLVM_ABI void constructForStatistics()
Ensure global objects required for statistics printing are initialized.
Definition Timer.cpp:570
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
Definition Timer.h:88
bool hasTriggered() const
Check if startTimer() has ever been called on this timer.
Definition Timer.h:129
LLVM_ABI void yieldTo(Timer &)
Stop the timer and start another timer.
Definition Timer.cpp:174
LLVM_ABI ~Timer()
Definition Timer.cpp:106
bool isRunning() const
Check if the timer is currently running.
Definition Timer.h:126
LLVM_ABI void stopTimer()
Stop the timer.
Definition Timer.cpp:159
const Timer & operator=(const Timer &T)
Definition Timer.h:109
const std::string & getDescription() const
Definition Timer.h:122
LLVM_ABI void init(StringRef TimerName, StringRef TimerDescription)
Definition Timer.cpp:92
LLVM_ABI void clear()
Clear the timer state.
Definition Timer.cpp:169
friend class TimerGroup
Definition Timer.h:149
const std::string & getName() const
Definition Timer.h:121
Timer()=default
Create an uninitialized timer, client must use 'init'.
Timer(const Timer &RHS)
Definition Timer.h:106
bool isInitialized() const
Definition Timer.h:123
Timer(StringRef TimerName, StringRef TimerDescription)
Definition Timer.h:100
Timer(StringRef TimerName, StringRef TimerDescription, TimerGroup &tg)
Definition Timer.h:103
LLVM_ABI void startTimer()
Start the timer running.
Definition Timer.cpp:150
TimeRecord getTotalTime() const
Return the duration for which this timer has been running.
Definition Timer.h:146
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
SmartMutex - A mutex with a compile time constant parameter that indicates whether this mutex should ...
Definition Mutex.h:28
This is an optimization pass for GlobalISel generic memory operations.
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled=true)
Definition Timer.cpp:252
static LLVM_ABI TimerGroup & getNamedTimerGroup(StringRef GroupName, StringRef GroupDescription)
Definition Timer.cpp:260