[llvm] r327018 - [llvm-mca] Unify the API for the various views. NFCI

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 8 08:08:44 PST 2018


Author: adibiagio
Date: Thu Mar  8 08:08:43 2018
New Revision: 327018

URL: http://llvm.org/viewvc/llvm-project?rev=327018&view=rev
Log:
[llvm-mca] Unify the API for the various views. NFCI

This allows the customization of the performance report.

Users can specify their own custom sequence of views.
Each view contributes a portion of the performance report generated by the
BackendPrinter.

Internally, class BackendPrinter keeps a sequence of views; views are printed
out in sequence when method 'printReport()' is called. 

This patch addresses one of the two review comments from Clement in D43951.

Added:
    llvm/trunk/tools/llvm-mca/View.cpp
    llvm/trunk/tools/llvm-mca/View.h
Modified:
    llvm/trunk/tools/llvm-mca/Backend.cpp
    llvm/trunk/tools/llvm-mca/Backend.h
    llvm/trunk/tools/llvm-mca/BackendPrinter.cpp
    llvm/trunk/tools/llvm-mca/BackendPrinter.h
    llvm/trunk/tools/llvm-mca/BackendStatistics.cpp
    llvm/trunk/tools/llvm-mca/BackendStatistics.h
    llvm/trunk/tools/llvm-mca/CMakeLists.txt
    llvm/trunk/tools/llvm-mca/HWEventListener.h
    llvm/trunk/tools/llvm-mca/ResourcePressureView.h
    llvm/trunk/tools/llvm-mca/TimelineView.h
    llvm/trunk/tools/llvm-mca/llvm-mca.cpp

Modified: llvm/trunk/tools/llvm-mca/Backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Backend.cpp?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Backend.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Backend.cpp Thu Mar  8 08:08:43 2018
@@ -31,12 +31,12 @@ void Backend::addEventListener(HWEventLi
 void Backend::runCycle(unsigned Cycle) {
   notifyCycleBegin(Cycle);
 
-  if (!SM->hasNext()) {
+  if (!SM.hasNext()) {
     notifyCycleEnd(Cycle);
     return;
   }
 
-  InstRef IR = SM->peekNext();
+  InstRef IR = SM.peekNext();
   const InstrDesc *Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
   while (DU->isAvailable(Desc->NumMicroOps) && DU->canDispatch(*Desc)) {
     Instruction *NewIS = IB->createInstruction(STI, *DU, IR.first, *IR.second);
@@ -49,12 +49,12 @@ void Backend::runCycle(unsigned Cycle) {
       notifyInstructionExecuted(IR.first);
 
     // Check if we have dispatched all the instructions.
-    SM->updateNext();
-    if (!SM->hasNext())
+    SM.updateNext();
+    if (!SM.hasNext())
       break;
 
     // Prepare for the next round.
-    IR = SM->peekNext();
+    IR = SM.peekNext();
     Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
   }
 

Modified: llvm/trunk/tools/llvm-mca/Backend.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Backend.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Backend.h (original)
+++ llvm/trunk/tools/llvm-mca/Backend.h Thu Mar  8 08:08:43 2018
@@ -48,7 +48,7 @@ class Backend {
   std::unique_ptr<InstrBuilder> IB;
   std::unique_ptr<Scheduler> HWS;
   std::unique_ptr<DispatchUnit> DU;
-  std::unique_ptr<SourceMgr> SM;
+  SourceMgr &SM;
   unsigned Cycles;
 
   llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions;
@@ -58,7 +58,7 @@ class Backend {
 
 public:
   Backend(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCInstrInfo &MCII,
-          const llvm::MCRegisterInfo &MRI, std::unique_ptr<SourceMgr> Source,
+          const llvm::MCRegisterInfo &MRI, SourceMgr &Source,
           unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0,
           unsigned MaxRetirePerCycle = 0, unsigned LoadQueueSize = 0,
           unsigned StoreQueueSize = 0, bool AssumeNoAlias = false)
@@ -69,17 +69,17 @@ public:
         DU(llvm::make_unique<DispatchUnit>(
             this, MRI, Subtarget.getSchedModel().MicroOpBufferSize,
             RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())),
-        SM(std::move(Source)), Cycles(0) {
+        SM(Source), Cycles(0) {
     IB = llvm::make_unique<InstrBuilder>(MCII, getProcResourceMasks());
   }
 
   void run() {
-    while (SM->hasNext() || !DU->isRCUEmpty())
+    while (SM.hasNext() || !DU->isRCUEmpty())
       runCycle(Cycles++);
   }
 
-  unsigned getNumIterations() const { return SM->getNumIterations(); }
-  unsigned getNumInstructions() const { return SM->size(); }
+  unsigned getNumIterations() const { return SM.getNumIterations(); }
+  unsigned getNumInstructions() const { return SM.size(); }
   unsigned getNumCycles() const { return Cycles; }
   unsigned getTotalRegisterMappingsCreated() const {
     return DU->getTotalRegisterMappingsCreated();
@@ -114,14 +114,14 @@ public:
   }
 
   const llvm::MCInst &getMCInstFromIndex(unsigned Index) const {
-    return SM->getMCInstFromIndex(Index);
+    return SM.getMCInstFromIndex(Index);
   }
 
   const InstrDesc &getInstrDesc(const llvm::MCInst &Inst) const {
     return IB->getOrCreateInstrDesc(STI, Inst);
   }
 
-  const SourceMgr &getSourceMgr() const { return *SM; }
+  const SourceMgr &getSourceMgr() const { return SM; }
 
   void addEventListener(HWEventListener *Listener);
   void notifyCycleBegin(unsigned Cycle);

Modified: llvm/trunk/tools/llvm-mca/BackendPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/BackendPrinter.cpp?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/BackendPrinter.cpp (original)
+++ llvm/trunk/tools/llvm-mca/BackendPrinter.cpp Thu Mar  8 08:08:43 2018
@@ -13,25 +13,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "BackendPrinter.h"
+#include "View.h"
 #include "llvm/CodeGen/TargetSchedule.h"
 
 namespace mca {
 
 using namespace llvm;
 
-std::unique_ptr<ToolOutputFile>
-BackendPrinter::getOutputStream(std::string OutputFile) {
-  if (OutputFile == "")
-    OutputFile = "-";
-  std::error_code EC;
-  auto Out = llvm::make_unique<ToolOutputFile>(OutputFile, EC, sys::fs::F_None);
-  if (!EC)
-    return Out;
-  errs() << EC.message() << '\n';
-  return nullptr;
-}
-
-void BackendPrinter::printGeneralStatistics(unsigned Iterations,
+void BackendPrinter::printGeneralStatistics(raw_ostream &OS,
+                                            unsigned Iterations,
                                             unsigned Cycles,
                                             unsigned Instructions,
                                             unsigned DispatchWidth) const {
@@ -46,67 +36,10 @@ void BackendPrinter::printGeneralStatist
   TempStream << "\nDispatch Width: " << DispatchWidth;
   TempStream << "\nIPC:            " << format("%.2f", IPC) << '\n';
   TempStream.flush();
-  File->os() << Buffer;
-}
-
-void BackendPrinter::printRATStatistics(unsigned TotalMappings,
-                                        unsigned MaxUsedMappings) const {
-  std::string Buffer;
-  raw_string_ostream TempStream(Buffer);
-  TempStream << "\n\nRegister Alias Table:";
-  TempStream << "\nTotal number of mappings created: " << TotalMappings;
-  TempStream << "\nMax number of mappings used:      " << MaxUsedMappings
-             << '\n';
-  TempStream.flush();
-  File->os() << Buffer;
-}
-
-void BackendPrinter::printDispatchStalls(unsigned RATStalls, unsigned RCUStalls,
-                                         unsigned SCHEDQStalls,
-                                         unsigned LDQStalls, unsigned STQStalls,
-                                         unsigned DGStalls) const {
-  std::string Buffer;
-  raw_string_ostream TempStream(Buffer);
-  TempStream << "\n\nDynamic Dispatch Stall Cycles:\n";
-  TempStream << "RAT     - Register unavailable:                      "
-             << RATStalls;
-  TempStream << "\nRCU     - Retire tokens unavailable:                 "
-             << RCUStalls;
-  TempStream << "\nSCHEDQ  - Scheduler full:                            "
-             << SCHEDQStalls;
-  TempStream << "\nLQ      - Load queue full:                           "
-             << LDQStalls;
-  TempStream << "\nSQ      - Store queue full:                          "
-             << STQStalls;
-  TempStream << "\nGROUP   - Static restrictions on the dispatch group: "
-             << DGStalls;
-  TempStream << '\n';
-  TempStream.flush();
-  File->os() << Buffer;
-}
-
-void BackendPrinter::printSchedulerUsage(
-    const MCSchedModel &SM, const ArrayRef<BufferUsageEntry> &Usage) const {
-  std::string Buffer;
-  raw_string_ostream TempStream(Buffer);
-  TempStream << "\n\nScheduler's queue usage:\n";
-  const ArrayRef<uint64_t> ResourceMasks = B.getProcResourceMasks();
-  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
-    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
-    if (!ProcResource.BufferSize)
-      continue;
-
-    for (const BufferUsageEntry &Entry : Usage)
-      if (ResourceMasks[I] == Entry.first)
-        TempStream << ProcResource.Name << ",  " << Entry.second << '/'
-                   << ProcResource.BufferSize << '\n';
-  }
-
-  TempStream.flush();
-  File->os() << Buffer;
+  OS << Buffer;
 }
 
-void BackendPrinter::printInstructionInfo() const {
+void BackendPrinter::printInstructionInfo(raw_ostream &OS) const {
   std::string Buffer;
   raw_string_ostream TempStream(Buffer);
 
@@ -143,67 +76,22 @@ void BackendPrinter::printInstructionInf
     TempStream << (ID.MayLoad ? " *     " : "       ");
     TempStream << (ID.MayStore ? " *     " : "       ");
     TempStream << (ID.HasSideEffects ? " * " : "   ");
-    MCIP->printInst(&Inst, TempStream, "", B.getSTI());
+    MCIP.printInst(&Inst, TempStream, "", B.getSTI());
     TempStream << '\n';
   }
 
   TempStream.flush();
-  File->os() << Buffer;
+  OS << Buffer;
 }
 
-void BackendPrinter::printReport() const {
-  assert(isFileValid());
+void BackendPrinter::printReport(llvm::raw_ostream &OS) const {
   unsigned Cycles = B.getNumCycles();
-  printGeneralStatistics(B.getNumIterations(), Cycles, B.getNumInstructions(),
+  printGeneralStatistics(OS, B.getNumIterations(), Cycles, B.getNumInstructions(),
                          B.getDispatchWidth());
-  printInstructionInfo();
-
-  if (EnableVerboseOutput) {
-    printDispatchStalls(B.getNumRATStalls(), B.getNumRCUStalls(),
-                        B.getNumSQStalls(), B.getNumLDQStalls(),
-                        B.getNumSTQStalls(), B.getNumDispatchGroupStalls());
-    printRATStatistics(B.getTotalRegisterMappingsCreated(),
-                       B.getMaxUsedRegisterMappings());
-    BS->printHistograms(File->os());
-
-    std::vector<BufferUsageEntry> Usage;
-    B.getBuffersUsage(Usage);
-    printSchedulerUsage(B.getSchedModel(), Usage);
-  }
-
-  if (RPV)
-    RPV->printResourcePressure(getOStream(), Cycles);
-
-  if (TV) {
-    TV->printTimeline(getOStream());
-    TV->printAverageWaitTimes(getOStream());
-  }
-}
-
-void BackendPrinter::addResourcePressureView() {
-  if (!RPV) {
-    RPV = llvm::make_unique<ResourcePressureView>(
-        B.getSTI(), *MCIP, B.getSourceMgr(), B.getProcResourceMasks());
-    B.addEventListener(RPV.get());
-  }
-}
+  printInstructionInfo(OS);
 
-void BackendPrinter::addTimelineView(unsigned MaxIterations,
-                                     unsigned MaxCycles) {
-  if (!TV) {
-    TV = llvm::make_unique<TimelineView>(B.getSTI(), *MCIP, B.getSourceMgr(),
-                                         MaxIterations, MaxCycles);
-    B.addEventListener(TV.get());
-  }
-}
-
-void BackendPrinter::initialize(std::string OutputFileName) {
-  File = getOutputStream(OutputFileName);
-  MCIP->setPrintImmHex(false);
-  if (EnableVerboseOutput) {
-    BS = llvm::make_unique<BackendStatistics>();
-    B.addEventListener(BS.get());
-  }
+  for (const auto &V : Views)
+    V->printView(OS);
 }
 
 } // namespace mca.

Modified: llvm/trunk/tools/llvm-mca/BackendPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/BackendPrinter.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/BackendPrinter.h (original)
+++ llvm/trunk/tools/llvm-mca/BackendPrinter.h Thu Mar  8 08:08:43 2018
@@ -9,9 +9,11 @@
 /// \file
 ///
 /// This file implements class BackendPrinter.
-/// BackendPrinter is able to collect statistics related to the code executed
-/// by the Backend class. Information is then printed out with the help of
-/// a MCInstPrinter (to pretty print MCInst objects) and other helper classes.
+///
+/// BackendPrinter allows the customization of the performance report.  With the
+/// help of this class, users can specify their own custom sequence of views.
+/// Each view is then printed out in sequence when method printReport() is
+/// called.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -19,20 +21,15 @@
 #define LLVM_TOOLS_LLVM_MCA_BACKENDPRINTER_H
 
 #include "Backend.h"
-#include "BackendStatistics.h"
-#include "ResourcePressureView.h"
-#include "TimelineView.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCInstPrinter.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
 
 #define DEBUG_TYPE "llvm-mca"
 
 namespace mca {
 
-class ResourcePressureView;
-class TimelineView;
+class View;
 
 /// \brief A printer class that knows how to collects statistics on the
 /// code analyzed by the llvm-mca tool.
@@ -42,59 +39,24 @@ class TimelineView;
 /// classes the task of printing out timeline information as well as
 /// resource pressure.
 class BackendPrinter {
-  Backend &B;
-  bool EnableVerboseOutput;
-
-  std::unique_ptr<llvm::MCInstPrinter> MCIP;
-  std::unique_ptr<llvm::ToolOutputFile> File;
+  const Backend &B;
+  llvm::MCInstPrinter &MCIP;
+  llvm::SmallVector<std::unique_ptr<View>, 8> Views;
 
-  std::unique_ptr<ResourcePressureView> RPV;
-  std::unique_ptr<TimelineView> TV;
-  std::unique_ptr<BackendStatistics> BS;
-
-  using Histogram = std::map<unsigned, unsigned>;
-  void printDUStatistics(const Histogram &Stats, unsigned Cycles) const;
-  void printDispatchStalls(unsigned RATStalls, unsigned RCUStalls,
-                           unsigned SQStalls, unsigned LDQStalls,
-                           unsigned STQStalls, unsigned DGStalls) const;
-  void printRATStatistics(unsigned Mappings, unsigned MaxUsedMappings) const;
-  void printRCUStatistics(const Histogram &Histogram, unsigned Cycles) const;
-  void printIssuePerCycle(const Histogram &IssuePerCycle,
-                          unsigned TotalCycles) const;
-  void printSchedulerUsage(const llvm::MCSchedModel &SM,
-                           const llvm::ArrayRef<BufferUsageEntry> &Usage) const;
-  void printGeneralStatistics(unsigned Iterations, unsigned Cycles,
+  void printGeneralStatistics(llvm::raw_ostream &OS,
+                              unsigned Iterations, unsigned Cycles,
                               unsigned Instructions,
                               unsigned DispatchWidth) const;
-  void printInstructionInfo() const;
-
-  std::unique_ptr<llvm::ToolOutputFile> getOutputStream(std::string OutputFile);
-  void initialize(std::string OputputFileName);
+  void printInstructionInfo(llvm::raw_ostream &OS) const;
 
 public:
-  BackendPrinter(Backend &backend, std::string OutputFileName,
-                 std::unique_ptr<llvm::MCInstPrinter> IP, bool EnableVerbose)
-      : B(backend), EnableVerboseOutput(EnableVerbose), MCIP(std::move(IP)) {
-    initialize(OutputFileName);
-  }
-
-  ~BackendPrinter() {
-    if (File)
-      File->keep();
-  }
-
-  bool isFileValid() const { return File.get(); }
-  llvm::raw_ostream &getOStream() const {
-    assert(isFileValid());
-    return File->os();
-  }
-
-  llvm::MCInstPrinter &getMCInstPrinter() const { return *MCIP; }
+  BackendPrinter(const Backend &backend, llvm::MCInstPrinter &IP)
+      : B(backend), MCIP(IP) {}
 
-  void addResourcePressureView();
-  void addTimelineView(unsigned MaxIterations = 3, unsigned MaxCycles = 80);
+  llvm::MCInstPrinter &getMCInstPrinter() const { return MCIP; }
 
-  void printReport() const;
+  void addView(std::unique_ptr<View> V) { Views.emplace_back(std::move(V)); }
+  void printReport(llvm::raw_ostream &OS) const;
 };
 
 } // namespace mca

Modified: llvm/trunk/tools/llvm-mca/BackendStatistics.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/BackendStatistics.cpp?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/BackendStatistics.cpp (original)
+++ llvm/trunk/tools/llvm-mca/BackendStatistics.cpp Thu Mar  8 08:08:43 2018
@@ -75,5 +75,64 @@ void BackendStatistics::printSchedulerSt
   OS << Buffer;
 }
 
+void BackendStatistics::printRATStatistics(raw_ostream &OS,
+                                        unsigned TotalMappings,
+                                        unsigned MaxUsedMappings) const {
+  std::string Buffer;
+  raw_string_ostream TempStream(Buffer);
+  TempStream << "\n\nRegister Alias Table:";
+  TempStream << "\nTotal number of mappings created: " << TotalMappings;
+  TempStream << "\nMax number of mappings used:      " << MaxUsedMappings
+             << '\n';
+  TempStream.flush();
+  OS << Buffer;
+}
+
+void BackendStatistics::printDispatchStalls(raw_ostream &OS,
+                                         unsigned RATStalls, unsigned RCUStalls,
+                                         unsigned SCHEDQStalls,
+                                         unsigned LDQStalls, unsigned STQStalls,
+                                         unsigned DGStalls) const {
+  std::string Buffer;
+  raw_string_ostream TempStream(Buffer);
+  TempStream << "\n\nDynamic Dispatch Stall Cycles:\n";
+  TempStream << "RAT     - Register unavailable:                      "
+             << RATStalls;
+  TempStream << "\nRCU     - Retire tokens unavailable:                 "
+             << RCUStalls;
+  TempStream << "\nSCHEDQ  - Scheduler full:                            "
+             << SCHEDQStalls;
+  TempStream << "\nLQ      - Load queue full:                           "
+             << LDQStalls;
+  TempStream << "\nSQ      - Store queue full:                          "
+             << STQStalls;
+  TempStream << "\nGROUP   - Static restrictions on the dispatch group: "
+             << DGStalls;
+  TempStream << '\n';
+  TempStream.flush();
+  OS << Buffer;
+}
+
+void BackendStatistics::printSchedulerUsage(raw_ostream &OS,
+    const MCSchedModel &SM, const ArrayRef<BufferUsageEntry> &Usage) const {
+  std::string Buffer;
+  raw_string_ostream TempStream(Buffer);
+  TempStream << "\n\nScheduler's queue usage:\n";
+  const ArrayRef<uint64_t> ResourceMasks = B.getProcResourceMasks();
+  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
+    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
+    if (!ProcResource.BufferSize)
+      continue;
+
+    for (const BufferUsageEntry &Entry : Usage)
+      if (ResourceMasks[I] == Entry.first)
+        TempStream << ProcResource.Name << ",  " << Entry.second << '/'
+                   << ProcResource.BufferSize << '\n';
+  }
+
+  TempStream.flush();
+  OS << Buffer;
+}
+
 } // namespace mca
 

Modified: llvm/trunk/tools/llvm-mca/BackendStatistics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/BackendStatistics.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/BackendStatistics.h (original)
+++ llvm/trunk/tools/llvm-mca/BackendStatistics.h Thu Mar  8 08:08:43 2018
@@ -14,6 +14,20 @@
 /// Example:
 /// ========
 ///
+/// Dynamic Dispatch Stall Cycles:
+/// RAT     - Register unavailable:                      0
+/// RCU     - Retire tokens unavailable:                 0
+/// SCHEDQ  - Scheduler full:                            42
+/// LQ      - Load queue full:                           0
+/// SQ      - Store queue full:                          0
+/// GROUP   - Static restrictions on the dispatch group: 0
+///
+///
+/// Register Alias Table:
+/// Total number of mappings created: 210
+/// Max number of mappings used:      35
+///
+///
 /// Dispatch Logic - number of cycles where we saw N instructions dispatched:
 /// [# dispatched], [# cycles]
 ///  0,              15  (11.5%)
@@ -32,18 +46,28 @@
 ///  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
 #define LLVM_TOOLS_LLVM_MCA_BACKENDSTATISTICS_H
 
-#include "HWEventListener.h"
+#include "Backend.h"
+#include "View.h"
 #include "llvm/Support/raw_ostream.h"
 #include <map>
 
 namespace mca {
 
-class BackendStatistics : public HWEventListener {
+class BackendStatistics : public View {
+  // TODO: remove the dependency from Backend.
+  const Backend &B;
+
   using Histogram = std::map<unsigned, unsigned>;
   Histogram DispatchGroupSizePerCycle;
   Histogram RetiredPerCycle;
@@ -67,8 +91,24 @@ class BackendStatistics : public HWEvent
   void printDispatchUnitStatistics(llvm::raw_ostream &OS) const;
   void printSchedulerStatistics(llvm::raw_ostream &OS) const;
 
+  void printDispatchStalls(llvm::raw_ostream &OS, unsigned RATStalls,
+                           unsigned RCUStalls, unsigned SQStalls,
+                           unsigned LDQStalls, unsigned STQStalls,
+                           unsigned DGStalls) const;
+  void printRATStatistics(llvm::raw_ostream &OS, unsigned Mappings,
+                          unsigned MaxUsedMappings) const;
+  void printRCUStatistics(llvm::raw_ostream &OS, const Histogram &Histogram,
+                          unsigned Cycles) const;
+  void printDispatchUnitUsage(llvm::raw_ostream &OS, const Histogram &Stats,
+                              unsigned Cycles) const;
+  void printIssuePerCycle(const Histogram &IssuePerCycle,
+                          unsigned TotalCycles) const;
+  void printSchedulerUsage(llvm::raw_ostream &OS, const llvm::MCSchedModel &SM,
+                           const llvm::ArrayRef<BufferUsageEntry> &Usage) const;
+
 public:
-  BackendStatistics() : NumDispatched(0), NumIssued(0), NumRetired(0) {}
+  BackendStatistics(const Backend &backend)
+      : B(backend), NumDispatched(0), NumIssued(0), NumRetired(0) {}
 
   void onInstructionDispatched(unsigned Index) override { NumDispatched++; }
   void
@@ -83,10 +123,18 @@ public:
 
   void onCycleEnd(unsigned Cycle) override { updateHistograms(); }
 
-  void printHistograms(llvm::raw_ostream &OS) {
+  void printView(llvm::raw_ostream &OS) const override {
+    printDispatchStalls(OS, B.getNumRATStalls(), B.getNumRCUStalls(), B.getNumSQStalls(),
+                        B.getNumLDQStalls(), B.getNumSTQStalls(), B.getNumDispatchGroupStalls());
+    printRATStatistics(OS, B.getTotalRegisterMappingsCreated(),
+                           B.getMaxUsedRegisterMappings());
     printDispatchUnitStatistics(OS);
     printSchedulerStatistics(OS);
     printRetireUnitStatistics(OS);
+
+    std::vector<BufferUsageEntry> Usage;
+    B.getBuffersUsage(Usage);
+    printSchedulerUsage(OS, B.getSchedModel(), Usage);
   }
 };
 

Modified: llvm/trunk/tools/llvm-mca/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CMakeLists.txt?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-mca/CMakeLists.txt Thu Mar  8 08:08:43 2018
@@ -22,4 +22,5 @@ add_llvm_tool(llvm-mca
   ResourcePressureView.cpp
   Scheduler.cpp
   TimelineView.cpp
+  View.cpp
   )

Modified: llvm/trunk/tools/llvm-mca/HWEventListener.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/HWEventListener.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/HWEventListener.h (original)
+++ llvm/trunk/tools/llvm-mca/HWEventListener.h Thu Mar  8 08:08:43 2018
@@ -21,7 +21,8 @@
 
 namespace mca {
 
-struct HWEventListener {
+class HWEventListener {
+public:
   // Events generated by the Retire Control Unit.
   virtual void onInstructionRetired(unsigned Index) {};
 

Modified: llvm/trunk/tools/llvm-mca/ResourcePressureView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/ResourcePressureView.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/ResourcePressureView.h (original)
+++ llvm/trunk/tools/llvm-mca/ResourcePressureView.h Thu Mar  8 08:08:43 2018
@@ -58,7 +58,7 @@
 #ifndef LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
 #define LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
 
-#include "HWEventListener.h"
+#include "View.h"
 #include "SourceMgr.h"
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCSubtargetInfo.h"
@@ -70,7 +70,7 @@ class Backend;
 
 /// This class collects resource pressure statistics and it is able to print
 /// out all the collected information as a table to an output stream.
-class ResourcePressureView : public HWEventListener {
+class ResourcePressureView : public View {
   const llvm::MCSubtargetInfo &STI;
   llvm::MCInstPrinter &MCIP;
   const SourceMgr &Source;
@@ -101,7 +101,7 @@ public:
       unsigned Index,
       const llvm::ArrayRef<std::pair<ResourceRef, unsigned>> &Used) override;
 
-  void printResourcePressure(llvm::raw_ostream &OS, unsigned Cycles) const {
+  void printView(llvm::raw_ostream &OS) const {
     unsigned Executions = Source.getNumIterations();
     printResourcePressurePerIteration(OS, Executions);
     printResourcePressurePerInstruction(OS, Executions);

Modified: llvm/trunk/tools/llvm-mca/TimelineView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/TimelineView.h?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/TimelineView.h (original)
+++ llvm/trunk/tools/llvm-mca/TimelineView.h Thu Mar  8 08:08:43 2018
@@ -100,7 +100,7 @@
 #ifndef LLVM_TOOLS_LLVM_MCA_TIMELINEVIEW_H
 #define LLVM_TOOLS_LLVM_MCA_TIMELINEVIEW_H
 
-#include "HWEventListener.h"
+#include "View.h"
 #include "SourceMgr.h"
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCSubtargetInfo.h"
@@ -116,7 +116,7 @@ namespace mca {
 /// a TimelineViewEntry object. TimelineViewEntry objects are then used
 /// to print the timeline information, as well as the "average wait times"
 /// for every instruction in the input assembly sequence.
-class TimelineView : public HWEventListener {
+class TimelineView : public View {
   const llvm::MCSubtargetInfo &STI;
   llvm::MCInstPrinter &MCIP;
   const SourceMgr &AsmSequence;
@@ -174,6 +174,10 @@ public:
   // print functionalities.
   void printTimeline(llvm::raw_ostream &OS) const;
   void printAverageWaitTimes(llvm::raw_ostream &OS) const;
+  void printView(llvm::raw_ostream &OS) const override {
+    printTimeline(OS);
+    printAverageWaitTimes(OS);
+  }
 };
 
 } // namespace mca

Added: llvm/trunk/tools/llvm-mca/View.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/View.cpp?rev=327018&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/View.cpp (added)
+++ llvm/trunk/tools/llvm-mca/View.cpp Thu Mar  8 08:08:43 2018
@@ -0,0 +1,21 @@
+//===----------------------- View.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 defines the virtual anchor method in View.h to pin the vtable.
+///
+//===----------------------------------------------------------------------===//
+
+#include "View.h"
+
+namespace mca {
+
+void View::anchor() {}
+
+} // namespace mca

Added: llvm/trunk/tools/llvm-mca/View.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/View.h?rev=327018&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/View.h (added)
+++ llvm/trunk/tools/llvm-mca/View.h Thu Mar  8 08:08:43 2018
@@ -0,0 +1,33 @@
+//===----------------------- View.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 the main interface for Views. Each view contributes a
+/// portion of the final report generated by the tool.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_VIEW_H
+#define LLVM_TOOLS_LLVM_MCA_VIEW_H
+
+#include "HWEventListener.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace mca {
+
+class View : public HWEventListener {
+public:
+  virtual void printView(llvm::raw_ostream &OS) const = 0;
+  virtual ~View() = default;
+  void anchor() override;
+};
+
+}
+
+#endif

Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=327018&r1=327017&r2=327018&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Thu Mar  8 08:08:43 2018
@@ -21,7 +21,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "BackendPrinter.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectFileInfo.h"
@@ -29,12 +28,20 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "BackendPrinter.h"
+#include "BackendStatistics.h"
+#include "ResourcePressureView.h"
+#include "TimelineView.h"
+
 
 using namespace llvm;
 
@@ -51,7 +58,7 @@ static cl::opt<std::string>
 
 static cl::opt<std::string>
     TripleName("mtriple", cl::desc("Target triple to assemble for, "
-                                  "see -version for available targets"));
+                                   "see -version for available targets"));
 
 static cl::opt<std::string>
     MCPU("mcpu",
@@ -101,10 +108,10 @@ static cl::opt<bool> PrintModeVerbose("v
                                       cl::desc("Enable verbose output"),
                                       cl::init(false));
 
-static cl::opt<bool>
-    AssumeNoAlias("noalias",
-                  cl::desc("If set, it assumes that loads and stores do not alias"),
-                  cl::init(true));
+static cl::opt<bool> AssumeNoAlias(
+    "noalias",
+    cl::desc("If set, it assumes that loads and stores do not alias"),
+    cl::init(true));
 
 static cl::opt<unsigned>
     LoadQueueSize("lqueue", cl::desc("Size of the load queue"), cl::init(0));
@@ -148,6 +155,17 @@ static int AssembleInput(const char *Pro
   return Parser->Run(false);
 }
 
+static ErrorOr<std::unique_ptr<ToolOutputFile>> getOutputStream() {
+  if (OutputFilename == "")
+    OutputFilename = "-";
+  std::error_code EC;
+  auto Out =
+      llvm::make_unique<ToolOutputFile>(OutputFilename, EC, sys::fs::F_None);
+  if (!EC)
+    return std::move(Out);
+  return EC;
+}
+
 namespace {
 
 class MCStreamerWrapper final : public MCStreamer {
@@ -284,6 +302,15 @@ int main(int argc, char **argv) {
     return 1;
   }
 
+  // Now initialize the output file.
+  auto OF = getOutputStream();
+  if (std::error_code EC = OF.getError()) {
+    errs() << EC.message() << '\n';
+    return 1;
+  }
+
+  std::unique_ptr<llvm::ToolOutputFile> TOF = std::move(*OF);
+
   const MCSchedModel &SM = STI->getSchedModel();
 
   unsigned Width = SM.IssueWidth;
@@ -291,17 +318,36 @@ int main(int argc, char **argv) {
     Width = DispatchWidth;
 
   std::unique_ptr<mca::Backend> B = llvm::make_unique<mca::Backend>(
-      *STI, *MCII, *MRI, std::move(S), Width, RegisterFileSize, MaxRetirePerCycle,
+      *STI, *MCII, *MRI, *S, Width, RegisterFileSize, MaxRetirePerCycle,
       LoadQueueSize, StoreQueueSize, AssumeNoAlias);
 
   std::unique_ptr<mca::BackendPrinter> Printer =
-      llvm::make_unique<mca::BackendPrinter>(*B, OutputFilename, std::move(IP),
-                                             PrintModeVerbose);
-  Printer->addResourcePressureView();
-  if (PrintTimelineView)
-    Printer->addTimelineView(TimelineMaxIterations, TimelineMaxCycles);
+      llvm::make_unique<mca::BackendPrinter>(*B, *IP);
+
+  if (PrintModeVerbose) {
+    std::unique_ptr<mca::BackendStatistics> BS =
+        llvm::make_unique<mca::BackendStatistics>(*B);
+    B->addEventListener(BS.get());
+    Printer->addView(std::move(BS));
+  }
+
+  std::unique_ptr<mca::ResourcePressureView> RPV =
+      llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S,
+                                                   B->getProcResourceMasks());
+  B->addEventListener(RPV.get());
+  Printer->addView(std::move(RPV));
+
+  if (PrintTimelineView) {
+    std::unique_ptr<mca::TimelineView> TV =
+        llvm::make_unique<mca::TimelineView>(
+            *STI, *IP, *S, TimelineMaxIterations, TimelineMaxCycles);
+    B->addEventListener(TV.get());
+    Printer->addView(std::move(TV));
+  }
 
   B->run();
-  Printer->printReport();
+  Printer->printReport(TOF->os());
+  TOF->keep();
+
   return 0;
 }




More information about the llvm-commits mailing list