blob: 511aefa8864bfbb39a82157da4e793b5535c6517 [file] [log] [blame]
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00001//===--------------------- BackendPrinter.cpp -------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10///
11/// This file implements the BackendPrinter interface.
12///
13//===----------------------------------------------------------------------===//
14
15#include "BackendPrinter.h"
16#include "llvm/CodeGen/TargetSchedule.h"
17
18namespace mca {
19
20using namespace llvm;
21
22std::unique_ptr<ToolOutputFile>
23BackendPrinter::getOutputStream(std::string OutputFile) {
24 if (OutputFile == "")
25 OutputFile = "-";
26 std::error_code EC;
27 auto Out = llvm::make_unique<ToolOutputFile>(OutputFile, EC, sys::fs::F_None);
28 if (!EC)
29 return Out;
30 errs() << EC.message() << '\n';
31 return nullptr;
32}
33
34void BackendPrinter::printGeneralStatistics(unsigned Iterations,
35 unsigned Cycles,
36 unsigned Instructions,
37 unsigned DispatchWidth) const {
38 unsigned TotalInstructions = Instructions * Iterations;
39 double IPC = (double)TotalInstructions / Cycles;
40
41 std::string Buffer;
42 raw_string_ostream TempStream(Buffer);
43 TempStream << "Iterations: " << Iterations;
44 TempStream << "\nInstructions: " << TotalInstructions;
45 TempStream << "\nTotal Cycles: " << Cycles;
46 TempStream << "\nDispatch Width: " << DispatchWidth;
47 TempStream << "\nIPC: " << format("%.2f", IPC) << '\n';
48 TempStream.flush();
49 File->os() << Buffer;
50}
51
52void BackendPrinter::printRATStatistics(unsigned TotalMappings,
53 unsigned MaxUsedMappings) const {
54 std::string Buffer;
55 raw_string_ostream TempStream(Buffer);
56 TempStream << "\n\nRegister Alias Table:";
57 TempStream << "\nTotal number of mappings created: " << TotalMappings;
58 TempStream << "\nMax number of mappings used: " << MaxUsedMappings
59 << '\n';
60 TempStream.flush();
61 File->os() << Buffer;
62}
63
64void BackendPrinter::printDispatchStalls(unsigned RATStalls, unsigned RCUStalls,
65 unsigned SCHEDQStalls,
66 unsigned LDQStalls, unsigned STQStalls,
67 unsigned DGStalls) const {
68 std::string Buffer;
69 raw_string_ostream TempStream(Buffer);
70 TempStream << "\n\nDynamic Dispatch Stall Cycles:\n";
71 TempStream << "RAT - Register unavailable: "
72 << RATStalls;
73 TempStream << "\nRCU - Retire tokens unavailable: "
74 << RCUStalls;
75 TempStream << "\nSCHEDQ - Scheduler full: "
76 << SCHEDQStalls;
77 TempStream << "\nLQ - Load queue full: "
78 << LDQStalls;
79 TempStream << "\nSQ - Store queue full: "
80 << STQStalls;
81 TempStream << "\nGROUP - Static restrictions on the dispatch group: "
82 << DGStalls;
83 TempStream << '\n';
84 TempStream.flush();
85 File->os() << Buffer;
86}
87
88void BackendPrinter::printSchedulerUsage(
89 const MCSchedModel &SM, const ArrayRef<BufferUsageEntry> &Usage) const {
90 std::string Buffer;
91 raw_string_ostream TempStream(Buffer);
92 TempStream << "\n\nScheduler's queue usage:\n";
93 const ArrayRef<uint64_t> ResourceMasks = B.getProcResourceMasks();
94 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
95 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
96 if (!ProcResource.BufferSize)
97 continue;
98
99 for (const BufferUsageEntry &Entry : Usage)
100 if (ResourceMasks[I] == Entry.first)
101 TempStream << ProcResource.Name << ", " << Entry.second << '/'
102 << ProcResource.BufferSize << '\n';
103 }
104
105 TempStream.flush();
106 File->os() << Buffer;
107}
108
109void BackendPrinter::printInstructionInfo() const {
110 std::string Buffer;
111 raw_string_ostream TempStream(Buffer);
112
113 TempStream << "\n\nInstruction Info:\n";
114 TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n"
115 << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects\n\n";
116
117 TempStream << "[1] [2] [3] [4] [5] [6]\tInstructions:\n";
118 for (unsigned I = 0, E = B.getNumInstructions(); I < E; ++I) {
119 const MCInst &Inst = B.getMCInstFromIndex(I);
120 const InstrDesc &ID = B.getInstrDesc(Inst);
121 unsigned NumMicroOpcodes = ID.NumMicroOps;
122 unsigned Latency = ID.MaxLatency;
123 double RThroughput = B.getRThroughput(ID);
124 TempStream << ' ' << NumMicroOpcodes << " ";
125 if (NumMicroOpcodes < 10)
126 TempStream << " ";
127 else if (NumMicroOpcodes < 100)
128 TempStream << ' ';
129 TempStream << Latency << " ";
130 if (Latency < 10.0)
131 TempStream << " ";
132 else if (Latency < 100.0)
133 TempStream << ' ';
134 if (RThroughput) {
135 TempStream << format("%.2f", RThroughput) << ' ';
136 if (RThroughput < 10.0)
137 TempStream << " ";
138 else if (RThroughput < 100.0)
139 TempStream << ' ';
140 } else {
141 TempStream << " - ";
142 }
143 TempStream << (ID.MayLoad ? " * " : " ");
144 TempStream << (ID.MayStore ? " * " : " ");
145 TempStream << (ID.HasSideEffects ? " * " : " ");
146 MCIP->printInst(&Inst, TempStream, "", B.getSTI());
147 TempStream << '\n';
148 }
149
150 TempStream.flush();
151 File->os() << Buffer;
152}
153
154void BackendPrinter::printReport() const {
155 assert(isFileValid());
156 unsigned Cycles = B.getNumCycles();
157 printGeneralStatistics(B.getNumIterations(), Cycles, B.getNumInstructions(),
158 B.getDispatchWidth());
159 if (EnableVerboseOutput) {
160 printDispatchStalls(B.getNumRATStalls(), B.getNumRCUStalls(),
161 B.getNumSQStalls(), B.getNumLDQStalls(),
162 B.getNumSTQStalls(), B.getNumDispatchGroupStalls());
163 printRATStatistics(B.getTotalRegisterMappingsCreated(),
164 B.getMaxUsedRegisterMappings());
165 BS->printHistograms(File->os());
166
167 std::vector<BufferUsageEntry> Usage;
168 B.getBuffersUsage(Usage);
169 printSchedulerUsage(B.getSchedModel(), Usage);
170 }
171
172 if (RPV) {
173 RPV->printResourcePressure(getOStream(), Cycles);
174 printInstructionInfo();
175 }
176
177 if (TV) {
178 TV->printTimeline(getOStream());
179 TV->printAverageWaitTimes(getOStream());
180 }
181}
182
183void BackendPrinter::addResourcePressureView() {
184 if (!RPV) {
185 RPV = llvm::make_unique<ResourcePressureView>(
186 B.getSTI(), *MCIP, B.getSourceMgr(), B.getProcResourceMasks());
187 B.addEventListener(RPV.get());
188 }
189}
190
191void BackendPrinter::addTimelineView(unsigned MaxIterations,
192 unsigned MaxCycles) {
193 if (!TV) {
194 TV = llvm::make_unique<TimelineView>(B.getSTI(), *MCIP, B.getSourceMgr(),
195 MaxIterations, MaxCycles);
196 B.addEventListener(TV.get());
197 }
198}
199
200void BackendPrinter::initialize(std::string OutputFileName) {
201 File = getOutputStream(OutputFileName);
202 MCIP->setPrintImmHex(false);
203 if (EnableVerboseOutput) {
204 BS = llvm::make_unique<BackendStatistics>();
205 B.addEventListener(BS.get());
206 }
207}
208
209} // namespace mca.