X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FTimer.h;h=2d9b0e24841ce1d2c878447b7f0575e39e3c7599;hb=4918b66f8428f0d5b4559da8f966e3aa54c3b1ba;hp=5cacadaf1ce2b397ec5c30ce72cef317a6693571;hpb=3889a2cb05c36f30050941679d5fd55d45e6a3ed;p=oota-llvm.git diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 5cacadaf1ce..2d9b0e24841 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -1,79 +1,107 @@ -//===-- Support/Timer.h - Interval Timing Support ---------------*- C++ -*-===// +//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===// // -// This file defines three classes: Timer, TimeRegion, and TimerGroup. +// The LLVM Compiler Infrastructure // -// The Timer class is used to track the amount of time spent between invocations -// of it's 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 it's -// TimerGroup is destroyed. Timer's do not print their information if they are -// never started. -// -// 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. -// -// 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. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_TIMER_H -#define SUPPORT_TIMER_H +#ifndef LLVM_SUPPORT_TIMER_H +#define LLVM_SUPPORT_TIMER_H +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" +#include #include +#include #include -#include -#include +namespace llvm { + +class Timer; class TimerGroup; +class raw_ostream; -class Timer { - double Elapsed; // Wall clock time elapsed in seconds +class TimeRecord { + double WallTime; // Wall clock time elapsed in seconds double UserTime; // User time elapsed double SystemTime; // System time elapsed - long MemUsed; // Memory allocated (in bytes) - long PeakMem; // Peak memory used - long PeakMemBase; // Temporary for peak calculation... - 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. + ssize_t MemUsed; // Memory allocated (in bytes) public: - Timer(const std::string &N); - Timer(const std::string &N, TimerGroup &tg); - Timer(const Timer &T); - ~Timer(); + 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; + } - double getProcessTime() const { return UserTime+SystemTime; } - double getWallTime() const { return Elapsed; } - long getMemUsed() const { return MemUsed; } - long getPeakMem() const { return PeakMem; } - std::string getName() const { return Name; } + /// 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 last 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(nullptr) { init(N); } + Timer(StringRef N, TimerGroup &tg) : TG(nullptr) { init(N, tg); } + Timer(const Timer &RHS) : TG(nullptr) { + assert(!RHS.TG && "Can only copy uninitialized timers"); + } const Timer &operator=(const Timer &T) { - Elapsed = T.Elapsed; - UserTime = T.UserTime; - SystemTime = T.SystemTime; - MemUsed = T.MemUsed; - PeakMem = T.PeakMem; - PeakMemBase = T.PeakMemBase; - Name = T.Name; - Started = T.Started; - assert(TG == T.TG && "Can only assign timers in the same TimerGroup!"); + assert(!TG && !T.TG && "Can only assign uninit timers"); return *this; } + ~Timer(); + + // Create an uninitialized timer, client must use 'init'. + explicit Timer() : TG(nullptr) {} + void init(StringRef N); + void init(StringRef N, TimerGroup &tg); + + const std::string &getName() const { return Name; } + bool isInitialized() const { return TG != nullptr; } - // operator< - Allow sorting... - bool operator<(const Timer &T) const { - // Sort by Wall Time elapsed, as it is the only thing really accurate - return Elapsed < T.Elapsed; - } - bool operator>(const Timer &T) const { return T.operator<(*this); } - /// 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. @@ -84,58 +112,76 @@ public: /// void stopTimer(); - /// addPeakMemoryMeasurement - This method should be called whenever memory - /// usage needs to be checked. It adds a peak memory measurement to the - /// currently active timers, which will be printed when the timer group prints - /// - static void addPeakMemoryMeasurement(); - - /// print - Print the current timer to standard error, and reset the "Started" - /// flag. - void print(const Timer &Total, std::ostream &OS); - private: friend class TimerGroup; - - // Copy ctor, initialize with no TG member. - Timer(bool, const Timer &T); - - /// sum - Add the time accumulated in the specified timer into this timer. - /// - void sum(const Timer &T); }; - +/// 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 its 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 + Timer *T; + TimeRegion(const TimeRegion &) = delete; + public: - TimeRegion(Timer &t) : T(t) { - T.startTimer(); + explicit TimeRegion(Timer &t) : T(&t) { + T->startTimer(); + } + explicit TimeRegion(Timer *t) : T(t) { + if (T) T->startTimer(); } ~TimeRegion() { - T.stopTimer(); + 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; - unsigned NumTimers; - std::vector TimersToPrint; + Timer *FirstTimer; // First timer in the group. + std::vector> TimersToPrint; + + TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's. + TimerGroup(const TimerGroup &TG) = delete; + void operator=(const TimerGroup &TG) = delete; + public: - TimerGroup(const std::string &name) : Name(name), NumTimers(0) {} - ~TimerGroup() { - assert(NumTimers == 0 && - "TimerGroup destroyed before all contained timers!"); - } + 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() { ++NumTimers; } - void removeTimer(); - void addTimerToPrint(const Timer &T) { - TimersToPrint.push_back(Timer(true, T)); - } + void addTimer(Timer &T); + void removeTimer(Timer &T); + void PrintQueuedTimers(raw_ostream &OS); }; +} // End llvm namespace + #endif