- Rework Statistics:
    * 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
diff --git a/lib/Support/Statistic.cpp b/lib/Support/Statistic.cpp
index a6b2dbd..b6c75c2 100644
--- a/lib/Support/Statistic.cpp
+++ b/lib/Support/Statistic.cpp
@@ -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
@@ -14,12 +14,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#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 @@
 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;
   }
 }