blob: 330de2de4e888b9d7c67db9c824501672beca3ce [file] [log] [blame]
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00001//===--------------------- ResourcePressureView.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 methods in the ResourcePressureView interface.
12///
13//===----------------------------------------------------------------------===//
14
15#include "ResourcePressureView.h"
16#include "llvm/Support/raw_ostream.h"
17
18namespace mca {
19
20using namespace llvm;
21
Andrea Di Biagio0c541292018-03-10 16:55:07 +000022void ResourcePressureView::initialize() {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000023 // Populate the map of resource descriptors.
24 unsigned R2VIndex = 0;
25 const MCSchedModel &SM = STI.getSchedModel();
26 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
27 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
28 unsigned NumUnits = ProcResource.NumUnits;
29 // Skip groups and invalid resources with zero units.
30 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
31 continue;
32
Andrea Di Biagio35622482018-03-22 10:19:20 +000033 Resource2VecIndex.insert(std::pair<unsigned, unsigned>(I, R2VIndex));
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000034 R2VIndex += ProcResource.NumUnits;
35 }
36
37 NumResourceUnits = R2VIndex;
38 ResourceUsage.resize(NumResourceUnits * (Source.size() + 1));
39 std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0);
40}
41
Clement Courbet844f22d2018-03-13 13:11:01 +000042void ResourcePressureView::onInstructionEvent(const HWInstructionEvent &Event) {
43 // We're only interested in Issue events.
44 if (Event.Type != HWInstructionEvent::Issued)
45 return;
46 const auto &IssueEvent = static_cast<const HWInstructionIssuedEvent &>(Event);
47 unsigned SourceIdx = Event.Index % Source.size();
48 for (const std::pair<ResourceRef, unsigned> &Use : IssueEvent.UsedResources) {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000049 const ResourceRef &RR = Use.first;
50 assert(Resource2VecIndex.find(RR.first) != Resource2VecIndex.end());
51 unsigned R2VIndex = Resource2VecIndex[RR.first];
52 R2VIndex += countTrailingZeros(RR.second);
53 ResourceUsage[R2VIndex + NumResourceUnits * SourceIdx] += Use.second;
54 ResourceUsage[R2VIndex + NumResourceUnits * Source.size()] += Use.second;
55 }
56}
57
58static void printColumnNames(raw_string_ostream &OS, const MCSchedModel &SM) {
59 for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
60 I < E; ++I) {
61 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
62 unsigned NumUnits = ProcResource.NumUnits;
63 // Skip groups and invalid resources with zero units.
64 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
65 continue;
66
67 if (NumUnits == 1) {
68 OS << '[' << ResourceIndex << ']';
69 if (ResourceIndex < 10)
70 OS << " ";
71 else
72 OS << " ";
Andrea Di Biagio35622482018-03-22 10:19:20 +000073 } else {
74 for (unsigned J = 0; J < NumUnits; ++J) {
75 OS << "[" << ResourceIndex << '.' << J << ']';
76 if (ResourceIndex < 10)
77 OS << " ";
78 else
79 OS << ' ';
80 }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000081 }
82 ResourceIndex++;
83 }
84}
85
86void ResourcePressureView::printResourcePressurePerIteration(
87 raw_ostream &OS, unsigned Executions) const {
88 std::string Buffer;
89 raw_string_ostream TempStream(Buffer);
90
91 TempStream << "\n\nResources:\n";
92 const MCSchedModel &SM = STI.getSchedModel();
93 for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
94 I < E; ++I) {
95 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
96 unsigned NumUnits = ProcResource.NumUnits;
97 // Skip groups and invalid resources with zero units.
98 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
99 continue;
100
101 for (unsigned J = 0; J < NumUnits; ++J) {
102 TempStream << '[' << ResourceIndex;
103 if (NumUnits > 1)
104 TempStream << '.' << J;
105 TempStream << "] - " << ProcResource.Name << '\n';
106 }
107
108 ResourceIndex++;
109 }
110
111 TempStream << "\n\nResource pressure per iteration:\n";
112 printColumnNames(TempStream, SM);
113 TempStream << '\n';
114
Andrea Di Biagio35622482018-03-22 10:19:20 +0000115 for (unsigned I = 0, E = NumResourceUnits; I < E; ++I) {
116 unsigned Usage = ResourceUsage[I + Source.size() * E];
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000117 if (!Usage) {
118 TempStream << " - ";
119 continue;
120 }
121
122 double Pressure = (double)Usage / Executions;
123 TempStream << format("%.2f", Pressure);
124 if (Pressure < 10.0)
125 TempStream << " ";
126 else if (Pressure < 100.0)
127 TempStream << " ";
128 else
129 TempStream << ' ';
130 }
131
132 TempStream.flush();
133 OS << Buffer;
134}
135
136void ResourcePressureView::printResourcePressurePerInstruction(
137 raw_ostream &OS, unsigned Executions) const {
138 std::string Buffer;
139 raw_string_ostream TempStream(Buffer);
140
141 TempStream << "\n\nResource pressure by instruction:\n";
142 printColumnNames(TempStream, STI.getSchedModel());
143 TempStream << "\tInstructions:\n";
144
145 for (unsigned I = 0, E = Source.size(); I < E; ++I) {
146 for (unsigned J = 0; J < NumResourceUnits; ++J) {
147 unsigned Usage = ResourceUsage[J + I * NumResourceUnits];
148 if (Usage == 0) {
149 TempStream << " - ";
150 } else {
151 double Pressure = (double)Usage / Executions;
152 if (Pressure < 0.005) {
153 TempStream << " - ";
154 } else {
155 TempStream << format("%.2f", Pressure);
156 if (Pressure < 10.0)
157 TempStream << " ";
158 else if (Pressure < 100.0)
159 TempStream << " ";
160 else
161 TempStream << ' ';
162 }
163 }
164 }
165
166 MCIP.printInst(&Source.getMCInstFromIndex(I), TempStream, "", STI);
167 TempStream << '\n';
168 TempStream.flush();
169 OS << Buffer;
170 Buffer = "";
171 }
172}
173
174} // namespace mca