[llvm-mca] Move the logic that prints scheduler statistics from BackendStatistics to its own view.

Added flag -scheduler-stats to print scheduler related statistics.

llvm-svn: 329792
diff --git a/llvm/tools/llvm-mca/BackendStatistics.cpp b/llvm/tools/llvm-mca/BackendStatistics.cpp
index c189a3a..4e378b1 100644
--- a/llvm/tools/llvm-mca/BackendStatistics.cpp
+++ b/llvm/tools/llvm-mca/BackendStatistics.cpp
@@ -21,42 +21,11 @@
 namespace mca {
 
 void BackendStatistics::onInstructionEvent(const HWInstructionEvent &Event) {
-  switch (Event.Type) {
-  default:
-    break;
-  case HWInstructionEvent::Retired: {
+  if (Event.Type == HWInstructionEvent::Retired)
     ++NumRetired;
-    break;
-  }
-  case HWInstructionEvent::Issued:
-    ++NumIssued;
-  }
 }
 
-void BackendStatistics::onReservedBuffers(ArrayRef<unsigned> Buffers) {
-  for (const unsigned Buffer : Buffers) {
-    if (BufferedResources.find(Buffer) != BufferedResources.end()) {
-      BufferUsage &BU = BufferedResources[Buffer];
-      BU.SlotsInUse++;
-      BU.MaxUsedSlots = std::max(BU.MaxUsedSlots, BU.SlotsInUse);
-      continue;
-    }
-
-    BufferedResources.insert(
-        std::pair<unsigned, BufferUsage>(Buffer, {1U, 1U}));
-  }
-}
-
-void BackendStatistics::onReleasedBuffers(ArrayRef<unsigned> Buffers) {
-  for (const unsigned Buffer : Buffers) {
-    assert(BufferedResources.find(Buffer) != BufferedResources.end() &&
-           "Buffered resource not in map?");
-    BufferUsage &BU = BufferedResources[Buffer];
-    BU.SlotsInUse--;
-  }
-}
-
-void BackendStatistics::printRetireUnitStatistics(llvm::raw_ostream &OS) const {
+void BackendStatistics::printView(llvm::raw_ostream &OS) const {
   std::string Buffer;
   raw_string_ostream TempStream(Buffer);
   TempStream << "\n\nRetire Control Unit - "
@@ -78,46 +47,4 @@
   OS << Buffer;
 }
 
-void BackendStatistics::printSchedulerStatistics(llvm::raw_ostream &OS) const {
-  std::string Buffer;
-  raw_string_ostream TempStream(Buffer);
-  TempStream << "\n\nSchedulers - number of cycles where we saw N instructions "
-                "issued:\n";
-  TempStream << "[# issued], [# cycles]\n";
-  for (const std::pair<unsigned, unsigned> &Entry : IssuedPerCycle) {
-    TempStream << " " << Entry.first << ",          " << Entry.second << "  ("
-               << format("%.1f", ((double)Entry.second / NumCycles) * 100)
-               << "%)\n";
-  }
-
-  TempStream.flush();
-  OS << Buffer;
-}
-
-void BackendStatistics::printSchedulerUsage(raw_ostream &OS,
-                                            const MCSchedModel &SM) const {
-  std::string Buffer;
-  raw_string_ostream TempStream(Buffer);
-  TempStream << "\n\nScheduler's queue usage:\n";
-  // Early exit if no buffered resources were consumed.
-  if (BufferedResources.empty()) {
-    TempStream << "No scheduler resources used.\n";
-    TempStream.flush();
-    OS << Buffer;
-    return;
-  }
-
-  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
-    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
-    if (ProcResource.BufferSize <= 0)
-      continue;
-
-    const BufferUsage &BU = BufferedResources.lookup(I);
-    TempStream << ProcResource.Name << ",  " << BU.MaxUsedSlots << '/'
-               << ProcResource.BufferSize << '\n';
-  }
-
-  TempStream.flush();
-  OS << Buffer;
-}
 } // namespace mca
diff --git a/llvm/tools/llvm-mca/BackendStatistics.h b/llvm/tools/llvm-mca/BackendStatistics.h
index 29fd43e..24b8e5c 100644
--- a/llvm/tools/llvm-mca/BackendStatistics.h
+++ b/llvm/tools/llvm-mca/BackendStatistics.h
@@ -8,18 +8,12 @@
 //===----------------------------------------------------------------------===//
 /// \file
 ///
-/// This file implements a printer class for printing generic Backend
-/// statistics related to the scheduler and retire unit.
+/// This file implements a View named BackendStatistics that knows how to
+/// collect and print a few statistics related to the retire unit.
 ///
 /// Example:
 /// ========
 ///
-/// Schedulers - number of cycles where we saw N instructions issued:
-/// [# issued], [# cycles]
-///  0,          7  (5.4%)
-///  1,          4  (3.1%)
-///  2,          8  (6.2%)
-///
 /// Retire Control Unit - number of cycles where we saw N instructions retired:
 /// [# retired], [# cycles]
 ///  0,           9  (6.9%)
@@ -27,11 +21,6 @@
 ///  2,           1  (0.8%)
 ///  4,           3  (2.3%)
 ///
-/// Scheduler's queue usage:
-/// JALU01,  0/20
-/// JFPU01,  18/18
-/// JLSAGU,  0/12
-///
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_TOOLS_LLVM_MCA_BACKENDSTATISTICS_H
@@ -49,43 +38,21 @@
 
   using Histogram = llvm::DenseMap<unsigned, unsigned>;
   Histogram RetiredPerCycle;
-  Histogram IssuedPerCycle;
 
-  unsigned NumIssued;
   unsigned NumRetired;
   unsigned NumCycles;
 
-  // Tracks the usage of a scheduler's queue.
-  struct BufferUsage {
-    unsigned SlotsInUse;
-    unsigned MaxUsedSlots;
-  };
-
-  // There is a map entry for each buffered resource in the scheduling model.
-  // Every time a buffer is consumed/freed, this view updates the corresponding
-  // entry.
-  llvm::DenseMap<unsigned, BufferUsage> BufferedResources;
-
   void updateHistograms() {
-    IssuedPerCycle[NumIssued]++;
     RetiredPerCycle[NumRetired]++;
-    NumIssued = 0;
     NumRetired = 0;
   }
 
-  void printRetireUnitStatistics(llvm::raw_ostream &OS) const;
-  void printSchedulerStatistics(llvm::raw_ostream &OS) const;
-
   void printRCUStatistics(llvm::raw_ostream &OS, const Histogram &Histogram,
                           unsigned Cycles) const;
-  void printIssuePerCycle(const Histogram &IssuePerCycle,
-                          unsigned TotalCycles) const;
-  void printSchedulerUsage(llvm::raw_ostream &OS,
-                           const llvm::MCSchedModel &SM) const;
 
 public:
   BackendStatistics(const llvm::MCSubtargetInfo &sti)
-      : STI(sti), NumIssued(0), NumRetired(0), NumCycles(0) { }
+      : STI(sti), NumRetired(0), NumCycles(0) {}
 
   void onInstructionEvent(const HWInstructionEvent &Event) override;
 
@@ -93,19 +60,7 @@
 
   void onCycleEnd(unsigned Cycle) override { updateHistograms(); }
 
-  // Increases the number of used scheduler queue slots of every buffered
-  // resource in the Buffers set.
-  void onReservedBuffers(llvm::ArrayRef<unsigned> Buffers) override;
-
-  // Decreases by one the number of used scheduler queue slots of every
-  // buffered resource in the Buffers set.
-  void onReleasedBuffers(llvm::ArrayRef<unsigned> Buffers) override;
-
-  void printView(llvm::raw_ostream &OS) const override {
-    printSchedulerStatistics(OS);
-    printRetireUnitStatistics(OS);
-    printSchedulerUsage(OS, STI.getSchedModel());
-  }
+  void printView(llvm::raw_ostream &OS) const override;
 };
 } // namespace mca
 
diff --git a/llvm/tools/llvm-mca/CMakeLists.txt b/llvm/tools/llvm-mca/CMakeLists.txt
index 98081c2..e0a97a5 100644
--- a/llvm/tools/llvm-mca/CMakeLists.txt
+++ b/llvm/tools/llvm-mca/CMakeLists.txt
@@ -26,6 +26,7 @@
   RegisterFileStatistics.cpp
   ResourcePressureView.cpp
   Scheduler.cpp
+  SchedulerStatistics.cpp
   Support.cpp
   SummaryView.cpp
   TimelineView.cpp
diff --git a/llvm/tools/llvm-mca/SchedulerStatistics.cpp b/llvm/tools/llvm-mca/SchedulerStatistics.cpp
new file mode 100644
index 0000000..28a34de
--- /dev/null
+++ b/llvm/tools/llvm-mca/SchedulerStatistics.cpp
@@ -0,0 +1,92 @@
+//===--------------------- SchedulerStatistics.cpp --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file implements the SchedulerStatistics interface.
+///
+//===----------------------------------------------------------------------===//
+
+#include "SchedulerStatistics.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+namespace mca {
+
+void SchedulerStatistics::onInstructionEvent(const HWInstructionEvent &Event) {
+  if (Event.Type == HWInstructionEvent::Issued)
+    ++NumIssued;
+}
+
+void SchedulerStatistics::onReservedBuffers(ArrayRef<unsigned> Buffers) {
+  for (const unsigned Buffer : Buffers) {
+    if (BufferedResources.find(Buffer) != BufferedResources.end()) {
+      BufferUsage &BU = BufferedResources[Buffer];
+      BU.SlotsInUse++;
+      BU.MaxUsedSlots = std::max(BU.MaxUsedSlots, BU.SlotsInUse);
+      continue;
+    }
+
+    BufferedResources.insert(
+        std::pair<unsigned, BufferUsage>(Buffer, {1U, 1U}));
+  }
+}
+
+void SchedulerStatistics::onReleasedBuffers(ArrayRef<unsigned> Buffers) {
+  for (const unsigned Buffer : Buffers) {
+    assert(BufferedResources.find(Buffer) != BufferedResources.end() &&
+           "Buffered resource not in map?");
+    BufferUsage &BU = BufferedResources[Buffer];
+    BU.SlotsInUse--;
+  }
+}
+
+void SchedulerStatistics::printSchedulerStatistics(llvm::raw_ostream &OS) const {
+  std::string Buffer;
+  raw_string_ostream TempStream(Buffer);
+  TempStream << "\n\nSchedulers - number of cycles where we saw N instructions "
+                "issued:\n";
+  TempStream << "[# issued], [# cycles]\n";
+  for (const std::pair<unsigned, unsigned> &Entry : IssuedPerCycle) {
+    TempStream << " " << Entry.first << ",          " << Entry.second << "  ("
+               << format("%.1f", ((double)Entry.second / NumCycles) * 100)
+               << "%)\n";
+  }
+
+  TempStream.flush();
+  OS << Buffer;
+}
+
+void SchedulerStatistics::printSchedulerUsage(raw_ostream &OS,
+                                            const MCSchedModel &SM) const {
+  std::string Buffer;
+  raw_string_ostream TempStream(Buffer);
+  TempStream << "\n\nScheduler's queue usage:\n";
+  // Early exit if no buffered resources were consumed.
+  if (BufferedResources.empty()) {
+    TempStream << "No scheduler resources used.\n";
+    TempStream.flush();
+    OS << Buffer;
+    return;
+  }
+
+  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
+    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
+    if (ProcResource.BufferSize <= 0)
+      continue;
+
+    const BufferUsage &BU = BufferedResources.lookup(I);
+    TempStream << ProcResource.Name << ",  " << BU.MaxUsedSlots << '/'
+               << ProcResource.BufferSize << '\n';
+  }
+
+  TempStream.flush();
+  OS << Buffer;
+}
+} // namespace mca
diff --git a/llvm/tools/llvm-mca/SchedulerStatistics.h b/llvm/tools/llvm-mca/SchedulerStatistics.h
new file mode 100644
index 0000000..88d35f0
--- /dev/null
+++ b/llvm/tools/llvm-mca/SchedulerStatistics.h
@@ -0,0 +1,95 @@
+//===--------------------- SchedulerStatistics.h ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines class SchedulerStatistics. Class SchedulerStatistics is a
+/// View that listens to instruction issue events in order to print general
+/// statistics related to the hardware schedulers.
+///
+/// Example:
+/// ========
+///
+/// Schedulers - number of cycles where we saw N instructions issued:
+/// [# issued], [# cycles]
+///  0,          7  (5.4%)
+///  1,          4  (3.1%)
+///  2,          8  (6.2%)
+///
+/// Scheduler's queue usage:
+/// JALU01,  0/20
+/// JFPU01,  18/18
+/// JLSAGU,  0/12
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_SCHEDULERSTATISTICS_H
+#define LLVM_TOOLS_LLVM_MCA_SCHEDULERSTATISTICS_H
+
+#include "View.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+
+namespace mca {
+
+class SchedulerStatistics : public View {
+  const llvm::MCSubtargetInfo &STI;
+
+  using Histogram = llvm::DenseMap<unsigned, unsigned>;
+  Histogram IssuedPerCycle;
+
+  unsigned NumIssued;
+  unsigned NumCycles;
+
+  // Tracks the usage of a scheduler's queue.
+  struct BufferUsage {
+    unsigned SlotsInUse;
+    unsigned MaxUsedSlots;
+  };
+
+  llvm::DenseMap<unsigned, BufferUsage> BufferedResources;
+
+  void updateHistograms() {
+    IssuedPerCycle[NumIssued]++;
+    NumIssued = 0;
+  }
+
+  void printSchedulerStatistics(llvm::raw_ostream &OS) const;
+
+  void printIssuePerCycle(const Histogram &IssuePerCycle,
+                          unsigned TotalCycles) const;
+  void printSchedulerUsage(llvm::raw_ostream &OS,
+                           const llvm::MCSchedModel &SM) const;
+
+public:
+  SchedulerStatistics(const llvm::MCSubtargetInfo &sti)
+      : STI(sti), NumIssued(0), NumCycles(0) { }
+
+  void onInstructionEvent(const HWInstructionEvent &Event) override;
+
+  void onCycleBegin(unsigned Cycle) override { NumCycles++; }
+
+  void onCycleEnd(unsigned Cycle) override { updateHistograms(); }
+
+  // Increases the number of used scheduler queue slots of every buffered
+  // resource in the Buffers set.
+  void onReservedBuffers(llvm::ArrayRef<unsigned> Buffers) override;
+
+  // Decreases by one the number of used scheduler queue slots of every
+  // buffered resource in the Buffers set.
+  void onReleasedBuffers(llvm::ArrayRef<unsigned> Buffers) override;
+
+  void printView(llvm::raw_ostream &OS) const override {
+    printSchedulerStatistics(OS);
+    printSchedulerUsage(OS, STI.getSchedModel());
+  }
+};
+} // namespace mca
+
+#endif
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index f49ae23..7b50196 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/tools/llvm-mca/llvm-mca.cpp
@@ -29,6 +29,7 @@
 #include "InstructionTables.h"
 #include "RegisterFileStatistics.h"
 #include "ResourcePressureView.h"
+#include "SchedulerStatistics.h"
 #include "SummaryView.h"
 #include "TimelineView.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -100,6 +101,11 @@
                        cl::init(false));
 
 static cl::opt<bool>
+    PrintiSchedulerStats("scheduler-stats",
+                         cl::desc("Print scheduler statistics"),
+                         cl::init(false));
+
+static cl::opt<bool>
     PrintResourcePressureView("resource-pressure",
                               cl::desc("Print the resource pressure view"),
                               cl::init(true));
@@ -432,6 +438,9 @@
     if (PrintDispatchStats)
       Printer.addView(llvm::make_unique<mca::DispatchStatistics>(*STI));
 
+    if (PrintiSchedulerStats)
+      Printer.addView(llvm::make_unique<mca::SchedulerStatistics>(*STI));
+
     if (PrintModeVerbose)
       Printer.addView(llvm::make_unique<mca::BackendStatistics>(*STI));