Timer.h revision 1f6efa3996dd1929fbc129203ce5009b620e6969
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
96c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//
10aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner// This file defines three classes: Timer, TimeRegion, and TimerGroup,
11aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner// documented below.
126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//
136c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner//===----------------------------------------------------------------------===//
146c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
15551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#ifndef LLVM_SUPPORT_TIMER_H
16551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#define LLVM_SUPPORT_TIMER_H
176c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
181f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h"
19cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner#include "llvm/ADT/StringRef.h"
20a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner#include <cassert>
21fff0f11989a9ef23ab3e308783cc90c7620000ebBenjamin Kramer#include <string>
226c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner#include <vector>
23a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner#include <utility>
24be583b914d8156b99d3da264d5adca37fee8dbc9John Criswell
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
27a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnerclass Timer;
286c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerclass TimerGroup;
29d9ea85ab01fb0f2929ed50223d3758dceea8bcbdChris Lattnerclass raw_ostream;
306c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
31a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnerclass TimeRecord {
32a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double WallTime;       // Wall clock time elapsed in seconds
33a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double UserTime;       // User time elapsed
34a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double SystemTime;     // System time elapsed
35a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  ssize_t MemUsed;       // Memory allocated (in bytes)
36a782e75d487006cafffdc256b3c623307fee4dcfChris Lattnerpublic:
37a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
38a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
39a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// getCurrentTime - Get the current time and memory usage.  If Start is true
40a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// we get the memory usage before the time, otherwise we get time before
41a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// memory usage.  This matters if the time to get the memory usage is
42a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// significant and shouldn't be counted as part of a duration.
43a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  static TimeRecord getCurrentTime(bool Start = true);
44a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
45a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double getProcessTime() const { return UserTime+SystemTime; }
46a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double getUserTime() const { return UserTime; }
47a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double getSystemTime() const { return SystemTime; }
48a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  double getWallTime() const { return WallTime; }
49a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  ssize_t getMemUsed() const { return MemUsed; }
50a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
51a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
52a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  // operator< - Allow sorting.
53a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  bool operator<(const TimeRecord &T) const {
54a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    // Sort by Wall Time elapsed, as it is the only thing really accurate
55a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    return WallTime < T.WallTime;
56a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  }
57a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
58a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  void operator+=(const TimeRecord &RHS) {
59a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    WallTime   += RHS.WallTime;
60a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    UserTime   += RHS.UserTime;
61a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    SystemTime += RHS.SystemTime;
62a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    MemUsed    += RHS.MemUsed;
63a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  }
64a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  void operator-=(const TimeRecord &RHS) {
65a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    WallTime   -= RHS.WallTime;
66a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    UserTime   -= RHS.UserTime;
67a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    SystemTime -= RHS.SystemTime;
68a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    MemUsed    -= RHS.MemUsed;
69a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  }
70a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
71a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// print - Print the current timer to standard error, and reset the "Started"
72a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  /// flag.
73a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  void print(const TimeRecord &Total, raw_ostream &OS) const;
74a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner};
75a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
76aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// Timer - This class is used to track the amount of time spent between
7775144f93eb7e4dbf22d308d21581ae255dd520c6Dan Gohman/// invocations of its startTimer()/stopTimer() methods.  Given appropriate OS
78aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// support it can also keep track of the RSS of the program at various points.
79aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// By default, the Timer will print the amount of time it has captured to
80aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// standard error when the laster timer is destroyed, otherwise it is printed
8194f9c7dc97bc586e01c101e9fcfeb93c2fb4bd87Dan Gohman/// when its TimerGroup is destroyed.  Timers do not print their information
82aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// if they are never started.
83aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner///
846c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerclass Timer {
85a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  TimeRecord Time;
860ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner  std::string Name;      // The name of this time variable.
876c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  bool Started;          // Has this time variable ever been started?
886c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  TimerGroup *TG;        // The TimerGroup this Timer is in.
89b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner
90b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner  Timer **Prev, *Next;   // Doubly linked list of timers in the group.
916c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerpublic:
92cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  explicit Timer(StringRef N) : TG(0) { init(N); }
93cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  Timer(StringRef N, TimerGroup &tg) : TG(0) { init(N, tg); }
94a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  Timer(const Timer &RHS) : TG(0) {
95a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    assert(RHS.TG == 0 && "Can only copy uninitialized timers");
96a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  }
97a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  const Timer &operator=(const Timer &T) {
98a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    assert(TG == 0 && T.TG == 0 && "Can only assign uninit timers");
99a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner    return *this;
100a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  }
1016c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  ~Timer();
1026c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
103a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  // Create an uninitialized timer, client must use 'init'.
104a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  explicit Timer() : TG(0) {}
105cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  void init(StringRef N);
106cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  void init(StringRef N, TimerGroup &tg);
107a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner
108a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  const std::string &getName() const { return Name; }
109a782e75d487006cafffdc256b3c623307fee4dcfChris Lattner  bool isInitialized() const { return TG != 0; }
1100ea86bc411748f10b913f42ef3a71b46ace7ceb2Chris Lattner
1116c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  /// startTimer - Start the timer running.  Time between calls to
1126c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  /// startTimer/stopTimer is counted by the Timer class.  Note that these calls
1136c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  /// must be correctly paired.
1146c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  ///
1156c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  void startTimer();
1166c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
1176c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  /// stopTimer - Stop the timer.
1186c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  ///
1196c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  void stopTimer();
1206c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
1216c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerprivate:
1226c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  friend class TimerGroup;
1236c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner};
1246c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
1256c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
126aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// The TimeRegion class is used as a helper class to call the startTimer() and
127aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// stopTimer() methods of the Timer class.  When the object is constructed, it
128aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// starts the timer specified as it's argument.  When it is destroyed, it stops
129aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// the relevant timer.  This makes it easy to time a region of code.
130aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner///
1316c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerclass TimeRegion {
132ccd846b73ffce9296e392e550712926845098fabChris Lattner  Timer *T;
1336c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
1346c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerpublic:
135ccd846b73ffce9296e392e550712926845098fabChris Lattner  explicit TimeRegion(Timer &t) : T(&t) {
136ccd846b73ffce9296e392e550712926845098fabChris Lattner    T->startTimer();
137ccd846b73ffce9296e392e550712926845098fabChris Lattner  }
138ccd846b73ffce9296e392e550712926845098fabChris Lattner  explicit TimeRegion(Timer *t) : T(t) {
139b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner    if (T) T->startTimer();
1406c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  }
1416c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  ~TimeRegion() {
142b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner    if (T) T->stopTimer();
1436c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  }
1446c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner};
1456c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
146aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner
147aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// NamedRegionTimer - This class is basically a combination of TimeRegion and
148aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// Timer.  It allows you to declare a new timer, AND specify the region to
149aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// time, all in one statement.  All timers with the same name are merged.  This
150aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// is primarily used for debugging and for hunting performance problems.
151aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner///
152aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattnerstruct NamedRegionTimer : public TimeRegion {
15303c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman  explicit NamedRegionTimer(StringRef Name,
15403c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman                            bool Enabled = true);
15503c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman  explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
15603c3dc7b6828d48a9f3be50896b3390a696caa64Dan Gohman                            bool Enabled = true);
157aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner};
158aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner
159aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner
160aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// The TimerGroup class is used to group together related timers into a single
161aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// report that is printed when the TimerGroup is destroyed.  It is illegal to
162aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// destroy a TimerGroup object before all of the Timers in it are gone.  A
163aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner/// TimerGroup can be specified for a newly created timer in its constructor.
164aacd3c8d86d6d4aa69ddae8814b4839a4973028aChris Lattner///
1656c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerclass TimerGroup {
1666c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  std::string Name;
167b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner  Timer *FirstTimer;   // First timer in the group.
168fff0f11989a9ef23ab3e308783cc90c7620000ebBenjamin Kramer  std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
16983fa78efb19d288d172a5db87bafcb9a34a4f035Chris Lattner
17083fa78efb19d288d172a5db87bafcb9a34a4f035Chris Lattner  TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
171ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner  TimerGroup(const TimerGroup &TG);      // DO NOT IMPLEMENT
172ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner  void operator=(const TimerGroup &TG);  // DO NOT IMPLEMENT
1736c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerpublic:
174cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  explicit TimerGroup(StringRef name);
1759f9f6d19dd67926446fb89a7b2dc0bda6353645bChris Lattner  ~TimerGroup();
176b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner
177cebf5bc2ee0c5fdfa2b604e002b60add3cc895f0Chris Lattner  void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
178ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner
179ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner  /// print - Print any started timers in this group and zero them.
180ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner  void print(raw_ostream &OS);
181b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner
18283fa78efb19d288d172a5db87bafcb9a34a4f035Chris Lattner  /// printAll - This static method prints all timers and clears them all out.
18383fa78efb19d288d172a5db87bafcb9a34a4f035Chris Lattner  static void printAll(raw_ostream &OS);
18483fa78efb19d288d172a5db87bafcb9a34a4f035Chris Lattner
1856c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattnerprivate:
1866c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner  friend class Timer;
187b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner  void addTimer(Timer &T);
188b9312690a2a79de490ab9c439b9b5d7c9319bff8Chris Lattner  void removeTimer(Timer &T);
189ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36Chris Lattner  void PrintQueuedTimers(raw_ostream &OS);
1906c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner};
1916c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner
192d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
193d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
1946c38a79d770f3f0eaa11694ad84ca729b75272c4Chris Lattner#endif
195