Timer.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
  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. #ifndef LLVM_SUPPORT_TIMER_H
  10. #define LLVM_SUPPORT_TIMER_H
  11. #include "llvm/ADT/StringRef.h"
  12. #include "llvm/Support/DataTypes.h"
  13. #include <cassert>
  14. #include <string>
  15. #include <utility>
  16. #include <vector>
  17. namespace llvm {
  18. class Timer;
  19. class TimerGroup;
  20. class raw_ostream;
  21. class TimeRecord {
  22. double WallTime; // Wall clock time elapsed in seconds
  23. double UserTime; // User time elapsed
  24. double SystemTime; // System time elapsed
  25. ssize_t MemUsed; // Memory allocated (in bytes)
  26. public:
  27. TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
  28. /// getCurrentTime - Get the current time and memory usage. If Start is true
  29. /// we get the memory usage before the time, otherwise we get time before
  30. /// memory usage. This matters if the time to get the memory usage is
  31. /// significant and shouldn't be counted as part of a duration.
  32. static TimeRecord getCurrentTime(bool Start = true);
  33. double getProcessTime() const { return UserTime+SystemTime; }
  34. double getUserTime() const { return UserTime; }
  35. double getSystemTime() const { return SystemTime; }
  36. double getWallTime() const { return WallTime; }
  37. ssize_t getMemUsed() const { return MemUsed; }
  38. // operator< - Allow sorting.
  39. bool operator<(const TimeRecord &T) const {
  40. // Sort by Wall Time elapsed, as it is the only thing really accurate
  41. return WallTime < T.WallTime;
  42. }
  43. void operator+=(const TimeRecord &RHS) {
  44. WallTime += RHS.WallTime;
  45. UserTime += RHS.UserTime;
  46. SystemTime += RHS.SystemTime;
  47. MemUsed += RHS.MemUsed;
  48. }
  49. void operator-=(const TimeRecord &RHS) {
  50. WallTime -= RHS.WallTime;
  51. UserTime -= RHS.UserTime;
  52. SystemTime -= RHS.SystemTime;
  53. MemUsed -= RHS.MemUsed;
  54. }
  55. /// print - Print the current timer to standard error, and reset the "Started"
  56. /// flag.
  57. void print(const TimeRecord &Total, raw_ostream &OS) const;
  58. };
  59. /// Timer - This class is used to track the amount of time spent between
  60. /// invocations of its startTimer()/stopTimer() methods. Given appropriate OS
  61. /// support it can also keep track of the RSS of the program at various points.
  62. /// By default, the Timer will print the amount of time it has captured to
  63. /// standard error when the last timer is destroyed, otherwise it is printed
  64. /// when its TimerGroup is destroyed. Timers do not print their information
  65. /// if they are never started.
  66. ///
  67. class Timer {
  68. TimeRecord Time;
  69. std::string Name; // The name of this time variable.
  70. bool Started; // Has this time variable ever been started?
  71. TimerGroup *TG; // The TimerGroup this Timer is in.
  72. Timer **Prev, *Next; // Doubly linked list of timers in the group.
  73. public:
  74. explicit Timer(StringRef N) : TG(nullptr) { init(N); }
  75. Timer(StringRef N, TimerGroup &tg) : TG(nullptr) { init(N, tg); }
  76. Timer(const Timer &RHS) : TG(nullptr) {
  77. assert(!RHS.TG && "Can only copy uninitialized timers");
  78. }
  79. const Timer &operator=(const Timer &T) {
  80. assert(!TG && !T.TG && "Can only assign uninit timers");
  81. return *this;
  82. }
  83. ~Timer();
  84. // Create an uninitialized timer, client must use 'init'.
  85. explicit Timer() : TG(nullptr) {}
  86. void init(StringRef N);
  87. void init(StringRef N, TimerGroup &tg);
  88. const std::string &getName() const { return Name; }
  89. bool isInitialized() const { return TG != nullptr; }
  90. /// startTimer - Start the timer running. Time between calls to
  91. /// startTimer/stopTimer is counted by the Timer class. Note that these calls
  92. /// must be correctly paired.
  93. ///
  94. void startTimer();
  95. /// stopTimer - Stop the timer.
  96. ///
  97. void stopTimer();
  98. private:
  99. friend class TimerGroup;
  100. };
  101. /// The TimeRegion class is used as a helper class to call the startTimer() and
  102. /// stopTimer() methods of the Timer class. When the object is constructed, it
  103. /// starts the timer specified as its argument. When it is destroyed, it stops
  104. /// the relevant timer. This makes it easy to time a region of code.
  105. ///
  106. class TimeRegion {
  107. Timer *T;
  108. TimeRegion(const TimeRegion &) = delete;
  109. public:
  110. explicit TimeRegion(Timer &t) : T(&t) {
  111. T->startTimer();
  112. }
  113. explicit TimeRegion(Timer *t) : T(t) {
  114. if (T) T->startTimer();
  115. }
  116. ~TimeRegion() {
  117. if (T) T->stopTimer();
  118. }
  119. };
  120. /// NamedRegionTimer - This class is basically a combination of TimeRegion and
  121. /// Timer. It allows you to declare a new timer, AND specify the region to
  122. /// time, all in one statement. All timers with the same name are merged. This
  123. /// is primarily used for debugging and for hunting performance problems.
  124. ///
  125. struct NamedRegionTimer : public TimeRegion {
  126. explicit NamedRegionTimer(StringRef Name,
  127. bool Enabled = true);
  128. explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
  129. bool Enabled = true);
  130. };
  131. /// The TimerGroup class is used to group together related timers into a single
  132. /// report that is printed when the TimerGroup is destroyed. It is illegal to
  133. /// destroy a TimerGroup object before all of the Timers in it are gone. A
  134. /// TimerGroup can be specified for a newly created timer in its constructor.
  135. ///
  136. class TimerGroup {
  137. std::string Name;
  138. Timer *FirstTimer; // First timer in the group.
  139. std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
  140. TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
  141. TimerGroup(const TimerGroup &TG) = delete;
  142. void operator=(const TimerGroup &TG) = delete;
  143. public:
  144. explicit TimerGroup(StringRef name);
  145. ~TimerGroup();
  146. void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
  147. /// print - Print any started timers in this group and zero them.
  148. void print(raw_ostream &OS);
  149. /// printAll - This static method prints all timers and clears them all out.
  150. static void printAll(raw_ostream &OS);
  151. private:
  152. friend class Timer;
  153. void addTimer(Timer &T);
  154. void removeTimer(Timer &T);
  155. void PrintQueuedTimers(raw_ostream &OS);
  156. };
  157. } // End llvm namespace
  158. #endif