blob: c5425509064efe3cc87af246ab55145affa7fa5d [file] [log] [blame]
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00001//===--------------------- BackendStatistics.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
Andrea Di Biagio53e6ade2018-03-09 12:50:42 +000010///
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000011/// Functionalities used by the BackendPrinter to print out histograms
12/// related to number of {dispatch/issue/retire} per number of cycles.
13///
14//===----------------------------------------------------------------------===//
15
16#include "BackendStatistics.h"
17#include "llvm/Support/Format.h"
18
19using namespace llvm;
20
21namespace mca {
22
Clement Courbet844f22d2018-03-13 13:11:01 +000023void BackendStatistics::onInstructionEvent(const HWInstructionEvent &Event) {
24 switch (Event.Type) {
Andrea Di Biagio12ef5262018-03-21 18:11:05 +000025 default:
26 break;
27 case HWInstructionEvent::Retired: {
28 const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event);
29 for (unsigned I = 0, E = RegisterFiles.size(); I < E; ++I)
30 RegisterFiles[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I];
31
Clement Courbet844f22d2018-03-13 13:11:01 +000032 ++NumRetired;
33 break;
Andrea Di Biagio12ef5262018-03-21 18:11:05 +000034 }
Clement Courbet844f22d2018-03-13 13:11:01 +000035 case HWInstructionEvent::Issued:
36 ++NumIssued;
37 break;
Andrea Di Biagio12ef5262018-03-21 18:11:05 +000038 case HWInstructionEvent::Dispatched: {
39 const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event);
40 for (unsigned I = 0, E = RegisterFiles.size(); I < E; ++I) {
41 RegisterFileUsage &RFU = RegisterFiles[I];
42 unsigned NumUsedPhysRegs = DE.UsedPhysRegs[I];
43 RFU.CurrentlyUsedMappings += NumUsedPhysRegs;
44 RFU.TotalMappings += NumUsedPhysRegs;
45 RFU.MaxUsedMappings =
46 std::max(RFU.MaxUsedMappings, RFU.CurrentlyUsedMappings);
47 }
48
Clement Courbet844f22d2018-03-13 13:11:01 +000049 ++NumDispatched;
Andrea Di Biagio12ef5262018-03-21 18:11:05 +000050 }
Clement Courbet844f22d2018-03-13 13:11:01 +000051 }
52}
53
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +000054void BackendStatistics::onReservedBuffers(ArrayRef<unsigned> Buffers) {
55 for (const unsigned Buffer : Buffers) {
56 if (BufferedResources.find(Buffer) != BufferedResources.end()) {
57 BufferUsage &BU = BufferedResources[Buffer];
58 BU.SlotsInUse++;
59 BU.MaxUsedSlots = std::max(BU.MaxUsedSlots, BU.SlotsInUse);
60 continue;
61 }
62
63 BufferedResources.insert(
64 std::pair<unsigned, BufferUsage>(Buffer, {1U, 1U}));
65 }
66}
67
68void BackendStatistics::onReleasedBuffers(ArrayRef<unsigned> Buffers) {
69 for (const unsigned Buffer : Buffers) {
70 assert(BufferedResources.find(Buffer) != BufferedResources.end() &&
71 "Buffered resource not in map?");
72 BufferUsage &BU = BufferedResources[Buffer];
73 BU.SlotsInUse--;
74 }
75}
76
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000077void BackendStatistics::printRetireUnitStatistics(llvm::raw_ostream &OS) const {
78 std::string Buffer;
79 raw_string_ostream TempStream(Buffer);
80 TempStream << "\n\nRetire Control Unit - "
81 << "number of cycles where we saw N instructions retired:\n";
82 TempStream << "[# retired], [# cycles]\n";
83
84 for (const std::pair<unsigned, unsigned> &Entry : RetiredPerCycle) {
85 TempStream << " " << Entry.first;
86 if (Entry.first < 10)
87 TempStream << ", ";
88 else
89 TempStream << ", ";
90 TempStream << Entry.second << " ("
91 << format("%.1f", ((double)Entry.second / NumCycles) * 100.0)
92 << "%)\n";
93 }
94
95 TempStream.flush();
96 OS << Buffer;
97}
98
Andrea Di Biagio53e6ade2018-03-09 12:50:42 +000099void BackendStatistics::printDispatchUnitStatistics(
100 llvm::raw_ostream &OS) const {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000101 std::string Buffer;
102 raw_string_ostream TempStream(Buffer);
103 TempStream << "\n\nDispatch Logic - "
104 << "number of cycles where we saw N instructions dispatched:\n";
105 TempStream << "[# dispatched], [# cycles]\n";
106 for (const std::pair<unsigned, unsigned> &Entry : DispatchGroupSizePerCycle) {
107 TempStream << " " << Entry.first << ", " << Entry.second
108 << " ("
109 << format("%.1f", ((double)Entry.second / NumCycles) * 100.0)
110 << "%)\n";
111 }
112
113 TempStream.flush();
114 OS << Buffer;
115}
116
117void BackendStatistics::printSchedulerStatistics(llvm::raw_ostream &OS) const {
118 std::string Buffer;
119 raw_string_ostream TempStream(Buffer);
120 TempStream << "\n\nSchedulers - number of cycles where we saw N instructions "
121 "issued:\n";
122 TempStream << "[# issued], [# cycles]\n";
123 for (const std::pair<unsigned, unsigned> &Entry : IssuedPerCycle) {
124 TempStream << " " << Entry.first << ", " << Entry.second << " ("
125 << format("%.1f", ((double)Entry.second / NumCycles) * 100)
126 << "%)\n";
127 }
128
129 TempStream.flush();
130 OS << Buffer;
131}
132
Andrea Di Biagio12ef5262018-03-21 18:11:05 +0000133void BackendStatistics::printRATStatistics(raw_ostream &OS) const {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000134 std::string Buffer;
135 raw_string_ostream TempStream(Buffer);
Andrea Di Biagio12ef5262018-03-21 18:11:05 +0000136
137 TempStream << "\n\nRegister File statistics.";
138 for (unsigned I = 0, E = RegisterFiles.size(); I < E; ++I) {
139 const RegisterFileUsage &RFU = RegisterFiles[I];
140 TempStream << "\nRegister File #" << I;
141 TempStream << "\n Total number of mappings created: " << RFU.TotalMappings;
142 TempStream << "\n Max number of mappings used: "
143 << RFU.MaxUsedMappings;
144 }
145
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000146 TempStream.flush();
147 OS << Buffer;
148}
149
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000150void BackendStatistics::printDispatchStalls(raw_ostream &OS) const {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000151 std::string Buffer;
152 raw_string_ostream TempStream(Buffer);
153 TempStream << "\n\nDynamic Dispatch Stall Cycles:\n";
154 TempStream << "RAT - Register unavailable: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000155 << HWStalls[HWStallEvent::RegisterFileStall];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000156 TempStream << "\nRCU - Retire tokens unavailable: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000157 << HWStalls[HWStallEvent::RetireControlUnitStall];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000158 TempStream << "\nSCHEDQ - Scheduler full: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000159 << HWStalls[HWStallEvent::SchedulerQueueFull];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000160 TempStream << "\nLQ - Load queue full: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000161 << HWStalls[HWStallEvent::LoadQueueFull];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000162 TempStream << "\nSQ - Store queue full: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000163 << HWStalls[HWStallEvent::StoreQueueFull];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000164 TempStream << "\nGROUP - Static restrictions on the dispatch group: "
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +0000165 << HWStalls[HWStallEvent::DispatchGroupStall];
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000166 TempStream << '\n';
167 TempStream.flush();
168 OS << Buffer;
169}
170
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +0000171void BackendStatistics::printSchedulerUsage(raw_ostream &OS,
172 const MCSchedModel &SM) const {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000173 std::string Buffer;
174 raw_string_ostream TempStream(Buffer);
175 TempStream << "\n\nScheduler's queue usage:\n";
Andrea Di Biagio79487382018-03-10 17:40:25 +0000176 // Early exit if no buffered resources were consumed.
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +0000177 if (BufferedResources.empty()) {
Andrea Di Biagio79487382018-03-10 17:40:25 +0000178 TempStream << "No scheduler resources used.\n";
179 TempStream.flush();
180 OS << Buffer;
181 return;
182 }
183
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000184 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
185 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +0000186 if (ProcResource.BufferSize <= 0)
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000187 continue;
188
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +0000189 const BufferUsage &BU = BufferedResources.lookup(I);
190 TempStream << ProcResource.Name << ", " << BU.MaxUsedSlots << '/'
191 << ProcResource.BufferSize << '\n';
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000192 }
193
194 TempStream.flush();
195 OS << Buffer;
196}
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000197} // namespace mca