LLVM API Documentation

Timer.h
Go to the documentation of this file.
00001 //===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_SUPPORT_TIMER_H
00011 #define LLVM_SUPPORT_TIMER_H
00012 
00013 #include "llvm/ADT/StringRef.h"
00014 #include "llvm/Support/Compiler.h"
00015 #include "llvm/Support/DataTypes.h"
00016 #include <cassert>
00017 #include <string>
00018 #include <utility>
00019 #include <vector>
00020 
00021 namespace llvm {
00022 
00023 class Timer;
00024 class TimerGroup;
00025 class raw_ostream;
00026 
00027 class TimeRecord {
00028   double WallTime;       // Wall clock time elapsed in seconds
00029   double UserTime;       // User time elapsed
00030   double SystemTime;     // System time elapsed
00031   ssize_t MemUsed;       // Memory allocated (in bytes)
00032 public:
00033   TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
00034   
00035   /// getCurrentTime - Get the current time and memory usage.  If Start is true
00036   /// we get the memory usage before the time, otherwise we get time before
00037   /// memory usage.  This matters if the time to get the memory usage is
00038   /// significant and shouldn't be counted as part of a duration.
00039   static TimeRecord getCurrentTime(bool Start = true);
00040   
00041   double getProcessTime() const { return UserTime+SystemTime; }
00042   double getUserTime() const { return UserTime; }
00043   double getSystemTime() const { return SystemTime; }
00044   double getWallTime() const { return WallTime; }
00045   ssize_t getMemUsed() const { return MemUsed; }
00046   
00047   
00048   // operator< - Allow sorting.
00049   bool operator<(const TimeRecord &T) const {
00050     // Sort by Wall Time elapsed, as it is the only thing really accurate
00051     return WallTime < T.WallTime;
00052   }
00053   
00054   void operator+=(const TimeRecord &RHS) {
00055     WallTime   += RHS.WallTime;
00056     UserTime   += RHS.UserTime;
00057     SystemTime += RHS.SystemTime;
00058     MemUsed    += RHS.MemUsed;
00059   }
00060   void operator-=(const TimeRecord &RHS) {
00061     WallTime   -= RHS.WallTime;
00062     UserTime   -= RHS.UserTime;
00063     SystemTime -= RHS.SystemTime;
00064     MemUsed    -= RHS.MemUsed;
00065   }
00066   
00067   /// print - Print the current timer to standard error, and reset the "Started"
00068   /// flag.
00069   void print(const TimeRecord &Total, raw_ostream &OS) const;
00070 };
00071   
00072 /// Timer - This class is used to track the amount of time spent between
00073 /// invocations of its startTimer()/stopTimer() methods.  Given appropriate OS
00074 /// support it can also keep track of the RSS of the program at various points.
00075 /// By default, the Timer will print the amount of time it has captured to
00076 /// standard error when the last timer is destroyed, otherwise it is printed
00077 /// when its TimerGroup is destroyed.  Timers do not print their information
00078 /// if they are never started.
00079 ///
00080 class Timer {
00081   TimeRecord Time;
00082   std::string Name;      // The name of this time variable.
00083   bool Started;          // Has this time variable ever been started?
00084   TimerGroup *TG;        // The TimerGroup this Timer is in.
00085   
00086   Timer **Prev, *Next;   // Doubly linked list of timers in the group.
00087 public:
00088   explicit Timer(StringRef N) : TG(nullptr) { init(N); }
00089   Timer(StringRef N, TimerGroup &tg) : TG(nullptr) { init(N, tg); }
00090   Timer(const Timer &RHS) : TG(nullptr) {
00091     assert(!RHS.TG && "Can only copy uninitialized timers");
00092   }
00093   const Timer &operator=(const Timer &T) {
00094     assert(!TG && !T.TG && "Can only assign uninit timers");
00095     return *this;
00096   }
00097   ~Timer();
00098 
00099   // Create an uninitialized timer, client must use 'init'.
00100   explicit Timer() : TG(nullptr) {}
00101   void init(StringRef N);
00102   void init(StringRef N, TimerGroup &tg);
00103   
00104   const std::string &getName() const { return Name; }
00105   bool isInitialized() const { return TG != nullptr; }
00106   
00107   /// startTimer - Start the timer running.  Time between calls to
00108   /// startTimer/stopTimer is counted by the Timer class.  Note that these calls
00109   /// must be correctly paired.
00110   ///
00111   void startTimer();
00112 
00113   /// stopTimer - Stop the timer.
00114   ///
00115   void stopTimer();
00116 
00117 private:
00118   friend class TimerGroup;
00119 };
00120 
00121 
00122 /// The TimeRegion class is used as a helper class to call the startTimer() and
00123 /// stopTimer() methods of the Timer class.  When the object is constructed, it
00124 /// starts the timer specified as its argument.  When it is destroyed, it stops
00125 /// the relevant timer.  This makes it easy to time a region of code.
00126 ///
00127 class TimeRegion {
00128   Timer *T;
00129   TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION;
00130 public:
00131   explicit TimeRegion(Timer &t) : T(&t) {
00132     T->startTimer();
00133   }
00134   explicit TimeRegion(Timer *t) : T(t) {
00135     if (T) T->startTimer();
00136   }
00137   ~TimeRegion() {
00138     if (T) T->stopTimer();
00139   }
00140 };
00141 
00142 
00143 /// NamedRegionTimer - This class is basically a combination of TimeRegion and
00144 /// Timer.  It allows you to declare a new timer, AND specify the region to
00145 /// time, all in one statement.  All timers with the same name are merged.  This
00146 /// is primarily used for debugging and for hunting performance problems.
00147 ///
00148 struct NamedRegionTimer : public TimeRegion {
00149   explicit NamedRegionTimer(StringRef Name,
00150                             bool Enabled = true);
00151   explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
00152                             bool Enabled = true);
00153 };
00154 
00155 
00156 /// The TimerGroup class is used to group together related timers into a single
00157 /// report that is printed when the TimerGroup is destroyed.  It is illegal to
00158 /// destroy a TimerGroup object before all of the Timers in it are gone.  A
00159 /// TimerGroup can be specified for a newly created timer in its constructor.
00160 ///
00161 class TimerGroup {
00162   std::string Name;
00163   Timer *FirstTimer;   // First timer in the group.
00164   std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
00165   
00166   TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
00167   TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
00168   void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
00169 public:
00170   explicit TimerGroup(StringRef name);
00171   ~TimerGroup();
00172 
00173   void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
00174 
00175   /// print - Print any started timers in this group and zero them.
00176   void print(raw_ostream &OS);
00177   
00178   /// printAll - This static method prints all timers and clears them all out.
00179   static void printAll(raw_ostream &OS);
00180   
00181 private:
00182   friend class Timer;
00183   void addTimer(Timer &T);
00184   void removeTimer(Timer &T);
00185   void PrintQueuedTimers(raw_ostream &OS);
00186 };
00187 
00188 } // End llvm namespace
00189 
00190 #endif