mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
change TimerGroup to keep a linked list of active timers
instead of just a count of them, and refactor the guts of report printing out of removeTimer into its own method. Refactor addTimerToPrint away. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99872 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a782e75d48
commit
b9312690a2
@ -85,6 +85,8 @@ class Timer {
|
||||
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:
|
||||
explicit Timer(const std::string &N) : TG(0) { init(N); }
|
||||
Timer(const std::string &N, TimerGroup &tg) : TG(0) { init(N, tg); }
|
||||
@ -133,12 +135,10 @@ public:
|
||||
T->startTimer();
|
||||
}
|
||||
explicit TimeRegion(Timer *t) : T(t) {
|
||||
if (T)
|
||||
T->startTimer();
|
||||
if (T) T->startTimer();
|
||||
}
|
||||
~TimeRegion() {
|
||||
if (T)
|
||||
T->stopTimer();
|
||||
if (T) T->stopTimer();
|
||||
}
|
||||
};
|
||||
|
||||
@ -162,24 +162,36 @@ struct NamedRegionTimer : public TimeRegion {
|
||||
///
|
||||
class TimerGroup {
|
||||
std::string Name;
|
||||
unsigned NumTimers;
|
||||
Timer *FirstTimer; // First timer in the group.
|
||||
std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
|
||||
public:
|
||||
explicit TimerGroup(const std::string &name) : Name(name), NumTimers(0) {}
|
||||
explicit TimerGroup() : NumTimers(0) {}
|
||||
explicit TimerGroup(const std::string &name) : Name(name), FirstTimer(0) {}
|
||||
explicit TimerGroup() : FirstTimer(0) {}
|
||||
|
||||
explicit TimerGroup(const TimerGroup &TG) : FirstTimer(0) {
|
||||
operator=(TG);
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
~TimerGroup() {
|
||||
assert(NumTimers == 0 &&
|
||||
assert(FirstTimer == 0 &&
|
||||
"TimerGroup destroyed before all contained timers!");
|
||||
}
|
||||
|
||||
void PrintQueuedTimers(raw_ostream &OS);
|
||||
|
||||
private:
|
||||
friend class Timer;
|
||||
void addTimer();
|
||||
void removeTimer();
|
||||
void addTimerToPrint(const TimeRecord &T, const std::string &Name);
|
||||
void addTimer(Timer &T);
|
||||
void removeTimer(Timer &T);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "llvm/System/Mutex.h"
|
||||
#include "llvm/System/Process.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <map>
|
||||
using namespace llvm;
|
||||
|
||||
// GetLibSupportInfoOutputFile - Return a file stream to print our output on.
|
||||
@ -101,7 +100,7 @@ void Timer::init(const std::string &N) {
|
||||
Name = N;
|
||||
Started = false;
|
||||
TG = getDefaultTimerGroup();
|
||||
TG->addTimer();
|
||||
TG->addTimer(*this);
|
||||
}
|
||||
|
||||
void Timer::init(const std::string &N, TimerGroup &tg) {
|
||||
@ -109,17 +108,12 @@ void Timer::init(const std::string &N, TimerGroup &tg) {
|
||||
Name = N;
|
||||
Started = false;
|
||||
TG = &tg;
|
||||
TG->addTimer();
|
||||
TG->addTimer(*this);
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
if (!TG) return; // Never initialized.
|
||||
|
||||
if (Started) {
|
||||
Started = false;
|
||||
TG->addTimerToPrint(Time, Name);
|
||||
}
|
||||
TG->removeTimer();
|
||||
TG->removeTimer(*this);
|
||||
}
|
||||
|
||||
static inline size_t getMemUsage() {
|
||||
@ -243,74 +237,92 @@ NamedRegionTimer::NamedRegionTimer(const std::string &Name,
|
||||
// TimerGroup Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void TimerGroup::removeTimer() {
|
||||
void TimerGroup::removeTimer(Timer &T) {
|
||||
sys::SmartScopedLock<true> L(*TimerLock);
|
||||
if (--NumTimers != 0 || TimersToPrint.empty())
|
||||
return; // Don't print timing report.
|
||||
|
||||
// Sort the timers in descending order by amount of time taken.
|
||||
std::sort(TimersToPrint.begin(), TimersToPrint.end());
|
||||
|
||||
// Figure out how many spaces to indent TimerGroup name.
|
||||
unsigned Padding = (80-Name.length())/2;
|
||||
if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
|
||||
|
||||
// If the timer was started, move its data to TimersToPrint.
|
||||
if (T.Started) {
|
||||
T.Started = false;
|
||||
TimersToPrint.push_back(std::make_pair(T.Time, T.Name));
|
||||
}
|
||||
|
||||
// Unlink the timer from our list.
|
||||
*T.Prev = T.Next;
|
||||
if (T.Next)
|
||||
T.Next->Prev = T.Prev;
|
||||
|
||||
// Print the report when all timers in this group are destroyed if some of
|
||||
// them were started.
|
||||
if (FirstTimer != 0 || TimersToPrint.empty())
|
||||
return;
|
||||
|
||||
raw_ostream *OutStream = GetLibSupportInfoOutputFile();
|
||||
|
||||
TimeRecord Total;
|
||||
for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
|
||||
Total += TimersToPrint[i].first;
|
||||
|
||||
// Print out timing header.
|
||||
*OutStream << "===" << std::string(73, '-') << "===\n";
|
||||
OutStream->indent(Padding) << Name << '\n';
|
||||
*OutStream << "===" << std::string(73, '-') << "===\n";
|
||||
|
||||
// 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) {
|
||||
*OutStream << " Total Execution Time: ";
|
||||
*OutStream << format("%5.4f", Total.getProcessTime()) << " seconds (";
|
||||
*OutStream << format("%5.4f", Total.getWallTime()) << " wall clock)\n";
|
||||
}
|
||||
*OutStream << "\n";
|
||||
|
||||
if (Total.getUserTime())
|
||||
*OutStream << " ---User Time---";
|
||||
if (Total.getSystemTime())
|
||||
*OutStream << " --System Time--";
|
||||
if (Total.getProcessTime())
|
||||
*OutStream << " --User+System--";
|
||||
*OutStream << " ---Wall Time---";
|
||||
if (Total.getMemUsed())
|
||||
*OutStream << " ---Mem---";
|
||||
*OutStream << " --- Name ---\n";
|
||||
|
||||
// Loop through all of the timing data, printing it out.
|
||||
for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) {
|
||||
const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1];
|
||||
Entry.first.print(Total, *OutStream);
|
||||
*OutStream << Entry.second << '\n';
|
||||
}
|
||||
|
||||
Total.print(Total, *OutStream);
|
||||
*OutStream << "Total\n\n";
|
||||
OutStream->flush();
|
||||
|
||||
TimersToPrint.clear();
|
||||
PrintQueuedTimers(*OutStream);
|
||||
|
||||
if (OutStream != &errs() && OutStream != &outs())
|
||||
delete OutStream; // Close the file.
|
||||
}
|
||||
|
||||
void TimerGroup::addTimer() {
|
||||
void TimerGroup::addTimer(Timer &T) {
|
||||
sys::SmartScopedLock<true> L(*TimerLock);
|
||||
++NumTimers;
|
||||
|
||||
// Add the timer to our list.
|
||||
if (FirstTimer)
|
||||
FirstTimer->Prev = &T.Next;
|
||||
T.Next = FirstTimer;
|
||||
T.Prev = &FirstTimer;
|
||||
FirstTimer = &T;
|
||||
}
|
||||
|
||||
void TimerGroup::addTimerToPrint(const TimeRecord &T, const std::string &Name) {
|
||||
sys::SmartScopedLock<true> L(*TimerLock);
|
||||
TimersToPrint.push_back(std::make_pair(T, Name));
|
||||
void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
|
||||
// Sort the timers in descending order by amount of time taken.
|
||||
std::sort(TimersToPrint.begin(), TimersToPrint.end());
|
||||
|
||||
TimeRecord Total;
|
||||
for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
|
||||
Total += TimersToPrint[i].first;
|
||||
|
||||
// Print out timing header.
|
||||
OS << "===" << std::string(73, '-') << "===\n";
|
||||
// Figure out how many spaces to indent TimerGroup name.
|
||||
unsigned Padding = (80-Name.length())/2;
|
||||
if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
|
||||
OS.indent(Padding) << Name << '\n';
|
||||
OS << "===" << std::string(73, '-') << "===\n";
|
||||
|
||||
// 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";
|
||||
}
|
||||
OS << '\n';
|
||||
|
||||
if (Total.getUserTime())
|
||||
OS << " ---User Time---";
|
||||
if (Total.getSystemTime())
|
||||
OS << " --System Time--";
|
||||
if (Total.getProcessTime())
|
||||
OS << " --User+System--";
|
||||
OS << " ---Wall Time---";
|
||||
if (Total.getMemUsed())
|
||||
OS << " ---Mem---";
|
||||
OS << " --- Name ---\n";
|
||||
|
||||
// Loop through all of the timing data, printing it out.
|
||||
for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) {
|
||||
const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1];
|
||||
Entry.first.print(Total, OS);
|
||||
OS << Entry.second << '\n';
|
||||
}
|
||||
|
||||
Total.print(Total, OS);
|
||||
OS << "Total\n\n";
|
||||
OS.flush();
|
||||
|
||||
TimersToPrint.clear();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user