//===----------------------------------------------------------------------===//
#include "llvm/Support/Timer.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-// CreateInfoOutputFile - Return a file stream to print our output on.
-namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
-
// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
// of constructor/destructor ordering being unspecified by C++. Basically the
// problem is that a Statistic object gets destroyed, which ends up calling
cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
}
-// CreateInfoOutputFile - Return a file stream to print our output on.
-raw_ostream *llvm::CreateInfoOutputFile() {
+// Return a file stream to print our output on.
+std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
const std::string &OutputFilename = getLibSupportInfoOutputFilename();
if (OutputFilename.empty())
- return new raw_fd_ostream(2, false); // stderr.
+ return llvm::make_unique<raw_fd_ostream>(2, false); // stderr.
if (OutputFilename == "-")
- return new raw_fd_ostream(1, false); // stdout.
-
+ return llvm::make_unique<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(
- OutputFilename.c_str(), Error, sys::fs::F_Append | sys::fs::F_Text);
- if (Error.empty())
+ std::error_code EC;
+ auto Result = llvm::make_unique<raw_fd_ostream>(
+ OutputFilename, EC, sys::fs::F_Append | sys::fs::F_Text);
+ if (!EC)
return Result;
-
+
errs() << "Error opening info-output-file '"
<< OutputFilename << " for appending!\n";
- delete Result;
- return new raw_fd_ostream(2, false); // stderr.
+ return llvm::make_unique<raw_fd_ostream>(2, false); // stderr.
}
sys::MemoryFence();
if (tmp) return tmp;
- llvm_acquire_global_lock();
+ sys::SmartScopedLock<true> Lock(*TimerLock);
tmp = DefaultTimerGroup;
if (!tmp) {
tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
sys::MemoryFence();
DefaultTimerGroup = tmp;
}
- llvm_release_global_lock();
return tmp;
}
//===----------------------------------------------------------------------===//
void Timer::init(StringRef N) {
- assert(!TG && "Timer already initialized");
- Name.assign(N.begin(), N.end());
- Started = false;
- TG = getDefaultTimerGroup();
- TG->addTimer(*this);
+ init(N, *getDefaultTimerGroup());
}
void Timer::init(StringRef N, TimerGroup &tg) {
assert(!TG && "Timer already initialized");
Name.assign(N.begin(), N.end());
- Started = false;
+ Running = Triggered = false;
TG = &tg;
TG->addTimer(*this);
}
return Result;
}
-static ManagedStatic<std::vector<Timer*> > ActiveTimers;
-
void Timer::startTimer() {
- Started = true;
- ActiveTimers->push_back(this);
- Time -= TimeRecord::getCurrentTime(true);
+ assert(!Running && "Cannot start a running timer");
+ Running = Triggered = true;
+ StartTime = TimeRecord::getCurrentTime(true);
}
void Timer::stopTimer() {
+ assert(Running && "Cannot stop a paused timer");
+ Running = false;
Time += TimeRecord::getCurrentTime(false);
+ Time -= StartTime;
+}
- if (ActiveTimers->back() == this) {
- ActiveTimers->pop_back();
- } else {
- std::vector<Timer*>::iterator I =
- std::find(ActiveTimers->begin(), ActiveTimers->end(), this);
- assert(I != ActiveTimers->end() && "stop but no startTimer?");
- ActiveTimers->erase(I);
- }
+void Timer::clear() {
+ Running = Triggered = false;
+ Time = StartTime = TimeRecord();
}
static void printVal(double Val, double Total, raw_ostream &OS) {
sys::SmartScopedLock<true> L(*TimerLock);
// If the timer was started, move its data to TimersToPrint.
- if (T.Started)
- TimersToPrint.push_back(std::make_pair(T.Time, T.Name));
+ if (T.hasTriggered())
+ TimersToPrint.emplace_back(T.Time, T.Name);
T.TG = nullptr;
// them were started.
if (FirstTimer || TimersToPrint.empty())
return;
-
- raw_ostream *OutStream = CreateInfoOutputFile();
+
+ std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
PrintQueuedTimers(*OutStream);
- delete OutStream; // Close the file.
}
void TimerGroup::addTimer(Timer &T) {
std::sort(TimersToPrint.begin(), TimersToPrint.end());
TimeRecord Total;
- for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
- Total += TimersToPrint[i].first;
+ for (auto &RecordNamePair : TimersToPrint)
+ Total += RecordNamePair.first;
// Print out timing header.
OS << "===" << std::string(73, '-') << "===\n";
// 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));
+ if (!T->hasTriggered()) continue;
+ TimersToPrint.emplace_back(T->Time, T->Name);
// Clear out the time.
- T->Started = 0;
- T->Time = TimeRecord();
+ T->clear();
}
// If any timers were started, print the group.