blob: 1dd15e0bbd03f9529a767e3ebe728904c85d41a9 [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
22void ResourcePressureView::initialize(
23 const ArrayRef<uint64_t> ProcResourceMasks) {
24 // Populate the map of resource descriptors.
25 unsigned R2VIndex = 0;
26 const MCSchedModel &SM = STI.getSchedModel();
27 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
28 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
29 unsigned NumUnits = ProcResource.NumUnits;
30 // Skip groups and invalid resources with zero units.
31 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
32 continue;
33
34 uint64_t ResourceMask = ProcResourceMasks[I];
35 Resource2VecIndex.insert(
36 std::pair<uint64_t, unsigned>(ResourceMask, R2VIndex));
37 R2VIndex += ProcResource.NumUnits;
38 }
39
40 NumResourceUnits = R2VIndex;
41 ResourceUsage.resize(NumResourceUnits * (Source.size() + 1));
42 std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0);
43}
44
45void ResourcePressureView::onInstructionIssued(
46 unsigned Index, const ArrayRef<std::pair<ResourceRef, unsigned>> &Used) {
47 unsigned SourceIdx = Index % Source.size();
48 for (const std::pair<ResourceRef, unsigned> &Use : Used) {
49 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 << " ";
73 ResourceIndex++;
74 continue;
75 }
76
77 for (unsigned J = 0; J < NumUnits; ++J) {
78 OS << "[" << ResourceIndex << '.' << J << ']';
79 if (ResourceIndex < 10)
80 OS << " ";
81 else
82 OS << ' ';
83 }
84 ResourceIndex++;
85 }
86}
87
88void ResourcePressureView::printResourcePressurePerIteration(
89 raw_ostream &OS, unsigned Executions) const {
90 std::string Buffer;
91 raw_string_ostream TempStream(Buffer);
92
93 TempStream << "\n\nResources:\n";
94 const MCSchedModel &SM = STI.getSchedModel();
95 for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
96 I < E; ++I) {
97 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
98 unsigned NumUnits = ProcResource.NumUnits;
99 // Skip groups and invalid resources with zero units.
100 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
101 continue;
102
103 for (unsigned J = 0; J < NumUnits; ++J) {
104 TempStream << '[' << ResourceIndex;
105 if (NumUnits > 1)
106 TempStream << '.' << J;
107 TempStream << "] - " << ProcResource.Name << '\n';
108 }
109
110 ResourceIndex++;
111 }
112
113 TempStream << "\n\nResource pressure per iteration:\n";
114 printColumnNames(TempStream, SM);
115 TempStream << '\n';
116
117 for (unsigned I = 0; I < NumResourceUnits; ++I) {
118 unsigned Usage = ResourceUsage[I + Source.size() * NumResourceUnits];
119 if (!Usage) {
120 TempStream << " - ";
121 continue;
122 }
123
124 double Pressure = (double)Usage / Executions;
125 TempStream << format("%.2f", Pressure);
126 if (Pressure < 10.0)
127 TempStream << " ";
128 else if (Pressure < 100.0)
129 TempStream << " ";
130 else
131 TempStream << ' ';
132 }
133
134 TempStream.flush();
135 OS << Buffer;
136}
137
138void ResourcePressureView::printResourcePressurePerInstruction(
139 raw_ostream &OS, unsigned Executions) const {
140 std::string Buffer;
141 raw_string_ostream TempStream(Buffer);
142
143 TempStream << "\n\nResource pressure by instruction:\n";
144 printColumnNames(TempStream, STI.getSchedModel());
145 TempStream << "\tInstructions:\n";
146
147 for (unsigned I = 0, E = Source.size(); I < E; ++I) {
148 for (unsigned J = 0; J < NumResourceUnits; ++J) {
149 unsigned Usage = ResourceUsage[J + I * NumResourceUnits];
150 if (Usage == 0) {
151 TempStream << " - ";
152 } else {
153 double Pressure = (double)Usage / Executions;
154 if (Pressure < 0.005) {
155 TempStream << " - ";
156 } else {
157 TempStream << format("%.2f", Pressure);
158 if (Pressure < 10.0)
159 TempStream << " ";
160 else if (Pressure < 100.0)
161 TempStream << " ";
162 else
163 TempStream << ' ';
164 }
165 }
166 }
167
168 MCIP.printInst(&Source.getMCInstFromIndex(I), TempStream, "", STI);
169 TempStream << '\n';
170 TempStream.flush();
171 OS << Buffer;
172 Buffer = "";
173 }
174}
175
176} // namespace mca