blob: 6fd23ccf346f27d6dbc25c18c45706f22cafd109 [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));
Andrea Di Biagio083960d2018-03-23 17:53:02 +000039 std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0.0);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000040}
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);
Matt Davis21a8d322018-05-07 18:29:15 +000047 const unsigned SourceIdx = Event.IR.getSourceIndex() % Source.size();
Andrea Di Biagio083960d2018-03-23 17:53:02 +000048 for (const std::pair<ResourceRef, double> &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
Andrea Di Biagiob8800b02018-04-10 15:14:15 +000086static void printResourcePressure(raw_string_ostream &OS, double Pressure) {
Andrea Di Biagio7bf82562018-05-05 12:21:54 +000087 if (!Pressure || Pressure < 0.005) {
Andrea Di Biagiob8800b02018-04-10 15:14:15 +000088 OS << " - ";
89 return;
90 }
91
92 // Round to the value to the nearest hundredth and then print it.
93 OS << format("%.2f", floor((Pressure * 100) + 0.5)/100);
94 if (Pressure < 10.0)
95 OS << " ";
96 else if (Pressure < 100.0)
97 OS << " ";
98 else
99 OS << ' ';
100}
101
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000102void ResourcePressureView::printResourcePressurePerIteration(
103 raw_ostream &OS, unsigned Executions) const {
104 std::string Buffer;
105 raw_string_ostream TempStream(Buffer);
106
107 TempStream << "\n\nResources:\n";
108 const MCSchedModel &SM = STI.getSchedModel();
109 for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
110 I < E; ++I) {
111 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
112 unsigned NumUnits = ProcResource.NumUnits;
113 // Skip groups and invalid resources with zero units.
114 if (ProcResource.SubUnitsIdxBegin || !NumUnits)
115 continue;
116
117 for (unsigned J = 0; J < NumUnits; ++J) {
118 TempStream << '[' << ResourceIndex;
119 if (NumUnits > 1)
120 TempStream << '.' << J;
121 TempStream << "] - " << ProcResource.Name << '\n';
122 }
123
124 ResourceIndex++;
125 }
126
127 TempStream << "\n\nResource pressure per iteration:\n";
128 printColumnNames(TempStream, SM);
129 TempStream << '\n';
130
Andrea Di Biagio35622482018-03-22 10:19:20 +0000131 for (unsigned I = 0, E = NumResourceUnits; I < E; ++I) {
Andrea Di Biagio083960d2018-03-23 17:53:02 +0000132 double Usage = ResourceUsage[I + Source.size() * E];
Andrea Di Biagiob8800b02018-04-10 15:14:15 +0000133 printResourcePressure(TempStream, Usage / Executions);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000134 }
135
136 TempStream.flush();
137 OS << Buffer;
138}
139
140void ResourcePressureView::printResourcePressurePerInstruction(
141 raw_ostream &OS, unsigned Executions) const {
142 std::string Buffer;
143 raw_string_ostream TempStream(Buffer);
144
145 TempStream << "\n\nResource pressure by instruction:\n";
146 printColumnNames(TempStream, STI.getSchedModel());
147 TempStream << "\tInstructions:\n";
148
149 for (unsigned I = 0, E = Source.size(); I < E; ++I) {
150 for (unsigned J = 0; J < NumResourceUnits; ++J) {
Andrea Di Biagio083960d2018-03-23 17:53:02 +0000151 double Usage = ResourceUsage[J + I * NumResourceUnits];
Andrea Di Biagiob8800b02018-04-10 15:14:15 +0000152 printResourcePressure(TempStream, Usage / Executions);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000153 }
154
155 MCIP.printInst(&Source.getMCInstFromIndex(I), TempStream, "", STI);
156 TempStream << '\n';
157 TempStream.flush();
158 OS << Buffer;
159 Buffer = "";
160 }
161}
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000162} // namespace mca