| //===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file defines three classes: Timer, TimeRegion, and TimerGroup, | |
| // documented below. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_SUPPORT_TIMER_H | |
| #define LLVM_SUPPORT_TIMER_H | |
| #include "llvm/Support/DataTypes.h" | |
| #include "llvm/ADT/StringRef.h" | |
| #include <cassert> | |
| #include <string> | |
| #include <vector> | |
| #include <utility> | |
| namespace llvm { | |
| class Timer; | |
| class TimerGroup; | |
| class raw_ostream; | |
| class TimeRecord { | |
| double WallTime; // Wall clock time elapsed in seconds | |
| double UserTime; // User time elapsed | |
| double SystemTime; // System time elapsed | |
| ssize_t MemUsed; // Memory allocated (in bytes) | |
| public: | |
| TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {} | |
| /// getCurrentTime - Get the current time and memory usage. If Start is true | |
| /// we get the memory usage before the time, otherwise we get time before | |
| /// memory usage. This matters if the time to get the memory usage is | |
| /// significant and shouldn't be counted as part of a duration. | |
| static TimeRecord getCurrentTime(bool Start = true); | |
| double getProcessTime() const { return UserTime+SystemTime; } | |
| double getUserTime() const { return UserTime; } | |
| double getSystemTime() const { return SystemTime; } | |
| double getWallTime() const { return WallTime; } | |
| ssize_t getMemUsed() const { return MemUsed; } | |
| // operator< - Allow sorting. | |
| bool operator<(const TimeRecord &T) const { | |
| // Sort by Wall Time elapsed, as it is the only thing really accurate | |
| return WallTime < T.WallTime; | |
| } | |
| void operator+=(const TimeRecord &RHS) { | |
| WallTime += RHS.WallTime; | |
| UserTime += RHS.UserTime; | |
| SystemTime += RHS.SystemTime; | |
| MemUsed += RHS.MemUsed; | |
| } | |
| void operator-=(const TimeRecord &RHS) { | |
| WallTime -= RHS.WallTime; | |
| UserTime -= RHS.UserTime; | |
| SystemTime -= RHS.SystemTime; | |
| MemUsed -= RHS.MemUsed; | |
| } | |
| /// print - Print the current timer to standard error, and reset the "Started" | |
| /// flag. | |
| void print(const TimeRecord &Total, raw_ostream &OS) const; | |
| }; | |
| /// Timer - This class is used to track the amount of time spent between | |
| /// invocations of its startTimer()/stopTimer() methods. Given appropriate OS | |
| /// support it can also keep track of the RSS of the program at various points. | |
| /// By default, the Timer will print the amount of time it has captured to | |
| /// standard error when the laster timer is destroyed, otherwise it is printed | |
| /// when its TimerGroup is destroyed. Timers do not print their information | |
| /// if they are never started. | |
| /// | |
| class Timer { | |
| TimeRecord Time; | |
| std::string Name; // The name of this time variable. | |
| bool Started; // Has this time variable ever been started? | |
| TimerGroup *TG; // The TimerGroup this Timer is in. | |
| Timer **Prev, *Next; // Doubly linked list of timers in the group. | |
| public: | |
| explicit Timer(StringRef N) : TG(0) { init(N); } | |
| Timer(StringRef N, TimerGroup &tg) : TG(0) { init(N, tg); } | |
| Timer(const Timer &RHS) : TG(0) { | |
| assert(RHS.TG == 0 && "Can only copy uninitialized timers"); | |
| } | |
| const Timer &operator=(const Timer &T) { | |
| assert(TG == 0 && T.TG == 0 && "Can only assign uninit timers"); | |
| return *this; | |
| } | |
| ~Timer(); | |
| // Create an uninitialized timer, client must use 'init'. | |
| explicit Timer() : TG(0) {} | |
| void init(StringRef N); | |
| void init(StringRef N, TimerGroup &tg); | |
| const std::string &getName() const { return Name; } | |
| bool isInitialized() const { return TG != 0; } | |
| /// startTimer - Start the timer running. Time between calls to | |
| /// startTimer/stopTimer is counted by the Timer class. Note that these calls | |
| /// must be correctly paired. | |
| /// | |
| void startTimer(); | |
| /// stopTimer - Stop the timer. | |
| /// | |
| void stopTimer(); | |
| private: | |
| friend class TimerGroup; | |
| }; | |
| /// The TimeRegion class is used as a helper class to call the startTimer() and | |
| /// stopTimer() methods of the Timer class. When the object is constructed, it | |
| /// starts the timer specified as it's argument. When it is destroyed, it stops | |
| /// the relevant timer. This makes it easy to time a region of code. | |
| /// | |
| class TimeRegion { | |
| Timer *T; | |
| TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT | |
| public: | |
| explicit TimeRegion(Timer &t) : T(&t) { | |
| T->startTimer(); | |
| } | |
| explicit TimeRegion(Timer *t) : T(t) { | |
| if (T) T->startTimer(); | |
| } | |
| ~TimeRegion() { | |
| if (T) T->stopTimer(); | |
| } | |
| }; | |
| /// NamedRegionTimer - This class is basically a combination of TimeRegion and | |
| /// Timer. It allows you to declare a new timer, AND specify the region to | |
| /// time, all in one statement. All timers with the same name are merged. This | |
| /// is primarily used for debugging and for hunting performance problems. | |
| /// | |
| struct NamedRegionTimer : public TimeRegion { | |
| explicit NamedRegionTimer(StringRef Name, | |
| bool Enabled = true); | |
| explicit NamedRegionTimer(StringRef Name, StringRef GroupName, | |
| bool Enabled = true); | |
| }; | |
| /// The TimerGroup class is used to group together related timers into a single | |
| /// report that is printed when the TimerGroup is destroyed. It is illegal to | |
| /// destroy a TimerGroup object before all of the Timers in it are gone. A | |
| /// TimerGroup can be specified for a newly created timer in its constructor. | |
| /// | |
| class TimerGroup { | |
| std::string Name; | |
| Timer *FirstTimer; // First timer in the group. | |
| std::vector<std::pair<TimeRecord, std::string> > TimersToPrint; | |
| TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's. | |
| TimerGroup(const TimerGroup &TG); // DO NOT IMPLEMENT | |
| void operator=(const TimerGroup &TG); // DO NOT IMPLEMENT | |
| public: | |
| explicit TimerGroup(StringRef name); | |
| ~TimerGroup(); | |
| void setName(StringRef name) { Name.assign(name.begin(), name.end()); } | |
| /// print - Print any started timers in this group and zero them. | |
| void print(raw_ostream &OS); | |
| /// printAll - This static method prints all timers and clears them all out. | |
| static void printAll(raw_ostream &OS); | |
| private: | |
| friend class Timer; | |
| void addTimer(Timer &T); | |
| void removeTimer(Timer &T); | |
| void PrintQueuedTimers(raw_ostream &OS); | |
| }; | |
| } // End llvm namespace | |
| #endif |