[llvm] cf6adec - [llvm-mca][NFC] Refactor views to separate data collection from printing.

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 11:28:22 PDT 2020


Author: Wolfgang Pieb
Date: 2020-08-21T11:27:36-07:00
New Revision: cf6adecd6a8718ee2737ca55e4cd938364b984cc

URL: https://github.com/llvm/llvm-project/commit/cf6adecd6a8718ee2737ca55e4cd938364b984cc
DIFF: https://github.com/llvm/llvm-project/commit/cf6adecd6a8718ee2737ca55e4cd938364b984cc.diff

LOG: [llvm-mca][NFC] Refactor views to separate data collection from printing.

    Reviewed By: andreadb, lebedev.ri

    Differential Revision: https://reviews.llvm.org/D86177

Added: 
    

Modified: 
    llvm/tools/llvm-mca/Views/InstructionInfoView.cpp
    llvm/tools/llvm-mca/Views/InstructionInfoView.h
    llvm/tools/llvm-mca/Views/SummaryView.cpp
    llvm/tools/llvm-mca/Views/SummaryView.h

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp b/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp
index fbe9d9021554..548f0b36d055 100644
--- a/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp
+++ b/llvm/tools/llvm-mca/Views/InstructionInfoView.cpp
@@ -20,11 +20,15 @@ namespace mca {
 void InstructionInfoView::printView(raw_ostream &OS) const {
   std::string Buffer;
   raw_string_ostream TempStream(Buffer);
-  const MCSchedModel &SM = STI.getSchedModel();
-
   std::string Instruction;
   raw_string_ostream InstrStream(Instruction);
 
+  if (!Source.size())
+    return;
+
+  IIVDVec IIVD(Source.size());
+  collectData(IIVD);
+
   TempStream << "\n\nInstruction Info:\n";
   TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n"
              << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects (U)\n";
@@ -36,40 +40,22 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
     TempStream << "\n[1]    [2]    [3]    [4]    [5]    [6]    Instructions:\n";
   }
 
-  for (unsigned I = 0, E = Source.size(); I < E; ++I) {
-    const MCInst &Inst = Source[I];
-    const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());
-
-    // Obtain the scheduling class information from the instruction.
-    unsigned SchedClassID = MCDesc.getSchedClass();
-    unsigned CPUID = SM.getProcessorID();
-
-    // Try to solve variant scheduling classes.
-    while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
-      SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);
-
-    const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
-    unsigned NumMicroOpcodes = SCDesc.NumMicroOps;
-    unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
-    // Add extra latency due to delays in the forwarding data paths.
-    Latency += MCSchedModel::getForwardingDelayCycles(
-        STI.getReadAdvanceEntries(SCDesc));
-    Optional<double> RThroughput =
-        MCSchedModel::getReciprocalThroughput(STI, SCDesc);
+  for (auto I : enumerate(zip(IIVD, Source))) {
+    const InstructionInfoViewData &IIVDEntry = std::get<0>(I.value());
 
-    TempStream << ' ' << NumMicroOpcodes << "    ";
-    if (NumMicroOpcodes < 10)
+    TempStream << ' ' << IIVDEntry.NumMicroOpcodes << "    ";
+    if (IIVDEntry.NumMicroOpcodes < 10)
       TempStream << "  ";
-    else if (NumMicroOpcodes < 100)
+    else if (IIVDEntry.NumMicroOpcodes < 100)
       TempStream << ' ';
-    TempStream << Latency << "   ";
-    if (Latency < 10)
+    TempStream << IIVDEntry.Latency << "   ";
+    if (IIVDEntry.Latency < 10)
       TempStream << "  ";
-    else if (Latency < 100)
+    else if (IIVDEntry.Latency < 100)
       TempStream << ' ';
 
-    if (RThroughput.hasValue()) {
-      double RT = RThroughput.getValue();
+    if (IIVDEntry.RThroughput.hasValue()) {
+      double RT = IIVDEntry.RThroughput.getValue();
       TempStream << format("%.2f", RT) << ' ';
       if (RT < 10.0)
         TempStream << "  ";
@@ -78,12 +64,12 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
     } else {
       TempStream << " -     ";
     }
-    TempStream << (MCDesc.mayLoad() ? " *     " : "       ");
-    TempStream << (MCDesc.mayStore() ? " *     " : "       ");
-    TempStream << (MCDesc.hasUnmodeledSideEffects() ? " U     " : "       ");
+    TempStream << (IIVDEntry.mayLoad ? " *     " : "       ");
+    TempStream << (IIVDEntry.mayStore ? " *     " : "       ");
+    TempStream << (IIVDEntry.hasUnmodeledSideEffects ? " U     " : "       ");
 
     if (PrintEncodings) {
-      StringRef Encoding(CE.getEncoding(I));
+      StringRef Encoding(CE.getEncoding(I.index()));
       unsigned EncodingSize = Encoding.size();
       TempStream << " " << EncodingSize
                  << (EncodingSize < 10 ? "     " : "    ");
@@ -95,6 +81,7 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
       FOS.flush();
     }
 
+    const MCInst &Inst = std::get<1>(I.value());
     MCIP.printInst(&Inst, 0, "", STI, InstrStream);
     InstrStream.flush();
 
@@ -108,5 +95,34 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
   TempStream.flush();
   OS << Buffer;
 }
+
+void InstructionInfoView::collectData(
+    MutableArrayRef<InstructionInfoViewData> IIVD) const {
+  const MCSchedModel &SM = STI.getSchedModel();
+  for (auto I : zip(Source, IIVD)) {
+    const MCInst &Inst = std::get<0>(I);
+    InstructionInfoViewData &IIVDEntry = std::get<1>(I);
+    const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());
+
+    // Obtain the scheduling class information from the instruction.
+    unsigned SchedClassID = MCDesc.getSchedClass();
+    unsigned CPUID = SM.getProcessorID();
+
+    // Try to solve variant scheduling classes.
+    while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
+      SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);
+
+    const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+    IIVDEntry.NumMicroOpcodes = SCDesc.NumMicroOps;
+    IIVDEntry.Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
+    // Add extra latency due to delays in the forwarding data paths.
+    IIVDEntry.Latency += MCSchedModel::getForwardingDelayCycles(
+        STI.getReadAdvanceEntries(SCDesc));
+    IIVDEntry.RThroughput = MCSchedModel::getReciprocalThroughput(STI, SCDesc);
+    IIVDEntry.mayLoad = MCDesc.mayLoad();
+    IIVDEntry.mayStore = MCDesc.mayStore();
+    IIVDEntry.hasUnmodeledSideEffects = MCDesc.hasUnmodeledSideEffects();
+  }
+}
 } // namespace mca.
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/Views/InstructionInfoView.h b/llvm/tools/llvm-mca/Views/InstructionInfoView.h
index 0e948304119f..aca7e5894a89 100644
--- a/llvm/tools/llvm-mca/Views/InstructionInfoView.h
+++ b/llvm/tools/llvm-mca/Views/InstructionInfoView.h
@@ -36,6 +36,7 @@
 
 #include "Views/View.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCInstrInfo.h"
@@ -57,6 +58,19 @@ class InstructionInfoView : public View {
   llvm::ArrayRef<llvm::MCInst> Source;
   llvm::MCInstPrinter &MCIP;
 
+  struct InstructionInfoViewData {
+    unsigned NumMicroOpcodes = 0;
+    unsigned Latency = 0;
+    Optional<double> RThroughput = 0.0;
+    bool mayLoad = false;
+    bool mayStore = false;
+    bool hasUnmodeledSideEffects = false;
+  };
+  using IIVDVec = SmallVector<InstructionInfoViewData, 16>;
+
+  /// Place the data into the array of InstructionInfoViewData IIVD.
+  void collectData(MutableArrayRef<InstructionInfoViewData> IIVD) const;
+
 public:
   InstructionInfoView(const llvm::MCSubtargetInfo &ST,
                       const llvm::MCInstrInfo &II, CodeEmitter &C,

diff  --git a/llvm/tools/llvm-mca/Views/SummaryView.cpp b/llvm/tools/llvm-mca/Views/SummaryView.cpp
index f0e75f7b13ae..e15b1b4cd7a0 100644
--- a/llvm/tools/llvm-mca/Views/SummaryView.cpp
+++ b/llvm/tools/llvm-mca/Views/SummaryView.cpp
@@ -63,32 +63,38 @@ void SummaryView::onEvent(const HWInstructionEvent &Event) {
 }
 
 void SummaryView::printView(raw_ostream &OS) const {
-  unsigned Instructions = Source.size();
-  unsigned Iterations = (LastInstructionIdx / Instructions) + 1;
-  unsigned TotalInstructions = Instructions * Iterations;
-  unsigned TotalUOps = NumMicroOps * Iterations;
-  double IPC = (double)TotalInstructions / TotalCycles;
-  double UOpsPerCycle = (double)TotalUOps / TotalCycles;
-  double BlockRThroughput = computeBlockRThroughput(
-      SM, DispatchWidth, NumMicroOps, ProcResourceUsage);
-
   std::string Buffer;
   raw_string_ostream TempStream(Buffer);
-  TempStream << "Iterations:        " << Iterations;
-  TempStream << "\nInstructions:      " << TotalInstructions;
-  TempStream << "\nTotal Cycles:      " << TotalCycles;
-  TempStream << "\nTotal uOps:        " << TotalUOps << '\n';
-  TempStream << "\nDispatch Width:    " << DispatchWidth;
+  DisplayValues DV;
+
+  collectData(DV);
+  TempStream << "Iterations:        " << DV.Iterations;
+  TempStream << "\nInstructions:      " << DV.TotalInstructions;
+  TempStream << "\nTotal Cycles:      " << DV.TotalCycles;
+  TempStream << "\nTotal uOps:        " << DV.TotalUOps << '\n';
+  TempStream << "\nDispatch Width:    " << DV.DispatchWidth;
   TempStream << "\nuOps Per Cycle:    "
-             << format("%.2f", floor((UOpsPerCycle * 100) + 0.5) / 100);
+             << format("%.2f", floor((DV.UOpsPerCycle * 100) + 0.5) / 100);
   TempStream << "\nIPC:               "
-             << format("%.2f", floor((IPC * 100) + 0.5) / 100);
+             << format("%.2f", floor((DV.IPC * 100) + 0.5) / 100);
   TempStream << "\nBlock RThroughput: "
-             << format("%.1f", floor((BlockRThroughput * 10) + 0.5) / 10)
+             << format("%.1f", floor((DV.BlockRThroughput * 10) + 0.5) / 10)
              << '\n';
   TempStream.flush();
   OS << Buffer;
 }
 
+void SummaryView::collectData(DisplayValues &DV) const {
+  DV.Instructions = Source.size();
+  DV.Iterations = (LastInstructionIdx / DV.Instructions) + 1;
+  DV.TotalInstructions = DV.Instructions * DV.Iterations;
+  DV.TotalCycles = TotalCycles;
+  DV.DispatchWidth = DispatchWidth;
+  DV.TotalUOps = NumMicroOps * DV.Iterations;
+  DV.UOpsPerCycle = (double)DV.TotalUOps / TotalCycles;
+  DV.IPC = (double)DV.TotalInstructions / TotalCycles;
+  DV.BlockRThroughput = computeBlockRThroughput(SM, DispatchWidth, NumMicroOps,
+                                                ProcResourceUsage);
+}
 } // namespace mca.
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/Views/SummaryView.h b/llvm/tools/llvm-mca/Views/SummaryView.h
index 9be31b7d51bd..bc957ea9152b 100644
--- a/llvm/tools/llvm-mca/Views/SummaryView.h
+++ b/llvm/tools/llvm-mca/Views/SummaryView.h
@@ -46,6 +46,18 @@ class SummaryView : public View {
   // The total number of micro opcodes contributed by a block of instructions.
   unsigned NumMicroOps;
 
+  struct DisplayValues {
+    unsigned Instructions;
+    unsigned Iterations;
+    unsigned TotalInstructions;
+    unsigned TotalCycles;
+    unsigned DispatchWidth;
+    unsigned TotalUOps;
+    double IPC;
+    double UOpsPerCycle;
+    double BlockRThroughput;
+  };
+
   // For each processor resource, this vector stores the cumulative number of
   // resource cycles consumed by the analyzed code block.
   llvm::SmallVector<unsigned, 8> ProcResourceUsage;
@@ -65,6 +77,9 @@ class SummaryView : public View {
   //   - Total Resource Cycles / #Units   (for every resource consumed).
   double getBlockRThroughput() const;
 
+  /// Compute the data we want to print out in the object DV.
+  void collectData(DisplayValues &DV) const;
+
 public:
   SummaryView(const llvm::MCSchedModel &Model, llvm::ArrayRef<llvm::MCInst> S,
               unsigned Width);


        


More information about the llvm-commits mailing list