diff options
author | Andrea Di Biagio <andrea.dibiagio@sony.com> | 2021-07-09 22:35:12 +0100 |
---|---|---|
committer | Andrea Di Biagio <andrea.dibiagio@sony.com> | 2021-07-09 22:56:39 +0100 |
commit | 10cb03622325e699d53fbca819e03dca2519f5aa (patch) | |
tree | cc8bc691e060665e5b2873e8ecb5010150ffd64c /llvm/tools/llvm-mca | |
parent | f3e6c3f327c278da27e5a3919f22719d128d8cc4 (diff) | |
download | llvm-10cb03622325e699d53fbca819e03dca2519f5aa.zip llvm-10cb03622325e699d53fbca819e03dca2519f5aa.tar.gz llvm-10cb03622325e699d53fbca819e03dca2519f5aa.tar.bz2 |
[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.
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r-- | llvm/tools/llvm-mca/PipelinePrinter.cpp | 46 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/PipelinePrinter.h | 15 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/Views/InstructionView.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/Views/InstructionView.h | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/Views/View.cpp | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/Views/View.h | 17 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/llvm-mca.cpp | 41 |
7 files changed, 86 insertions, 58 deletions
diff --git a/llvm/tools/llvm-mca/PipelinePrinter.cpp b/llvm/tools/llvm-mca/PipelinePrinter.cpp index 0bae7f1..ba491c3 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 aadb80a..1451813 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 @@ 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 176cdba..2e3c08b 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 6f09236..c396fb3 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 @@ public: 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 @@ public: 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 09d08d3..79abd3b 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 8eeb25d..2b578c1 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 a4c9528..0f1e74b 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) |