diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index 2997a8744cc..1d4b080bb3f 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -164,30 +164,24 @@ class TimerGroup { std::string Name; Timer *FirstTimer; // First timer in the group. std::vector > TimersToPrint; + TimerGroup(const TimerGroup &TG); // DO NOT IMPLEMENT + void operator=(const TimerGroup &TG); // DO NOT IMPLEMENT public: - explicit TimerGroup(const std::string &name) : Name(name), FirstTimer(0) {} - explicit TimerGroup() : FirstTimer(0) {} + explicit TimerGroup(const std::string &name = "") + : Name(name), FirstTimer(0) {} - explicit TimerGroup(const TimerGroup &TG) : FirstTimer(0) { - operator=(TG); - } ~TimerGroup(); - void operator=(const TimerGroup &TG) { - assert(TG.FirstTimer == 0 && FirstTimer == 0 && - "Cannot assign group with timers"); - Name = TG.Name; - } - - void setName(const std::string &name) { Name = name; } - - void PrintQueuedTimers(raw_ostream &OS); + + /// print - Print any started timers in this group and zero them. + void print(raw_ostream &OS); private: friend class Timer; void addTimer(Timer &T); void removeTimer(Timer &T); + void PrintQueuedTimers(raw_ostream &OS); }; } // End llvm namespace diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp index c0bc750d596..ace9158f6c0 100644 --- a/lib/Support/Timer.cpp +++ b/lib/Support/Timer.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/Format.h" #include "llvm/System/Mutex.h" #include "llvm/System/Process.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" using namespace llvm; @@ -112,36 +113,30 @@ void Timer::init(const std::string &N, TimerGroup &tg) { } Timer::~Timer() { - if (!TG) return; // Never initialized. + if (!TG) return; // Never initialized, or already cleared. TG->removeTimer(*this); } static inline size_t getMemUsage() { - if (TrackSpace) - return sys::Process::GetMallocUsage(); - return 0; + if (!TrackSpace) return 0; + return sys::Process::GetMallocUsage(); } TimeRecord TimeRecord::getCurrentTime(bool Start) { TimeRecord Result; - - sys::TimeValue now(0,0); - sys::TimeValue user(0,0); - sys::TimeValue sys(0,0); - - ssize_t MemUsed = 0; + sys::TimeValue now(0,0), user(0,0), sys(0,0); + if (Start) { - MemUsed = getMemUsage(); + Result.MemUsed = getMemUsage(); sys::Process::GetTimeUsage(now, user, sys); } else { sys::Process::GetTimeUsage(now, user, sys); - MemUsed = getMemUsage(); + Result.MemUsed = getMemUsage(); } Result.WallTime = now.seconds() + now.microseconds() / 1000000.0; Result.UserTime = user.seconds() + user.microseconds() / 1000000.0; Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0; - Result.MemUsed = MemUsed; return Result; } @@ -196,7 +191,30 @@ void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const { //===----------------------------------------------------------------------===// typedef StringMap Name2TimerMap; -typedef StringMap > Name2PairMap; + +class Name2PairMap { + StringMap > Map; +public: + ~Name2PairMap() { + for (StringMap >::iterator + I = Map.begin(), E = Map.end(); I != E; ++I) + delete I->second.first; + } + + Timer &get(const std::string &Name, const std::string &GroupName) { + sys::SmartScopedLock L(*TimerLock); + + std::pair &GroupEntry = Map[GroupName]; + + if (!GroupEntry.first) + GroupEntry.first = new TimerGroup(GroupName); + + Timer &T = GroupEntry.second[Name]; + if (!T.isInitialized()) + T.init(Name, *GroupEntry.first); + return T; + } +}; static ManagedStatic NamedTimers; static ManagedStatic NamedGroupedTimers; @@ -210,28 +228,12 @@ static Timer &getNamedRegionTimer(const std::string &Name) { return T; } -static Timer &getNamedRegionTimer(const std::string &Name, - const std::string &GroupName) { - sys::SmartScopedLock L(*TimerLock); - - std::pair &GroupEntry = - (*NamedGroupedTimers)[GroupName]; - - if (GroupEntry.second.empty()) - GroupEntry.first.setName(GroupName); - - Timer &T = GroupEntry.second[Name]; - if (!T.isInitialized()) - T.init(Name); - return T; -} - NamedRegionTimer::NamedRegionTimer(const std::string &Name) : TimeRegion(getNamedRegionTimer(Name)) {} NamedRegionTimer::NamedRegionTimer(const std::string &Name, const std::string &GroupName) - : TimeRegion(getNamedRegionTimer(Name, GroupName)) {} + : TimeRegion(NamedGroupedTimers->get(Name, GroupName)) {} //===----------------------------------------------------------------------===// // TimerGroup Implementation @@ -331,3 +333,22 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) { TimersToPrint.clear(); } +/// print - Print any started timers in this group and zero them. +void TimerGroup::print(raw_ostream &OS) { + sys::SmartScopedLock L(*TimerLock); + + // See if any of our timers were started, if so add them to TimersToPrint and + // reset them. + for (Timer *T = FirstTimer; T; T = T->Next) { + if (!T->Started) continue; + TimersToPrint.push_back(std::make_pair(T->Time, T->Name)); + + // Clear out the time. + T->Started = 0; + T->Time = TimeRecord(); + } + + // If any timers were started, print the group. + if (!TimersToPrint.empty()) + PrintQueuedTimers(OS); +}