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
18namespace llvm {
19namespace mca {
20
21void PipelinePrinter::printRegionHeader(llvm::raw_ostream &OS) const {
22 StringRef RegionName;
23 if (!Region.getDescription().empty())
24 RegionName = Region.getDescription();
25
26 OS << "\n[" << RegionIdx << "] Code Region";
27 if (!RegionName.empty())
28 OS << " - " << RegionName;
29 OS << "\n\n";
30}
31
32json::Object PipelinePrinter::getJSONReportRegion() const {
33 json::Object JO;
34
35 StringRef RegionName = "";
36 if (!Region.getDescription().empty())
37 RegionName = Region.getDescription();
38
39 JO.try_emplace(K: "Name", Args&: RegionName);
40 for (const auto &V : Views)
41 if (V->isSerializable())
42 JO.try_emplace(K: V->getNameAsString().str(), Args: V->toJSON());
43
44 return JO;
45}
46
47json::Object PipelinePrinter::getJSONSimulationParameters() const {
48 json::Object SimParameters({{.K: "-mcpu", .V: STI.getCPU()},
49 {.K: "-mtriple", .V: STI.getTargetTriple().getTriple()},
50 {.K: "-march", .V: STI.getTargetTriple().getArchName()}});
51
52 const MCSchedModel &SM = STI.getSchedModel();
53 if (!SM.isOutOfOrder())
54 return SimParameters;
55
56 if (PO.RegisterFileSize)
57 SimParameters.try_emplace(K: "-register-file-size", Args: PO.RegisterFileSize);
58
59 if (!PO.AssumeNoAlias)
60 SimParameters.try_emplace(K: "-noalias", Args: PO.AssumeNoAlias);
61
62 if (PO.DecodersThroughput)
63 SimParameters.try_emplace(K: "-decoder-throughput", Args: PO.DecodersThroughput);
64
65 if (PO.MicroOpQueueSize)
66 SimParameters.try_emplace(K: "-micro-op-queue-size", Args: PO.MicroOpQueueSize);
67
68 if (PO.DispatchWidth)
69 SimParameters.try_emplace(K: "-dispatch", Args: PO.DispatchWidth);
70
71 if (PO.LoadQueueSize)
72 SimParameters.try_emplace(K: "-lqueue", Args: PO.LoadQueueSize);
73
74 if (PO.StoreQueueSize)
75 SimParameters.try_emplace(K: "-squeue", Args: PO.StoreQueueSize);
76
77 return SimParameters;
78}
79
80json::Object PipelinePrinter::getJSONTargetInfo() const {
81 json::Array Resources;
82 const MCSchedModel &SM = STI.getSchedModel();
83 StringRef MCPU = STI.getCPU();
84
85 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
86 const MCProcResourceDesc &ProcResource = *SM.getProcResource(ProcResourceIdx: I);
87 unsigned NumUnits = ProcResource.NumUnits;
88 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
89 continue;
90
91 for (unsigned J = 0; J < NumUnits; ++J) {
92 std::string ResourceName = ProcResource.Name;
93 if (NumUnits > 1) {
94 ResourceName += ".";
95 ResourceName += J;
96 }
97
98 Resources.push_back(E: ResourceName);
99 }
100 }
101
102 return json::Object({{.K: "CPUName", .V: MCPU}, {.K: "Resources", .V: std::move(Resources)}});
103}
104
105void PipelinePrinter::printReport(json::Object &JO) const {
106 if (!RegionIdx) {
107 JO.try_emplace(K: "TargetInfo", Args: getJSONTargetInfo());
108 JO.try_emplace(K: "SimulationParameters", Args: getJSONSimulationParameters());
109 // Construct an array of regions.
110 JO.try_emplace(K: "CodeRegions", Args: json::Array());
111 }
112
113 json::Array *Regions = JO.getArray(K: "CodeRegions");
114 assert(Regions && "This array must exist!");
115 Regions->push_back(E: getJSONReportRegion());
116}
117
118void PipelinePrinter::printReport(llvm::raw_ostream &OS) const {
119 // Don't print the header of this region if it is the default region, and if
120 // it doesn't have an end location.
121 if (Region.startLoc().isValid() || Region.endLoc().isValid())
122 printRegionHeader(OS);
123
124 for (const auto &V : Views)
125 V->printView(OS);
126}
127
128} // namespace mca
129} // namespace llvm
130