File indexing completed on 2026-05-10 08:44:34
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_SUPPORT_TIMER_H
0010 #define LLVM_SUPPORT_TIMER_H
0011
0012 #include "llvm/ADT/StringMap.h"
0013 #include "llvm/ADT/StringRef.h"
0014 #include "llvm/Support/DataTypes.h"
0015 #include "llvm/Support/Mutex.h"
0016 #include <cassert>
0017 #include <memory>
0018 #include <string>
0019 #include <vector>
0020
0021 namespace llvm {
0022
0023 class TimerGlobals;
0024 class TimerGroup;
0025 class raw_ostream;
0026
0027 class TimeRecord {
0028 double WallTime = 0.0;
0029 double UserTime = 0.0;
0030 double SystemTime = 0.0;
0031 ssize_t MemUsed = 0;
0032 uint64_t InstructionsExecuted = 0;
0033 public:
0034 TimeRecord() = default;
0035
0036
0037
0038
0039
0040 static TimeRecord getCurrentTime(bool Start = true);
0041
0042 double getProcessTime() const { return UserTime + SystemTime; }
0043 double getUserTime() const { return UserTime; }
0044 double getSystemTime() const { return SystemTime; }
0045 double getWallTime() const { return WallTime; }
0046 ssize_t getMemUsed() const { return MemUsed; }
0047 uint64_t getInstructionsExecuted() const { return InstructionsExecuted; }
0048
0049 bool operator<(const TimeRecord &T) const {
0050
0051 return WallTime < T.WallTime;
0052 }
0053
0054 void operator+=(const TimeRecord &RHS) {
0055 WallTime += RHS.WallTime;
0056 UserTime += RHS.UserTime;
0057 SystemTime += RHS.SystemTime;
0058 MemUsed += RHS.MemUsed;
0059 InstructionsExecuted += RHS.InstructionsExecuted;
0060 }
0061 void operator-=(const TimeRecord &RHS) {
0062 WallTime -= RHS.WallTime;
0063 UserTime -= RHS.UserTime;
0064 SystemTime -= RHS.SystemTime;
0065 MemUsed -= RHS.MemUsed;
0066 InstructionsExecuted -= RHS.InstructionsExecuted;
0067 }
0068
0069
0070
0071 void print(const TimeRecord &Total, raw_ostream &OS) const;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081 class Timer {
0082 TimeRecord Time;
0083 TimeRecord StartTime;
0084 std::string Name;
0085 std::string Description;
0086 bool Running = false;
0087 bool Triggered = false;
0088 TimerGroup *TG = nullptr;
0089
0090 Timer **Prev = nullptr;
0091 Timer *Next = nullptr;
0092 public:
0093 explicit Timer(StringRef TimerName, StringRef TimerDescription) {
0094 init(TimerName, TimerDescription);
0095 }
0096 Timer(StringRef TimerName, StringRef TimerDescription, TimerGroup &tg) {
0097 init(TimerName, TimerDescription, tg);
0098 }
0099 Timer(const Timer &RHS) {
0100 assert(!RHS.TG && "Can only copy uninitialized timers");
0101 }
0102 const Timer &operator=(const Timer &T) {
0103 assert(!TG && !T.TG && "Can only assign uninit timers");
0104 return *this;
0105 }
0106 ~Timer();
0107
0108
0109 explicit Timer() = default;
0110 void init(StringRef TimerName, StringRef TimerDescription);
0111 void init(StringRef TimerName, StringRef TimerDescription, TimerGroup &tg);
0112
0113 const std::string &getName() const { return Name; }
0114 const std::string &getDescription() const { return Description; }
0115 bool isInitialized() const { return TG != nullptr; }
0116
0117
0118 bool isRunning() const { return Running; }
0119
0120
0121 bool hasTriggered() const { return Triggered; }
0122
0123
0124
0125
0126 void startTimer();
0127
0128
0129 void stopTimer();
0130
0131
0132 void clear();
0133
0134
0135 void yieldTo(Timer &);
0136
0137
0138 TimeRecord getTotalTime() const { return Time; }
0139
0140 private:
0141 friend class TimerGroup;
0142 };
0143
0144
0145
0146
0147
0148 class TimeRegion {
0149 Timer *T;
0150 TimeRegion(const TimeRegion &) = delete;
0151
0152 public:
0153 explicit TimeRegion(Timer &t) : T(&t) {
0154 T->startTimer();
0155 }
0156 explicit TimeRegion(Timer *t) : T(t) {
0157 if (T) T->startTimer();
0158 }
0159 ~TimeRegion() {
0160 if (T) T->stopTimer();
0161 }
0162 };
0163
0164
0165
0166
0167
0168 struct NamedRegionTimer : public TimeRegion {
0169 explicit NamedRegionTimer(StringRef Name, StringRef Description,
0170 StringRef GroupName,
0171 StringRef GroupDescription, bool Enabled = true);
0172 };
0173
0174
0175
0176
0177
0178 class TimerGroup {
0179 struct PrintRecord {
0180 TimeRecord Time;
0181 std::string Name;
0182 std::string Description;
0183
0184 PrintRecord(const PrintRecord &Other) = default;
0185 PrintRecord &operator=(const PrintRecord &Other) = default;
0186 PrintRecord(const TimeRecord &Time, const std::string &Name,
0187 const std::string &Description)
0188 : Time(Time), Name(Name), Description(Description) {}
0189
0190 bool operator <(const PrintRecord &Other) const {
0191 return Time < Other.Time;
0192 }
0193 };
0194 std::string Name;
0195 std::string Description;
0196 Timer *FirstTimer = nullptr;
0197 std::vector<PrintRecord> TimersToPrint;
0198
0199 TimerGroup **Prev;
0200 TimerGroup *Next;
0201 TimerGroup(const TimerGroup &TG) = delete;
0202 void operator=(const TimerGroup &TG) = delete;
0203
0204 friend class TimerGlobals;
0205 explicit TimerGroup(StringRef Name, StringRef Description,
0206 sys::SmartMutex<true> &lock);
0207
0208 public:
0209 explicit TimerGroup(StringRef Name, StringRef Description);
0210
0211 explicit TimerGroup(StringRef Name, StringRef Description,
0212 const StringMap<TimeRecord> &Records);
0213
0214 ~TimerGroup();
0215
0216 void setName(StringRef NewName, StringRef NewDescription) {
0217 Name.assign(NewName.begin(), NewName.end());
0218 Description.assign(NewDescription.begin(), NewDescription.end());
0219 }
0220
0221
0222
0223 void print(raw_ostream &OS, bool ResetAfterPrint = false);
0224
0225
0226 void clear();
0227
0228
0229 static void printAll(raw_ostream &OS);
0230
0231
0232
0233
0234 static void clearAll();
0235
0236 const char *printJSONValues(raw_ostream &OS, const char *delim);
0237
0238
0239 static const char *printAllJSONValues(raw_ostream &OS, const char *delim);
0240
0241
0242
0243
0244 static void constructForStatistics();
0245
0246
0247
0248 static void *acquireTimerGlobals();
0249
0250 private:
0251 friend class Timer;
0252 friend void PrintStatisticsJSON(raw_ostream &OS);
0253 void addTimer(Timer &T);
0254 void removeTimer(Timer &T);
0255 void prepareToPrintList(bool reset_time = false);
0256 void PrintQueuedTimers(raw_ostream &OS);
0257 void printJSONValue(raw_ostream &OS, const PrintRecord &R,
0258 const char *suffix, double Value);
0259 };
0260
0261 }
0262
0263 #endif