X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FTimer.h;h=2cd30e2aaf32221555c5a0d5d0c8a5e5a0bd6250;hb=4389f0be7350303a366bf936e195d2e6a76d2e2a;hp=5d39fc0f12eee33f53370d0d7e928a8fe669ba35;hpb=b0d0f5b473b6110a9e72d823f2f2c4c52928a1bf;p=oota-llvm.git diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 5d39fc0f12e..2cd30e2aaf3 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -1,73 +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 +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 - unsigned long MaxRSS; // Maximum resident set size (in bytes) - unsigned long RSSTemp; // Temp for calculating maxrss - std::string Name; // The name of this time variable + 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 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: - Timer(const std::string &N); - Timer(const std::string &N, TimerGroup &tg); - Timer(const Timer &T); - ~Timer(); - - double getProcessTime() const { return UserTime+SystemTime; } - double getWallTime() const { return Elapsed; } - unsigned long getMaxRSS() const { return MaxRSS; } - std::string getName() const { return Name; } - + 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; - MaxRSS = T.MaxRSS; - RSSTemp = T.RSSTemp; - 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(); - // 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); } + // 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; } /// startTimer - Start the timer running. Time between calls to /// startTimer/stopTimer is counted by the Timer class. Note that these calls @@ -79,52 +113,77 @@ public: /// void stopTimer(); - /// print - Print the current timer to standard error, and reset the "Started" - /// flag. - void print(const Timer &Total); - 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