[llvm] r272826 - Statistic: Add machine parseable json output
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 15 13:19:16 PDT 2016
Author: matze
Date: Wed Jun 15 15:19:16 2016
New Revision: 272826
URL: http://llvm.org/viewvc/llvm-project?rev=272826&view=rev
Log:
Statistic: Add machine parseable json output
- We lacked a short unique identifier for a statistics, so I renamed the
current "Name" field that just contained the DEBUG_TYPE name of the
current file to DebugType and added a new "Name" field that contains
the C++ identifier of the statistic variable.
- Add the -stats-json option which outputs statistics in json format.
Differential Revision: http://reviews.llvm.org/D20995
Added:
llvm/trunk/test/Other/statistic.ll
Modified:
llvm/trunk/include/llvm/ADT/Statistic.h
llvm/trunk/lib/Support/Statistic.cpp
Modified: llvm/trunk/include/llvm/ADT/Statistic.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Statistic.h?rev=272826&r1=272825&r2=272826&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/Statistic.h (original)
+++ llvm/trunk/include/llvm/ADT/Statistic.h Wed Jun 15 15:19:16 2016
@@ -37,19 +37,24 @@ class raw_fd_ostream;
class Statistic {
public:
+ const char *DebugType;
const char *Name;
const char *Desc;
std::atomic<unsigned> Value;
bool Initialized;
unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
+ const char *getDebugType() const { return DebugType; }
const char *getName() const { return Name; }
const char *getDesc() const { return Desc; }
/// construct - This should only be called for non-global statistics.
- void construct(const char *name, const char *desc) {
- Name = name; Desc = desc;
- Value = 0; Initialized = false;
+ void construct(const char *debugtype, const char *name, const char *desc) {
+ DebugType = debugtype;
+ Name = name;
+ Desc = desc;
+ Value = 0;
+ Initialized = false;
}
// Allow use of this class as the value itself.
@@ -141,7 +146,7 @@ protected:
// STATISTIC - A macro to make definition of statistics really simple. This
// automatically passes the DEBUG_TYPE of the file into the statistic.
#define STATISTIC(VARNAME, DESC) \
- static llvm::Statistic VARNAME = {DEBUG_TYPE, DESC, {0}, 0}
+ static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, 0}
/// \brief Enable the collection and printing of statistics.
void EnableStatistics();
@@ -158,6 +163,9 @@ void PrintStatistics();
/// \brief Print statistics to the given output stream.
void PrintStatistics(raw_ostream &OS);
+/// Print statistics in JSON format.
+void PrintStatisticsJSON(raw_ostream &OS);
+
} // end llvm namespace
#endif // LLVM_ADT_STATISTIC_H
Modified: llvm/trunk/lib/Support/Statistic.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Statistic.cpp?rev=272826&r1=272825&r2=272826&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Statistic.cpp (original)
+++ llvm/trunk/lib/Support/Statistic.cpp Wed Jun 15 15:19:16 2016
@@ -43,6 +43,9 @@ Enabled(
cl::desc("Enable statistics output from program (available with Asserts)"));
+static cl::opt<bool> StatsAsJSON("stats-json",
+ cl::desc("Display statistics as json data"));
+
namespace {
/// StatisticInfo - This class is used in a ManagedStatic so that it is created
/// on demand (when the first statistic is bumped) and destroyed only when
@@ -51,6 +54,10 @@ class StatisticInfo {
std::vector<const Statistic*> Stats;
friend void llvm::PrintStatistics();
friend void llvm::PrintStatistics(raw_ostream &OS);
+ friend void llvm::PrintStatisticsJSON(raw_ostream &OS);
+
+ /// Sort statistics by debugtype,name,description.
+ void sort();
public:
~StatisticInfo();
@@ -95,27 +102,32 @@ bool llvm::AreStatisticsEnabled() {
return Enabled;
}
+void StatisticInfo::sort() {
+ std::stable_sort(Stats.begin(), Stats.end(),
+ [](const Statistic *LHS, const Statistic *RHS) {
+ if (int Cmp = std::strcmp(LHS->getDebugType(), RHS->getDebugType()))
+ return Cmp < 0;
+
+ if (int Cmp = std::strcmp(LHS->getName(), RHS->getName()))
+ return Cmp < 0;
+
+ return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0;
+ });
+}
+
void llvm::PrintStatistics(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;
// Figure out how long the biggest Value and Name fields are.
- unsigned MaxNameLen = 0, MaxValLen = 0;
+ unsigned MaxDebugTypeLen = 0, MaxValLen = 0;
for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i) {
MaxValLen = std::max(MaxValLen,
(unsigned)utostr(Stats.Stats[i]->getValue()).size());
- MaxNameLen = std::max(MaxNameLen,
- (unsigned)std::strlen(Stats.Stats[i]->getName()));
+ MaxDebugTypeLen = std::max(MaxDebugTypeLen,
+ (unsigned)std::strlen(Stats.Stats[i]->getDebugType()));
}
- // Sort the fields by name.
- std::stable_sort(Stats.Stats.begin(), Stats.Stats.end(),
- [](const Statistic *LHS, const Statistic *RHS) {
- if (int Cmp = std::strcmp(LHS->getName(), RHS->getName()))
- return Cmp < 0;
-
- // Secondary key is the description.
- return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0;
- });
+ Stats.sort();
// Print out the statistics header...
OS << "===" << std::string(73, '-') << "===\n"
@@ -126,12 +138,43 @@ void llvm::PrintStatistics(raw_ostream &
for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i)
OS << format("%*u %-*s - %s\n",
MaxValLen, Stats.Stats[i]->getValue(),
- MaxNameLen, Stats.Stats[i]->getName(),
+ MaxDebugTypeLen, Stats.Stats[i]->getDebugType(),
Stats.Stats[i]->getDesc());
OS << '\n'; // Flush the output stream.
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;
+
+ Stats.sort();
+ // Print all of the statistics.
+ OS << "{\n";
+ 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();
+ delim = ",\n";
+ }
+ OS << "\n}\n";
+ OS.flush();
}
void llvm::PrintStatistics() {
@@ -143,7 +186,10 @@ void llvm::PrintStatistics() {
// Get the stream to write to.
std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
- PrintStatistics(*OutStream);
+ if (StatsAsJSON)
+ PrintStatisticsJSON(*OutStream);
+ else
+ PrintStatistics(*OutStream);
#else
// Check if the -stats option is set instead of checking
Added: llvm/trunk/test/Other/statistic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/statistic.ll?rev=272826&view=auto
==============================================================================
--- llvm/trunk/test/Other/statistic.ll (added)
+++ llvm/trunk/test/Other/statistic.ll Wed Jun 15 15:19:16 2016
@@ -0,0 +1,16 @@
+; RUN: opt < %s -o /dev/null -instsimplify -stats -stats-json 2>&1 | FileCheck %s --check-prefix=JSON
+; RUN: opt < %s -o /dev/null -instsimplify -stats -stats-json -info-output-file %t && FileCheck %s < %t --check-prefix=JSON
+; RUN: opt < %s -o /dev/null -instsimplify -stats 2>&1 | FileCheck %s --check-prefix=DEFAULT
+; RUN: opt < %s -o /dev/null -instsimplify -stats -info-output-file %t && FileCheck %s < %t --check-prefix=DEFAULT
+; REQUIRES: asserts
+
+; JSON: {
+; JSON: "instsimplify.NumSimplified": 1
+; JSON: }
+
+; DEFAULT: 1 instsimplify - Number of redundant instructions removed
+
+define i32 @foo() {
+ %res = add i32 5, 4
+ ret i32 %res
+}
More information about the llvm-commits
mailing list