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