summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r--llvm/lib/Support/Statistic.cpp32
-rw-r--r--llvm/lib/Support/Timer.cpp62
2 files changed, 67 insertions, 27 deletions
diff --git a/llvm/lib/Support/Statistic.cpp b/llvm/lib/Support/Statistic.cpp
index d299bfcae46..0c50dfd27d6 100644
--- a/llvm/lib/Support/Statistic.cpp
+++ b/llvm/lib/Support/Statistic.cpp
@@ -29,7 +29,9 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstring>
using namespace llvm;
@@ -60,6 +62,7 @@ class StatisticInfo {
/// Sort statistics by debugtype,name,description.
void sort();
public:
+ StatisticInfo();
~StatisticInfo();
void addStatistic(const Statistic *S) {
@@ -90,6 +93,11 @@ void Statistic::RegisterStatistic() {
}
}
+StatisticInfo::StatisticInfo() {
+ // Ensure timergroup lists are created first so they are destructed after us.
+ TimerGroup::ConstructTimerLists();
+}
+
// Print information when destroyed, iff command line option is specified.
StatisticInfo::~StatisticInfo() {
if (::Stats || PrintOnExit)
@@ -148,17 +156,6 @@ void llvm::PrintStatistics(raw_ostream &OS) {
OS.flush();
}
-static void write_json_string_escaped(raw_ostream &OS, const char *string) {
- // Out current usage should not need any escaping. Keep it simple and just
- // check that the input is pure ASCII without special characers.
-#ifndef NDEBUG
- for (const unsigned char *c = (const unsigned char*)string; *c != '\0'; ++c) {
- assert(*c != '\\' && *c != '\"' && *c >= 0x20 && *c < 0x80);
- }
-#endif
- OS << string;
-}
-
void llvm::PrintStatisticsJSON(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;
@@ -169,13 +166,16 @@ void llvm::PrintStatisticsJSON(raw_ostream &OS) {
const char *delim = "";
for (const Statistic *Stat : Stats.Stats) {
OS << delim;
- OS << "\t\"";
- write_json_string_escaped(OS, Stat->getDebugType());
- OS << '.';
- write_json_string_escaped(OS, Stat->getName());
- OS << "\": " << Stat->getValue();
+ assert(!yaml::needsQuotes(Stat->getDebugType()) &&
+ "Statistic group/type name is simple.");
+ assert(!yaml::needsQuotes(Stat->getName()) && "Statistic name is simple");
+ OS << "\t\"" << Stat->getDebugType() << '.' << Stat->getName() << "\": "
+ << Stat->getValue();
delim = ",\n";
}
+ // Print timers.
+ TimerGroup::printAllJSONValues(OS, delim);
+
OS << "\n}\n";
OS.flush();
}
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index cca538c3d25..fbd73d0b6b3 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -21,6 +21,7 @@
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
// This ugly hack is brought to you courtesy of constructor/destructor ordering
@@ -260,7 +261,7 @@ void TimerGroup::removeTimer(Timer &T) {
// If the timer was started, move its data to TimersToPrint.
if (T.hasTriggered())
- TimersToPrint.emplace_back(T.Time, T.Description);
+ TimersToPrint.emplace_back(T.Time, T.Name, T.Description);
T.TG = nullptr;
@@ -294,8 +295,8 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
std::sort(TimersToPrint.begin(), TimersToPrint.end());
TimeRecord Total;
- for (auto &RecordNamePair : TimersToPrint)
- Total += RecordNamePair.first;
+ for (const PrintRecord &Record : TimersToPrint)
+ Total += Record.Time;
// Print out timing header.
OS << "===" << std::string(73, '-') << "===\n";
@@ -325,10 +326,10 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
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';
+ for (const PrintRecord &Record : make_range(TimersToPrint.rbegin(),
+ TimersToPrint.rend())) {
+ Record.Time.print(Total, OS);
+ OS << Record.Description << '\n';
}
Total.print(Total, OS);
@@ -338,18 +339,22 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
TimersToPrint.clear();
}
-void TimerGroup::print(raw_ostream &OS) {
- sys::SmartScopedLock<true> L(*TimerLock);
-
+void TimerGroup::prepareToPrintList() {
// 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->hasTriggered()) continue;
- TimersToPrint.emplace_back(T->Time, T->Description);
+ TimersToPrint.emplace_back(T->Time, T->Name, T->Description);
// Clear out the time.
T->clear();
}
+}
+
+void TimerGroup::print(raw_ostream &OS) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ prepareToPrintList();
// If any timers were started, print the group.
if (!TimersToPrint.empty())
@@ -362,3 +367,38 @@ void TimerGroup::printAll(raw_ostream &OS) {
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
TG->print(OS);
}
+
+void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
+ const char *suffix, double Value) {
+ assert(!yaml::needsQuotes(Name) && "TimerGroup name needs no quotes");
+ assert(!yaml::needsQuotes(R.Name) && "Timer name needs no quotes");
+ OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value;
+}
+
+const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
+ prepareToPrintList();
+ for (const PrintRecord &R : TimersToPrint) {
+ OS << delim;
+ delim = ",\n";
+
+ const TimeRecord &T = R.Time;
+ printJSONValue(OS, R, ".wall", T.getWallTime());
+ OS << delim;
+ printJSONValue(OS, R, ".user", T.getUserTime());
+ OS << delim;
+ printJSONValue(OS, R, ".sys", T.getSystemTime());
+ }
+ TimersToPrint.clear();
+ return delim;
+}
+
+const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+ for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
+ delim = TG->printJSONValues(OS, delim);
+ return delim;
+}
+
+void TimerGroup::ConstructTimerLists() {
+ (void)*NamedGroupedTimers;
+}
OpenPOWER on IntegriCloud