[llvm] 10cb036 - [llvm-mca] Refactor the logic that prints JSON files.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 9 15:02:15 PDT 2021


Author: Andrea Di Biagio
Date: 2021-07-09T22:56:39+01:00
New Revision: 10cb03622325e699d53fbca819e03dca2519f5aa

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

LOG: [llvm-mca] Refactor the logic that prints JSON files.

Moved most of the printing logic into the PipelinePrinter.

This patch also fixes the JSON output when flag -instruction-tables is
specified.

Added: 
    llvm/test/tools/llvm-mca/JSON/X86/instruction-tables-multiple-regions.s

Modified: 
    llvm/tools/llvm-mca/PipelinePrinter.cpp
    llvm/tools/llvm-mca/PipelinePrinter.h
    llvm/tools/llvm-mca/Views/InstructionView.cpp
    llvm/tools/llvm-mca/Views/InstructionView.h
    llvm/tools/llvm-mca/Views/View.cpp
    llvm/tools/llvm-mca/Views/View.h
    llvm/tools/llvm-mca/llvm-mca.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-mca/JSON/X86/instruction-tables-multiple-regions.s b/llvm/test/tools/llvm-mca/JSON/X86/instruction-tables-multiple-regions.s
new file mode 100644
index 0000000000000..3fb320af06cdf
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/JSON/X86/instruction-tables-multiple-regions.s
@@ -0,0 +1,277 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=haswell --json -instruction-tables < %s | FileCheck %s
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=haswell --json -instruction-tables -o %t.json < %s
+# RUN: cat %t.json \
+# RUN:  | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
+# RUN:  | FileCheck %s
+
+# LLVM-MCA-BEGIN foo
+add %eax, %eax
+# LLVM-MCA-BEGIN bar
+add %ebx, %ebx
+add %ecx, %ecx
+# LLVM-MCA-END bar
+add %edx, %edx
+# LLVM-MCA-END foo
+
+# CHECK:      {
+# CHECK-NEXT:   "Resources": {
+# CHECK-NEXT:     "CPUName": "haswell",
+# CHECK-NEXT:     "Resources": [
+# CHECK-NEXT:       "HWDivider",
+# CHECK-NEXT:       "HWFPDivider",
+# CHECK-NEXT:       "HWPort0",
+# CHECK-NEXT:       "HWPort1",
+# CHECK-NEXT:       "HWPort2",
+# CHECK-NEXT:       "HWPort3",
+# CHECK-NEXT:       "HWPort4",
+# CHECK-NEXT:       "HWPort5",
+# CHECK-NEXT:       "HWPort6",
+# CHECK-NEXT:       "HWPort7"
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   },
+# CHECK-NEXT:   "bar": {
+# CHECK-NEXT:     "InstructionInfoView": {
+# CHECK-NEXT:       "InstructionList": [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 0,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 1,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     },
+# CHECK-NEXT:     "Instructions": [
+# CHECK-NEXT:       "addl\t%ebx, %ebx",
+# CHECK-NEXT:       "addl\t%ecx, %ecx"
+# CHECK-NEXT:     ],
+# CHECK-NEXT:     "ResourcePressureView": {
+# CHECK-NEXT:       "ResourcePressureInfo": [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.5
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.5
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.5
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.5
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   },
+# CHECK-NEXT:   "foo": {
+# CHECK-NEXT:     "InstructionInfoView": {
+# CHECK-NEXT:       "InstructionList": [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 0,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 1,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 2,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "Instruction": 3,
+# CHECK-NEXT:           "Latency": 1,
+# CHECK-NEXT:           "NumMicroOpcodes": 1,
+# CHECK-NEXT:           "RThroughput": 0.25,
+# CHECK-NEXT:           "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:           "mayLoad": false,
+# CHECK-NEXT:           "mayStore": false
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     },
+# CHECK-NEXT:     "Instructions": [
+# CHECK-NEXT:       "addl\t%eax, %eax",
+# CHECK-NEXT:       "addl\t%ebx, %ebx",
+# CHECK-NEXT:       "addl\t%ecx, %ecx",
+# CHECK-NEXT:       "addl\t%edx, %edx"
+# CHECK-NEXT:     ],
+# CHECK-NEXT:     "ResourcePressureView": {
+# CHECK-NEXT:       "ResourcePressureInfo": [
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 0,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 1,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 2,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 3,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 3,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 3,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 3,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 0.25
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 4,
+# CHECK-NEXT:           "ResourceIndex": 2,
+# CHECK-NEXT:           "ResourceUsage": 1
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 4,
+# CHECK-NEXT:           "ResourceIndex": 3,
+# CHECK-NEXT:           "ResourceUsage": 1
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 4,
+# CHECK-NEXT:           "ResourceIndex": 7,
+# CHECK-NEXT:           "ResourceUsage": 1
+# CHECK-NEXT:         },
+# CHECK-NEXT:         {
+# CHECK-NEXT:           "InstructionIndex": 4,
+# CHECK-NEXT:           "ResourceIndex": 8,
+# CHECK-NEXT:           "ResourceUsage": 1
+# CHECK-NEXT:         }
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT: }

diff  --git a/llvm/tools/llvm-mca/PipelinePrinter.cpp b/llvm/tools/llvm-mca/PipelinePrinter.cpp
index 0bae7f1f7a6da..ba491c3807138 100644
--- a/llvm/tools/llvm-mca/PipelinePrinter.cpp
+++ b/llvm/tools/llvm-mca/PipelinePrinter.cpp
@@ -12,26 +12,56 @@
 //===----------------------------------------------------------------------===//
 
 #include "PipelinePrinter.h"
+#include "CodeRegion.h"
+#include "Views/InstructionView.h"
 #include "Views/View.h"
 
 namespace llvm {
 namespace mca {
 
+void PipelinePrinter::printRegionHeader(llvm::raw_ostream &OS) const {
+  StringRef RegionName;
+  if (!Region.getDescription().empty())
+    RegionName = Region.getDescription();
+
+  OS << "\n[" << RegionIdx << "] Code Region";
+  if (!RegionName.empty())
+    OS << " - " << RegionName;
+  OS << "\n\n";
+}
+
 json::Object PipelinePrinter::getJSONReportRegion() const {
   json::Object JO;
-  for (const auto &V : Views) {
-    if (V->isSerializable()) {
+
+  for (const auto &V : Views)
+    if (V->isSerializable())
       JO.try_emplace(V->getNameAsString().str(), V->toJSON());
-    }
-  }
+
   return JO;
 }
 
+void PipelinePrinter::printReport(json::Object &JO) const {
+  if (!RegionIdx)
+    JO.try_emplace("Resources", InstructionView::getJSONTargetInfo(STI));
+
+  StringRef RegionName;
+  if (Region.getDescription().empty())
+    RegionName = "main";
+  else
+    RegionName = Region.getDescription();
+
+  JO.try_emplace(RegionName, getJSONReportRegion());
+}
+
 void PipelinePrinter::printReport(llvm::raw_ostream &OS) const {
-  json::Object JO;
-  for (const auto &V : Views) {
+  // Don't print the header of this region if it is the default region, and if
+  // it doesn't have an end location.
+  if (Region.startLoc().isValid() || Region.endLoc().isValid())
+    printRegionHeader(OS);
+
+  for (const auto &V : Views)
     V->printView(OS);
-  }
 }
-} // namespace mca.
+
+} // namespace mca
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/PipelinePrinter.h b/llvm/tools/llvm-mca/PipelinePrinter.h
index aadb80af86b52..1451813d58232 100644
--- a/llvm/tools/llvm-mca/PipelinePrinter.h
+++ b/llvm/tools/llvm-mca/PipelinePrinter.h
@@ -18,6 +18,7 @@
 
 #include "Views/View.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MCA/Pipeline.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -26,6 +27,8 @@
 namespace llvm {
 namespace mca {
 
+class CodeRegion;
+
 /// A printer class that knows how to collects statistics on the
 /// code analyzed by the llvm-mca tool.
 ///
@@ -35,10 +38,18 @@ namespace mca {
 /// resource pressure.
 class PipelinePrinter {
   Pipeline &P;
+  const CodeRegion &Region;
+  unsigned RegionIdx;
+  const MCSubtargetInfo &STI;
   llvm::SmallVector<std::unique_ptr<View>, 8> Views;
 
+  void printRegionHeader(llvm::raw_ostream &OS) const;
+  json::Object getJSONReportRegion() const;
+
 public:
-  PipelinePrinter(Pipeline &pipeline) : P(pipeline) {}
+  PipelinePrinter(Pipeline &Pipe, const CodeRegion &R, unsigned Idx,
+                  const MCSubtargetInfo &STI)
+      : P(Pipe), Region(R), RegionIdx(Idx), STI(STI), Views() {}
 
   void addView(std::unique_ptr<View> V) {
     P.addEventListener(V.get());
@@ -46,7 +57,7 @@ class PipelinePrinter {
   }
 
   void printReport(llvm::raw_ostream &OS) const;
-  json::Object getJSONReportRegion() const;
+  void printReport(json::Object &JO) const;
 };
 } // namespace mca
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/Views/InstructionView.cpp b/llvm/tools/llvm-mca/Views/InstructionView.cpp
index 176cdba734bcd..2e3c08bf7cca9 100644
--- a/llvm/tools/llvm-mca/Views/InstructionView.cpp
+++ b/llvm/tools/llvm-mca/Views/InstructionView.cpp
@@ -19,6 +19,8 @@
 namespace llvm {
 namespace mca {
 
+InstructionView::~InstructionView() = default;
+
 StringRef InstructionView::printInstructionString(const llvm::MCInst &MCI) const {
   InstructionString = "";
   MCIP.printInst(&MCI, 0, "", STI, InstrStream);
@@ -36,9 +38,11 @@ json::Value InstructionView::toJSON() const {
   return SourceInfo;
 }
 
-json::Object InstructionView::getJSONResources() const {
+json::Object InstructionView::getJSONTargetInfo(const MCSubtargetInfo &STI) {
   json::Array Resources;
   const MCSchedModel &SM = STI.getSchedModel();
+  StringRef MCPU = STI.getCPU();
+
   for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
     const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
     unsigned NumUnits = ProcResource.NumUnits;

diff  --git a/llvm/tools/llvm-mca/Views/InstructionView.h b/llvm/tools/llvm-mca/Views/InstructionView.h
index 6f092368d6d01..c396fb37c5a12 100644
--- a/llvm/tools/llvm-mca/Views/InstructionView.h
+++ b/llvm/tools/llvm-mca/Views/InstructionView.h
@@ -28,7 +28,6 @@ class InstructionView : public View {
   const llvm::MCSubtargetInfo &STI;
   llvm::MCInstPrinter &MCIP;
   llvm::ArrayRef<llvm::MCInst> Source;
-  StringRef MCPU;
 
   mutable std::string InstructionString;
   mutable raw_string_ostream InstrStream;
@@ -37,12 +36,10 @@ class InstructionView : public View {
   void printView(llvm::raw_ostream &) const override {}
   InstructionView(const llvm::MCSubtargetInfo &STI,
                   llvm::MCInstPrinter &Printer,
-                  llvm::ArrayRef<llvm::MCInst> S,
-                  StringRef MCPU = StringRef())
-      : STI(STI), MCIP(Printer), Source(S), MCPU(MCPU),
-        InstrStream(InstructionString) {}
+                  llvm::ArrayRef<llvm::MCInst> S)
+      : STI(STI), MCIP(Printer), Source(S), InstrStream(InstructionString) {}
 
-  virtual ~InstructionView() = default;
+  virtual ~InstructionView();
 
   StringRef getNameAsString() const override {
     return "Instructions";
@@ -56,11 +53,12 @@ class InstructionView : public View {
   llvm::MCInstPrinter &getInstPrinter() const { return MCIP; }
   llvm::ArrayRef<llvm::MCInst> getSource() const { return Source; }
   json::Value toJSON() const override;
-  json::Object getJSONResources() const;
   virtual void printViewJSON(llvm::raw_ostream &OS) override {
     json::Value JV = toJSON();
     OS << formatv("{0:2}", JV) << "\n";
   }
+
+  static json::Object getJSONTargetInfo(const llvm::MCSubtargetInfo &STI);
 };
 } // namespace mca
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/Views/View.cpp b/llvm/tools/llvm-mca/Views/View.cpp
index 09d08d3ae0075..79abd3b506497 100644
--- a/llvm/tools/llvm-mca/Views/View.cpp
+++ b/llvm/tools/llvm-mca/Views/View.cpp
@@ -20,5 +20,12 @@ namespace mca {
 
 void View::anchor() {}
 
+void View::printViewJSON(llvm::raw_ostream &OS) {
+  json::Object JO;
+  JO.try_emplace(getNameAsString().str(), toJSON());
+  OS << formatv("{0:2}", json::Value(std::move(JO))) << "\n";
+}
+
+
 } // namespace mca
 } // namespace llvm

diff  --git a/llvm/tools/llvm-mca/Views/View.h b/llvm/tools/llvm-mca/Views/View.h
index 8eeb25d21dbfa..2b578c11d4f2a 100644
--- a/llvm/tools/llvm-mca/Views/View.h
+++ b/llvm/tools/llvm-mca/Views/View.h
@@ -25,23 +25,12 @@ namespace mca {
 
 class View : public HWEventListener {
 public:
-  enum OutputKind { OK_READABLE, OK_JSON };
-
-  void printView(OutputKind OutputKind, llvm::raw_ostream &OS) {
-    if (OutputKind == OK_JSON)
-      printViewJSON(OS);
-    else
-      printView(OS);
-  }
+  virtual ~View() = default;
 
   virtual void printView(llvm::raw_ostream &OS) const = 0;
-  virtual void printViewJSON(llvm::raw_ostream &OS) {
-    json::Object JO;
-    JO.try_emplace(getNameAsString().str(), toJSON());
-    OS << formatv("{0:2}", json::Value(std::move(JO))) << "\n";
-  }
-  virtual ~View() = default;
   virtual StringRef getNameAsString() const = 0;
+
+  virtual void printViewJSON(llvm::raw_ostream &OS);
   virtual json::Value toJSON() const { return "not implemented"; }
   virtual bool isSerializable() const { return true; }
   void anchor() override;

diff  --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index a4c952809302c..0f1e74baaefc6 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/tools/llvm-mca/llvm-mca.cpp
@@ -529,16 +529,7 @@ int main(int argc, char **argv) {
     if (Region->empty())
       continue;
 
-    // Don't print the header of this region if it is the default region, and
-    // it doesn't have an end location.
-    if (!PrintJson &&
-        (Region->startLoc().isValid() || Region->endLoc().isValid())) {
-      TOF->os() << "\n[" << RegionIdx++ << "] Code Region";
-      StringRef Desc = Region->getDescription();
-      if (!Desc.empty())
-        TOF->os() << " - " << Desc;
-      TOF->os() << "\n\n";
-    }
+    IB.clear();
 
     // Lower the MCInst sequence into an mca::Instruction sequence.
     ArrayRef<MCInst> Insts = Region->getInstructions();
@@ -579,7 +570,12 @@ int main(int argc, char **argv) {
       auto P = std::make_unique<mca::Pipeline>();
       P->appendStage(std::make_unique<mca::EntryStage>(S));
       P->appendStage(std::make_unique<mca::InstructionTables>(SM));
-      mca::PipelinePrinter Printer(*P);
+
+      mca::PipelinePrinter Printer(*P, *Region, RegionIdx, *STI);
+      if (PrintJson) {
+        auto IV = std::make_unique<mca::InstructionView>(*STI, *IP, Insts);
+        Printer.addView(std::move(IV));
+      }
 
       // Create the views for this pipeline, execute, and emit a report.
       if (PrintInstructionInfoView) {
@@ -593,13 +589,12 @@ int main(int argc, char **argv) {
         return 1;
 
       if (PrintJson) {
-        JSONOutput.try_emplace(!Region->getDescription().empty()
-                                   ? Region->getDescription().str()
-                                   : "main",
-                               Printer.getJSONReportRegion());
+        Printer.printReport(JSONOutput);
       } else {
         Printer.printReport(TOF->os());
       }
+
+      ++RegionIdx;
       continue;
     }
 
@@ -614,15 +609,13 @@ int main(int argc, char **argv) {
 
     // Create a basic pipeline simulating an out-of-order backend.
     auto P = MCA.createDefaultPipeline(PO, S, *CB);
-    mca::PipelinePrinter Printer(*P);
+
+    mca::PipelinePrinter Printer(*P, *Region, RegionIdx, *STI);
 
     // When we output JSON, we add a view that contains the instructions
     // and CPU resource information.
     if (PrintJson) {
-      auto IV = std::make_unique<mca::InstructionView>(*STI, *IP, Insts, MCPU);
-      if (JSONOutput.find("Resources") == JSONOutput.end()) {
-        JSONOutput.try_emplace("Resources", IV->getJSONResources());
-      }
+      auto IV = std::make_unique<mca::InstructionView>(*STI, *IP, Insts);
       Printer.addView(std::move(IV));
     }
 
@@ -672,16 +665,12 @@ int main(int argc, char **argv) {
       return 1;
 
     if (PrintJson) {
-      JSONOutput.try_emplace(!Region->getDescription().empty()
-                                 ? Region->getDescription().str()
-                                 : "main",
-                             Printer.getJSONReportRegion());
+      Printer.printReport(JSONOutput);
     } else {
       Printer.printReport(TOF->os());
     }
 
-    // Clear the InstrBuilder internal state in preparation for another round.
-    IB.clear();
+    ++RegionIdx;
   }
 
   if (PrintJson)


        


More information about the llvm-commits mailing list