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