- Rework Statistics:
authorChris Lattner <sabre@nondot.org>
Tue, 1 Oct 2002 22:35:45 +0000 (22:35 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 1 Oct 2002 22:35:45 +0000 (22:35 +0000)
    * Renamed StatisticReporter.h/cpp to Statistic.h/cpp
    * Broke constructor to take two const char * arguments instead of one, so
      that indendation can be taken care of automatically.
    * Sort the list by pass name when printing
    * Make sure to print all statistics as a group, instead of randomly when
      the statistics dtors are called.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3999 91177308-0d34-0410-b5e6-96231b3b80d8

include/Support/Statistic.h
include/Support/StatisticReporter.h [deleted file]
include/llvm/ADT/Statistic.h
lib/Support/Statistic.cpp
support/lib/Support/Statistic.cpp
support/lib/Support/StatisticReporter.cpp [deleted file]

index 8f6ed79da8fb4910e28b216d0e1f778f79899600..62dec92bc4fa79c09bdebbc3e3b9012d64b4c5b0 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Support/StatisticReporter.h - Easy way to expose stats ---*- C++ -*-==//
+//===-- Support/Statistic.h - Easy way to expose stats ----------*- C++ -*-===//
 //
 // This file defines the 'Statistic' class, which is designed to be an easy way
 // to expose various success metrics from passes.  These statistics are printed
@@ -14,8 +14,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef SUPPORT_STATISTIC_REPORTER_H
-#define SUPPORT_STATISTIC_REPORTER_H
+#ifndef SUPPORT_STATISTIC_H
+#define SUPPORT_STATISTIC_H
 
 #include <iosfwd>
 
@@ -43,8 +43,12 @@ extern bool DebugFlag;
 // StatisticBase - Nontemplated base class for Statistic<> class...
 class StatisticBase {
   const char *Name;
+  const char *Desc;
+  static unsigned NumStats;
 protected:
-  StatisticBase(const char *name) : Name(name) {}
+  StatisticBase(const char *name, const char *desc) : Name(name), Desc(desc) {
+    ++NumStats;  // Keep track of how many stats are created...
+  }
   virtual ~StatisticBase() {}
 
   // destroy - Called by subclass dtor so that we can still invoke virtual
@@ -69,11 +73,12 @@ class Statistic : private StatisticBase {
   virtual bool hasSomeData() const { return Value != DataType(); }
 public:
   // Normal constructor, default initialize data item...
-  Statistic(const char *name) : StatisticBase(name), Value(DataType()) {}
+  Statistic(const char *name, const char *desc)
+    : StatisticBase(name, desc), Value(DataType()) {}
 
   // Constructor to provide an initial value...
-  Statistic(const DataType &Val, const char *name)
-    : StatisticBase(name), Value(Val) {}
+  Statistic(const DataType &Val, const char *name, const char *desc)
+    : StatisticBase(name, desc), Value(Val) {}
 
   // Print information when destroyed, iff command line option is specified
   ~Statistic() { destroy(); }
diff --git a/include/Support/StatisticReporter.h b/include/Support/StatisticReporter.h
deleted file mode 100644 (file)
index 8f6ed79..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-//===-- Support/StatisticReporter.h - Easy way to expose stats ---*- C++ -*-==//
-//
-// This file defines the 'Statistic' class, which is designed to be an easy way
-// to expose various success metrics from passes.  These statistics are printed
-// at the end of a run, when the -stats command line option is enabled on the
-// command line.
-//
-// This is useful for reporting information like the number of instructions
-// simplified, optimized or removed by various transformations, like this:
-//
-// static Statistic<> NumInstEliminated("GCSE - Number of instructions killed");
-//
-// Later, in the code: ++NumInstEliminated;
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SUPPORT_STATISTIC_REPORTER_H
-#define SUPPORT_STATISTIC_REPORTER_H
-
-#include <iosfwd>
-
-// DebugFlag - This boolean is set to true if the '-debug' command line option
-// is specified.  This should probably not be referenced directly, instead, use
-// the DEBUG macro below.
-//
-extern bool DebugFlag;
-
-// DEBUG macro - This macro should be used by passes to emit debug information.
-// In the '-debug' option is specified on the commandline, and if this is a
-// debug build, then the code specified as the option to the macro will be
-// executed.  Otherwise it will not be.  Example:
-//
-// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
-//
-#ifdef NDEBUG
-#define DEBUG(X)
-#else
-#define DEBUG(X) \
-  do { if (DebugFlag) { X; } } while (0)
-#endif
-
-
-// StatisticBase - Nontemplated base class for Statistic<> class...
-class StatisticBase {
-  const char *Name;
-protected:
-  StatisticBase(const char *name) : Name(name) {}
-  virtual ~StatisticBase() {}
-
-  // destroy - Called by subclass dtor so that we can still invoke virtual
-  // functions on the subclass.
-  void destroy() const;
-
-  // printValue - Overridden by template class to print out the value type...
-  virtual void printValue(std::ostream &o) const = 0;
-
-  // hasSomeData - Return true if some data has been aquired.  Avoid printing
-  // lots of zero counts.
-  //
-  virtual bool hasSomeData() const = 0;
-};
-
-// Statistic Class - templated on the data type we are monitoring...
-template <typename DataType=unsigned>
-class Statistic : private StatisticBase {
-  DataType Value;
-
-  virtual void printValue(std::ostream &o) const { o << Value; }
-  virtual bool hasSomeData() const { return Value != DataType(); }
-public:
-  // Normal constructor, default initialize data item...
-  Statistic(const char *name) : StatisticBase(name), Value(DataType()) {}
-
-  // Constructor to provide an initial value...
-  Statistic(const DataType &Val, const char *name)
-    : StatisticBase(name), Value(Val) {}
-
-  // Print information when destroyed, iff command line option is specified
-  ~Statistic() { destroy(); }
-
-  // Allow use of this class as the value itself...
-  inline operator DataType() const { return Value; }
-  inline const DataType &operator=(DataType Val) { Value = Val; return Value; }
-  inline const DataType &operator++() { return ++Value; }
-  inline DataType operator++(int) { return Value++; }
-  inline const DataType &operator+=(const DataType &V) { return Value += V; }
-  inline const DataType &operator-=(const DataType &V) { return Value -= V; }
-};
-
-#endif
index 8f6ed79da8fb4910e28b216d0e1f778f79899600..62dec92bc4fa79c09bdebbc3e3b9012d64b4c5b0 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Support/StatisticReporter.h - Easy way to expose stats ---*- C++ -*-==//
+//===-- Support/Statistic.h - Easy way to expose stats ----------*- C++ -*-===//
 //
 // This file defines the 'Statistic' class, which is designed to be an easy way
 // to expose various success metrics from passes.  These statistics are printed
@@ -14,8 +14,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef SUPPORT_STATISTIC_REPORTER_H
-#define SUPPORT_STATISTIC_REPORTER_H
+#ifndef SUPPORT_STATISTIC_H
+#define SUPPORT_STATISTIC_H
 
 #include <iosfwd>
 
@@ -43,8 +43,12 @@ extern bool DebugFlag;
 // StatisticBase - Nontemplated base class for Statistic<> class...
 class StatisticBase {
   const char *Name;
+  const char *Desc;
+  static unsigned NumStats;
 protected:
-  StatisticBase(const char *name) : Name(name) {}
+  StatisticBase(const char *name, const char *desc) : Name(name), Desc(desc) {
+    ++NumStats;  // Keep track of how many stats are created...
+  }
   virtual ~StatisticBase() {}
 
   // destroy - Called by subclass dtor so that we can still invoke virtual
@@ -69,11 +73,12 @@ class Statistic : private StatisticBase {
   virtual bool hasSomeData() const { return Value != DataType(); }
 public:
   // Normal constructor, default initialize data item...
-  Statistic(const char *name) : StatisticBase(name), Value(DataType()) {}
+  Statistic(const char *name, const char *desc)
+    : StatisticBase(name, desc), Value(DataType()) {}
 
   // Constructor to provide an initial value...
-  Statistic(const DataType &Val, const char *name)
-    : StatisticBase(name), Value(Val) {}
+  Statistic(const DataType &Val, const char *name, const char *desc)
+    : StatisticBase(name, desc), Value(Val) {}
 
   // Print information when destroyed, iff command line option is specified
   ~Statistic() { destroy(); }
index a6b2dbdef6abd6bbf36b1c89f02aa4b7d6bb80f4..b6c75c2adee49e5048bf8d27ead48b5f3144801a 100644 (file)
@@ -1,4 +1,4 @@
-//===-- StatisticReporter.cpp - Easy way to expose stats information -------==//
+//===-- Statistic.cpp - Easy way to expose stats information --------------===//
 //
 // This file implements the 'Statistic' class, which is designed to be an easy
 // way to expose various success metrics from passes.  These statistics are
 //
 //===----------------------------------------------------------------------===//
 
-#include "Support/StatisticReporter.h"
+#include "Support/Statistic.h"
 #include "Support/CommandLine.h"
 #include <iostream>
+#include <sstream>
 
 bool DebugFlag;  // DebugFlag - Exported boolean set by the -debug option
 
+unsigned StatisticBase::NumStats = 0;
+
 // -stats - Command line option to cause transformations to emit stats about
 // what they did.
 //
@@ -31,12 +34,62 @@ static cl::opt<bool, true>
 Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
       cl::location(DebugFlag));
 
+struct StatRecord {
+  std::string Value;
+  const char *Name, *Desc;
+
+  StatRecord(const std::string V, const char *N, const char *D)
+    : Value(V), Name(N), Desc(D) {}
+
+  bool operator<(const StatRecord &SR) const {
+    return std::strcmp(Name, SR.Name) < 0;
+  }
+
+  void print(unsigned ValFieldSize, unsigned NameFieldSize) {
+    std::cerr << std::string(ValFieldSize-Value.length(), ' ')
+              << Value << " " << Name
+              << std::string(NameFieldSize-std::strlen(Name), ' ')
+              << " - " << Desc << "\n";
+  }
+};
+
+static std::vector<StatRecord> *AccumStats = 0;
+
 // Print information when destroyed, iff command line option is specified
 void StatisticBase::destroy() const {
   if (Enabled && hasSomeData()) {
-    std::cerr.width(7);
-    printValue(std::cerr);
-    std::cerr.width(0);
-    std::cerr << "\t" << Name << "\n";
+    if (AccumStats == 0)
+      AccumStats = new std::vector<StatRecord>();
+
+    std::ostringstream Out;
+    printValue(Out);
+    AccumStats->push_back(StatRecord(Out.str(), Name, Desc));
+  }
+
+  if (--NumStats == 0 && AccumStats) {
+    // Figure out how long the biggest Value and Name fields are...
+    unsigned MaxNameLen = 0, MaxValLen = 0;
+    for (unsigned i = 0, e = AccumStats->size(); i != e; ++i) {
+      MaxValLen = std::max(MaxValLen, (*AccumStats)[i].Value.length());
+      MaxNameLen = std::max(MaxNameLen, std::strlen((*AccumStats)[i].Name));
+    }
+
+    // Sort the fields...
+    std::stable_sort(AccumStats->begin(), AccumStats->end());
+
+    // Print out the statistics header...
+    std::cerr << "===" << std::string(73, '-') << "===\n"
+              << "                          ... Statistics Collected ...\n"
+              << "===" << std::string(73, '-') << "===\n\n";
+
+    // Print all of the statistics accumulated...
+    for (unsigned i = 0, e = AccumStats->size(); i != e; ++i)
+      (*AccumStats)[i].print(MaxValLen, MaxNameLen);
+
+    std::cerr << std::endl;  // Flush the output stream...
+
+    // Free all accumulated statistics...
+    delete AccumStats;
+    AccumStats = 0;
   }
 }
index a6b2dbdef6abd6bbf36b1c89f02aa4b7d6bb80f4..b6c75c2adee49e5048bf8d27ead48b5f3144801a 100644 (file)
@@ -1,4 +1,4 @@
-//===-- StatisticReporter.cpp - Easy way to expose stats information -------==//
+//===-- Statistic.cpp - Easy way to expose stats information --------------===//
 //
 // This file implements the 'Statistic' class, which is designed to be an easy
 // way to expose various success metrics from passes.  These statistics are
 //
 //===----------------------------------------------------------------------===//
 
-#include "Support/StatisticReporter.h"
+#include "Support/Statistic.h"
 #include "Support/CommandLine.h"
 #include <iostream>
+#include <sstream>
 
 bool DebugFlag;  // DebugFlag - Exported boolean set by the -debug option
 
+unsigned StatisticBase::NumStats = 0;
+
 // -stats - Command line option to cause transformations to emit stats about
 // what they did.
 //
@@ -31,12 +34,62 @@ static cl::opt<bool, true>
 Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
       cl::location(DebugFlag));
 
+struct StatRecord {
+  std::string Value;
+  const char *Name, *Desc;
+
+  StatRecord(const std::string V, const char *N, const char *D)
+    : Value(V), Name(N), Desc(D) {}
+
+  bool operator<(const StatRecord &SR) const {
+    return std::strcmp(Name, SR.Name) < 0;
+  }
+
+  void print(unsigned ValFieldSize, unsigned NameFieldSize) {
+    std::cerr << std::string(ValFieldSize-Value.length(), ' ')
+              << Value << " " << Name
+              << std::string(NameFieldSize-std::strlen(Name), ' ')
+              << " - " << Desc << "\n";
+  }
+};
+
+static std::vector<StatRecord> *AccumStats = 0;
+
 // Print information when destroyed, iff command line option is specified
 void StatisticBase::destroy() const {
   if (Enabled && hasSomeData()) {
-    std::cerr.width(7);
-    printValue(std::cerr);
-    std::cerr.width(0);
-    std::cerr << "\t" << Name << "\n";
+    if (AccumStats == 0)
+      AccumStats = new std::vector<StatRecord>();
+
+    std::ostringstream Out;
+    printValue(Out);
+    AccumStats->push_back(StatRecord(Out.str(), Name, Desc));
+  }
+
+  if (--NumStats == 0 && AccumStats) {
+    // Figure out how long the biggest Value and Name fields are...
+    unsigned MaxNameLen = 0, MaxValLen = 0;
+    for (unsigned i = 0, e = AccumStats->size(); i != e; ++i) {
+      MaxValLen = std::max(MaxValLen, (*AccumStats)[i].Value.length());
+      MaxNameLen = std::max(MaxNameLen, std::strlen((*AccumStats)[i].Name));
+    }
+
+    // Sort the fields...
+    std::stable_sort(AccumStats->begin(), AccumStats->end());
+
+    // Print out the statistics header...
+    std::cerr << "===" << std::string(73, '-') << "===\n"
+              << "                          ... Statistics Collected ...\n"
+              << "===" << std::string(73, '-') << "===\n\n";
+
+    // Print all of the statistics accumulated...
+    for (unsigned i = 0, e = AccumStats->size(); i != e; ++i)
+      (*AccumStats)[i].print(MaxValLen, MaxNameLen);
+
+    std::cerr << std::endl;  // Flush the output stream...
+
+    // Free all accumulated statistics...
+    delete AccumStats;
+    AccumStats = 0;
   }
 }
diff --git a/support/lib/Support/StatisticReporter.cpp b/support/lib/Support/StatisticReporter.cpp
deleted file mode 100644 (file)
index a6b2dbd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- StatisticReporter.cpp - Easy way to expose stats information -------==//
-//
-// This file implements the 'Statistic' class, which is designed to be an easy
-// way to expose various success metrics from passes.  These statistics are
-// printed at the end of a run, when the -stats command line option is enabled
-// on the command line.
-//
-// This is useful for reporting information like the number of instructions
-// simplified, optimized or removed by various transformations, like this:
-//
-// static Statistic<> NumInstEliminated("GCSE - Number of instructions killed");
-//
-// Later, in the code: ++NumInstEliminated;
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/StatisticReporter.h"
-#include "Support/CommandLine.h"
-#include <iostream>
-
-bool DebugFlag;  // DebugFlag - Exported boolean set by the -debug option
-
-// -stats - Command line option to cause transformations to emit stats about
-// what they did.
-//
-static cl::opt<bool>
-Enabled("stats", cl::desc("Enable statistics output from program"));
-
-// -debug - Command line option to enable the DEBUG statements in the passes.
-static cl::opt<bool, true>
-Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
-      cl::location(DebugFlag));
-
-// Print information when destroyed, iff command line option is specified
-void StatisticBase::destroy() const {
-  if (Enabled && hasSomeData()) {
-    std::cerr.width(7);
-    printValue(std::cerr);
-    std::cerr.width(0);
-    std::cerr << "\t" << Name << "\n";
-  }
-}