1 //===--------------------- PipelinePrinter.cpp ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file implements the PipelinePrinter interface.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "PipelinePrinter.h"
15 #include "CodeRegion.h"
16 #include "Views/InstructionView.h"
17 #include "Views/View.h"
18 
19 namespace llvm {
20 namespace mca {
21 
printRegionHeader(llvm::raw_ostream & OS) const22 void PipelinePrinter::printRegionHeader(llvm::raw_ostream &OS) const {
23   StringRef RegionName;
24   if (!Region.getDescription().empty())
25     RegionName = Region.getDescription();
26 
27   OS << "\n[" << RegionIdx << "] Code Region";
28   if (!RegionName.empty())
29     OS << " - " << RegionName;
30   OS << "\n\n";
31 }
32 
getJSONReportRegion() const33 json::Object PipelinePrinter::getJSONReportRegion() const {
34   json::Object JO;
35 
36   StringRef RegionName = "";
37   if (!Region.getDescription().empty())
38     RegionName = Region.getDescription();
39 
40   JO.try_emplace("Name", RegionName);
41   for (const auto &V : Views)
42     if (V->isSerializable())
43       JO.try_emplace(V->getNameAsString().str(), V->toJSON());
44 
45   return JO;
46 }
47 
getJSONSimulationParameters() const48 json::Object PipelinePrinter::getJSONSimulationParameters() const {
49   json::Object SimParameters({{"-mcpu", STI.getCPU()},
50                               {"-mtriple", STI.getTargetTriple().getTriple()},
51                               {"-march", STI.getTargetTriple().getArchName()}});
52 
53   const MCSchedModel &SM = STI.getSchedModel();
54   if (!SM.isOutOfOrder())
55     return SimParameters;
56 
57   if (PO.RegisterFileSize)
58     SimParameters.try_emplace("-register-file-size", PO.RegisterFileSize);
59 
60   if (!PO.AssumeNoAlias)
61     SimParameters.try_emplace("-noalias", PO.AssumeNoAlias);
62 
63   if (PO.DecodersThroughput)
64     SimParameters.try_emplace("-decoder-throughput", PO.DecodersThroughput);
65 
66   if (PO.MicroOpQueueSize)
67     SimParameters.try_emplace("-micro-op-queue-size", PO.MicroOpQueueSize);
68 
69   if (PO.DispatchWidth)
70     SimParameters.try_emplace("-dispatch", PO.DispatchWidth);
71 
72   if (PO.LoadQueueSize)
73     SimParameters.try_emplace("-lqueue", PO.LoadQueueSize);
74 
75   if (PO.StoreQueueSize)
76     SimParameters.try_emplace("-squeue", PO.StoreQueueSize);
77 
78   return SimParameters;
79 }
80 
getJSONTargetInfo() const81 json::Object PipelinePrinter::getJSONTargetInfo() const {
82   json::Array Resources;
83   const MCSchedModel &SM = STI.getSchedModel();
84   StringRef MCPU = STI.getCPU();
85 
86   for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
87     const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
88     unsigned NumUnits = ProcResource.NumUnits;
89     if (ProcResource.SubUnitsIdxBegin || !NumUnits)
90       continue;
91 
92     for (unsigned J = 0; J < NumUnits; ++J) {
93       std::string ResourceName = ProcResource.Name;
94       if (NumUnits > 1) {
95         ResourceName += ".";
96         ResourceName += J;
97       }
98 
99       Resources.push_back(ResourceName);
100     }
101   }
102 
103   return json::Object({{"CPUName", MCPU}, {"Resources", std::move(Resources)}});
104 }
105 
printReport(json::Object & JO) const106 void PipelinePrinter::printReport(json::Object &JO) const {
107   if (!RegionIdx) {
108     JO.try_emplace("TargetInfo", getJSONTargetInfo());
109     JO.try_emplace("SimulationParameters", getJSONSimulationParameters());
110     // Construct an array of regions.
111     JO.try_emplace("CodeRegions", json::Array());
112   }
113 
114   json::Array *Regions = JO.getArray("CodeRegions");
115   assert(Regions && "This array must exist!");
116   Regions->push_back(getJSONReportRegion());
117 }
118 
printReport(llvm::raw_ostream & OS) const119 void PipelinePrinter::printReport(llvm::raw_ostream &OS) const {
120   // Don't print the header of this region if it is the default region, and if
121   // it doesn't have an end location.
122   if (Region.startLoc().isValid() || Region.endLoc().isValid())
123     printRegionHeader(OS);
124 
125   for (const auto &V : Views)
126     V->printView(OS);
127 }
128 
129 } // namespace mca
130 } // namespace llvm
131