X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FTimer.cpp;h=896d869aa1e7ed6a9c3fcf8597f79eb29af76a28;hb=11eb51e23935e22e1cb7b346c45713e8c9169c84;hp=ace9158f6c027eb5ef60c6031e85598621c4ac20;hpb=ecdbff8c74e9c85af08fe9ec9cee4625d36c3c36;p=oota-llvm.git diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp index ace9158f6c0..896d869aa1e 100644 --- a/lib/Support/Timer.cpp +++ b/lib/Support/Timer.cpp @@ -12,15 +12,15 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Timer.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" -#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; // CreateInfoOutputFile - Return a file stream to print our output on. @@ -55,20 +55,24 @@ namespace { // CreateInfoOutputFile - Return a file stream to print our output on. raw_ostream *llvm::CreateInfoOutputFile() { - std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename(); - if (LibSupportInfoOutputFilename.empty()) + const std::string &OutputFilename = getLibSupportInfoOutputFilename(); + if (OutputFilename.empty()) return new raw_fd_ostream(2, false); // stderr. - if (LibSupportInfoOutputFilename == "-") + if (OutputFilename == "-") return new raw_fd_ostream(1, false); // stdout. + // Append mode is used because the info output file is opened and closed + // each time -stats or -time-passes wants to print output to it. To + // compensate for this, the test-suite Makefiles have code to delete the + // info output file before running commands which write to it. std::string Error; - raw_ostream *Result = new raw_fd_ostream(LibSupportInfoOutputFilename.c_str(), + raw_ostream *Result = new raw_fd_ostream(OutputFilename.c_str(), Error, raw_fd_ostream::F_Append); if (Error.empty()) return Result; errs() << "Error opening info-output-file '" - << LibSupportInfoOutputFilename << " for appending!\n"; + << OutputFilename << " for appending!\n"; delete Result; return new raw_fd_ostream(2, false); // stderr. } @@ -96,17 +100,17 @@ static TimerGroup *getDefaultTimerGroup() { // Timer Implementation //===----------------------------------------------------------------------===// -void Timer::init(const std::string &N) { +void Timer::init(StringRef N) { assert(TG == 0 && "Timer already initialized"); - Name = N; + Name.assign(N.begin(), N.end()); Started = false; TG = getDefaultTimerGroup(); TG->addTimer(*this); } -void Timer::init(const std::string &N, TimerGroup &tg) { +void Timer::init(StringRef N, TimerGroup &tg) { assert(TG == 0 && "Timer already initialized"); - Name = N; + Name.assign(N.begin(), N.end()); Started = false; TG = &tg; TG->addTimer(*this); @@ -164,10 +168,8 @@ void Timer::stopTimer() { static void printVal(double Val, double Total, raw_ostream &OS) { if (Total < 1e-7) // Avoid dividing by zero. OS << " ----- "; - else { - OS << " " << format("%7.4f", Val) << " ("; - OS << format("%5.1f", Val*100/Total) << "%)"; - } + else + OS << format(" %7.4f (%5.1f%%)", Val, Val*100/Total); } void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const { @@ -182,7 +184,7 @@ void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const { OS << " "; if (Total.getMemUsed()) - OS << format("%9lld", (long long)getMemUsed()) << " "; + OS << format("%9" PRId64 " ", (int64_t)getMemUsed()); } @@ -190,6 +192,8 @@ void TimeRecord::print(const TimeRecord &Total, raw_ostream &OS) const { // NamedRegionTimer Implementation //===----------------------------------------------------------------------===// +namespace { + typedef StringMap Name2TimerMap; class Name2PairMap { @@ -201,7 +205,7 @@ public: delete I->second.first; } - Timer &get(const std::string &Name, const std::string &GroupName) { + Timer &get(StringRef Name, StringRef GroupName) { sys::SmartScopedLock L(*TimerLock); std::pair &GroupEntry = Map[GroupName]; @@ -216,10 +220,12 @@ public: } }; +} + static ManagedStatic NamedTimers; static ManagedStatic NamedGroupedTimers; -static Timer &getNamedRegionTimer(const std::string &Name) { +static Timer &getNamedRegionTimer(StringRef Name) { sys::SmartScopedLock L(*TimerLock); Timer &T = (*NamedTimers)[Name]; @@ -228,22 +234,45 @@ static Timer &getNamedRegionTimer(const std::string &Name) { return T; } -NamedRegionTimer::NamedRegionTimer(const std::string &Name) - : TimeRegion(getNamedRegionTimer(Name)) {} +NamedRegionTimer::NamedRegionTimer(StringRef Name, + bool Enabled) + : TimeRegion(!Enabled ? 0 : &getNamedRegionTimer(Name)) {} -NamedRegionTimer::NamedRegionTimer(const std::string &Name, - const std::string &GroupName) - : TimeRegion(NamedGroupedTimers->get(Name, GroupName)) {} +NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName, + bool Enabled) + : TimeRegion(!Enabled ? 0 : &NamedGroupedTimers->get(Name, GroupName)) {} //===----------------------------------------------------------------------===// // TimerGroup Implementation //===----------------------------------------------------------------------===// +/// TimerGroupList - This is the global list of TimerGroups, maintained by the +/// TimerGroup ctor/dtor and is protected by the TimerLock lock. +static TimerGroup *TimerGroupList = 0; + +TimerGroup::TimerGroup(StringRef name) + : Name(name.begin(), name.end()), FirstTimer(0) { + + // Add the group to TimerGroupList. + sys::SmartScopedLock L(*TimerLock); + if (TimerGroupList) + TimerGroupList->Prev = &Next; + Next = TimerGroupList; + Prev = &TimerGroupList; + TimerGroupList = this; +} + TimerGroup::~TimerGroup() { // If the timer group is destroyed before the timers it owns, accumulate and // print the timing data. while (FirstTimer != 0) removeTimer(*FirstTimer); + + // Remove the group from the TimerGroupList. + sys::SmartScopedLock L(*TimerLock); + *Prev = Next; + if (Next) + Next->Prev = Prev; } @@ -301,11 +330,9 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) { // If this is not an collection of ungrouped times, print the total time. // Ungrouped timers don't really make sense to add up. We still print the // TOTAL line to make the percentages make sense. - if (this != DefaultTimerGroup) { - OS << " Total Execution Time: "; - OS << format("%5.4f", Total.getProcessTime()) << " seconds ("; - OS << format("%5.4f", Total.getWallTime()) << " wall clock)\n"; - } + if (this != DefaultTimerGroup) + OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n", + Total.getProcessTime(), Total.getWallTime()); OS << '\n'; if (Total.getUserTime()) @@ -352,3 +379,11 @@ void TimerGroup::print(raw_ostream &OS) { if (!TimersToPrint.empty()) PrintQueuedTimers(OS); } + +/// printAll - This static method prints all timers and clears them all out. +void TimerGroup::printAll(raw_ostream &OS) { + sys::SmartScopedLock L(*TimerLock); + + for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next) + TG->print(OS); +}