From 10cb03622325e699d53fbca819e03dca2519f5aa Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Fri, 9 Jul 2021 22:35:12 +0100 Subject: [PATCH] [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. --- .../X86/instruction-tables-multiple-regions.s | 277 ++++++++++++++++++ llvm/tools/llvm-mca/PipelinePrinter.cpp | 50 +++- llvm/tools/llvm-mca/PipelinePrinter.h | 15 +- llvm/tools/llvm-mca/Views/InstructionView.cpp | 6 +- llvm/tools/llvm-mca/Views/InstructionView.h | 12 +- llvm/tools/llvm-mca/Views/View.cpp | 7 + llvm/tools/llvm-mca/Views/View.h | 17 +- llvm/tools/llvm-mca/llvm-mca.cpp | 41 +-- 8 files changed, 365 insertions(+), 60 deletions(-) create mode 100644 llvm/test/tools/llvm-mca/JSON/X86/instruction-tables-multiple-regions.s 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 000000000000..3fb320af06cd --- /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 0bae7f1f7a6d..ba491c380713 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(llvm::raw_ostream &OS) const { - json::Object JO; - for (const auto &V : Views) { - V->printView(OS); - } +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()); } -} // namespace mca. + +void PipelinePrinter::printReport(llvm::raw_ostream &OS) const { + // 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 llvm diff --git a/llvm/tools/llvm-mca/PipelinePrinter.h b/llvm/tools/llvm-mca/PipelinePrinter.h index aadb80af86b5..1451813d5823 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, 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 V) { P.addEventListener(V.get()); @@ -46,7 +57,7 @@ public: } 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 176cdba734bc..2e3c08bf7cca 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 6f092368d6d0..c396fb37c5a1 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 Source; - StringRef MCPU; mutable std::string InstructionString; mutable raw_string_ostream InstrStream; @@ -37,12 +36,10 @@ public: void printView(llvm::raw_ostream &) const override {} InstructionView(const llvm::MCSubtargetInfo &STI, llvm::MCInstPrinter &Printer, - llvm::ArrayRef S, - StringRef MCPU = StringRef()) - : STI(STI), MCIP(Printer), Source(S), MCPU(MCPU), - InstrStream(InstructionString) {} + llvm::ArrayRef S) + : STI(STI), MCIP(Printer), Source(S), InstrStream(InstructionString) {} - virtual ~InstructionView() = default; + virtual ~InstructionView(); StringRef getNameAsString() const override { return "Instructions"; @@ -56,11 +53,12 @@ public: llvm::MCInstPrinter &getInstPrinter() const { return MCIP; } llvm::ArrayRef 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 09d08d3ae007..79abd3b50649 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 8eeb25d21dbf..2b578c11d4f2 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 a4c952809302..0f1e74baaefc 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 Insts = Region->getInstructions(); @@ -579,7 +570,12 @@ int main(int argc, char **argv) { auto P = std::make_unique(); P->appendStage(std::make_unique(S)); P->appendStage(std::make_unique(SM)); - mca::PipelinePrinter Printer(*P); + + mca::PipelinePrinter Printer(*P, *Region, RegionIdx, *STI); + if (PrintJson) { + auto IV = std::make_unique(*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(*STI, *IP, Insts, MCPU); - if (JSONOutput.find("Resources") == JSONOutput.end()) { - JSONOutput.try_emplace("Resources", IV->getJSONResources()); - } + auto IV = std::make_unique(*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)