Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-mca/Views/RegisterFileStatistics.cpp
96353 views
1
//===--------------------- RegisterFileStatistics.cpp -----------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
///
10
/// This file implements the RegisterFileStatistics interface.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "Views/RegisterFileStatistics.h"
15
#include "llvm/Support/Format.h"
16
17
namespace llvm {
18
namespace mca {
19
20
RegisterFileStatistics::RegisterFileStatistics(const MCSubtargetInfo &sti)
21
: STI(sti) {
22
const MCSchedModel &SM = STI.getSchedModel();
23
RegisterFileUsage RFUEmpty = {0, 0, 0};
24
MoveEliminationInfo MEIEmpty = {0, 0, 0, 0, 0};
25
if (!SM.hasExtraProcessorInfo()) {
26
// Assume a single register file.
27
PRFUsage.emplace_back(RFUEmpty);
28
MoveElimInfo.emplace_back(MEIEmpty);
29
return;
30
}
31
32
// Initialize a RegisterFileUsage for every user defined register file, plus
33
// the default register file which is always at index #0.
34
const MCExtraProcessorInfo &PI = SM.getExtraProcessorInfo();
35
// There is always an "InvalidRegisterFile" entry in tablegen. That entry can
36
// be skipped. If there are no user defined register files, then reserve a
37
// single entry for the default register file at index #0.
38
unsigned NumRegFiles = std::max(PI.NumRegisterFiles, 1U);
39
40
PRFUsage.resize(NumRegFiles);
41
std::fill(PRFUsage.begin(), PRFUsage.end(), RFUEmpty);
42
43
MoveElimInfo.resize(NumRegFiles);
44
std::fill(MoveElimInfo.begin(), MoveElimInfo.end(), MEIEmpty);
45
}
46
47
void RegisterFileStatistics::updateRegisterFileUsage(
48
ArrayRef<unsigned> UsedPhysRegs) {
49
for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I) {
50
RegisterFileUsage &RFU = PRFUsage[I];
51
unsigned NumUsedPhysRegs = UsedPhysRegs[I];
52
RFU.CurrentlyUsedMappings += NumUsedPhysRegs;
53
RFU.TotalMappings += NumUsedPhysRegs;
54
RFU.MaxUsedMappings =
55
std::max(RFU.MaxUsedMappings, RFU.CurrentlyUsedMappings);
56
}
57
}
58
59
void RegisterFileStatistics::updateMoveElimInfo(const Instruction &Inst) {
60
if (!Inst.isOptimizableMove())
61
return;
62
63
if (Inst.getDefs().size() != Inst.getUses().size())
64
return;
65
66
for (size_t I = 0, E = Inst.getDefs().size(); I < E; ++I) {
67
const WriteState &WS = Inst.getDefs()[I];
68
const ReadState &RS = Inst.getUses()[E - (I + 1)];
69
70
MoveEliminationInfo &Info =
71
MoveElimInfo[Inst.getDefs()[0].getRegisterFileID()];
72
Info.TotalMoveEliminationCandidates++;
73
if (WS.isEliminated())
74
Info.CurrentMovesEliminated++;
75
if (WS.isWriteZero() && RS.isReadZero())
76
Info.TotalMovesThatPropagateZero++;
77
}
78
}
79
80
void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) {
81
switch (Event.Type) {
82
default:
83
break;
84
case HWInstructionEvent::Retired: {
85
const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event);
86
for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I)
87
PRFUsage[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I];
88
break;
89
}
90
case HWInstructionEvent::Dispatched: {
91
const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event);
92
updateRegisterFileUsage(DE.UsedPhysRegs);
93
updateMoveElimInfo(*DE.IR.getInstruction());
94
}
95
}
96
}
97
98
void RegisterFileStatistics::onCycleEnd() {
99
for (MoveEliminationInfo &MEI : MoveElimInfo) {
100
unsigned &CurrentMax = MEI.MaxMovesEliminatedPerCycle;
101
CurrentMax = std::max(CurrentMax, MEI.CurrentMovesEliminated);
102
MEI.TotalMovesEliminated += MEI.CurrentMovesEliminated;
103
MEI.CurrentMovesEliminated = 0;
104
}
105
}
106
107
void RegisterFileStatistics::printView(raw_ostream &OS) const {
108
std::string Buffer;
109
raw_string_ostream TempStream(Buffer);
110
111
TempStream << "\n\nRegister File statistics:";
112
const RegisterFileUsage &GlobalUsage = PRFUsage[0];
113
TempStream << "\nTotal number of mappings created: "
114
<< GlobalUsage.TotalMappings;
115
TempStream << "\nMax number of mappings used: "
116
<< GlobalUsage.MaxUsedMappings << '\n';
117
118
for (unsigned I = 1, E = PRFUsage.size(); I < E; ++I) {
119
const RegisterFileUsage &RFU = PRFUsage[I];
120
// Obtain the register file descriptor from the scheduling model.
121
assert(STI.getSchedModel().hasExtraProcessorInfo() &&
122
"Unable to find register file info!");
123
const MCExtraProcessorInfo &PI =
124
STI.getSchedModel().getExtraProcessorInfo();
125
assert(I <= PI.NumRegisterFiles && "Unexpected register file index!");
126
const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I];
127
// Skip invalid register files.
128
if (!RFDesc.NumPhysRegs)
129
continue;
130
131
TempStream << "\n* Register File #" << I;
132
TempStream << " -- " << StringRef(RFDesc.Name) << ':';
133
TempStream << "\n Number of physical registers: ";
134
if (!RFDesc.NumPhysRegs)
135
TempStream << "unbounded";
136
else
137
TempStream << RFDesc.NumPhysRegs;
138
TempStream << "\n Total number of mappings created: "
139
<< RFU.TotalMappings;
140
TempStream << "\n Max number of mappings used: "
141
<< RFU.MaxUsedMappings << '\n';
142
const MoveEliminationInfo &MEI = MoveElimInfo[I];
143
144
if (MEI.TotalMoveEliminationCandidates) {
145
TempStream << " Number of optimizable moves: "
146
<< MEI.TotalMoveEliminationCandidates;
147
double EliminatedMovProportion = (double)MEI.TotalMovesEliminated /
148
MEI.TotalMoveEliminationCandidates *
149
100.0;
150
double ZeroMovProportion = (double)MEI.TotalMovesThatPropagateZero /
151
MEI.TotalMoveEliminationCandidates * 100.0;
152
TempStream << "\n Number of moves eliminated: "
153
<< MEI.TotalMovesEliminated << " "
154
<< format("(%.1f%%)",
155
floor((EliminatedMovProportion * 10) + 0.5) / 10);
156
TempStream << "\n Number of zero moves: "
157
<< MEI.TotalMovesThatPropagateZero << " "
158
<< format("(%.1f%%)",
159
floor((ZeroMovProportion * 10) + 0.5) / 10);
160
TempStream << "\n Max moves eliminated per cycle: "
161
<< MEI.MaxMovesEliminatedPerCycle << '\n';
162
}
163
}
164
165
TempStream.flush();
166
OS << Buffer;
167
}
168
169
} // namespace mca
170
} // namespace llvm
171
172