[ARM] sext of a load is free
[llvm-core.git] / tools / llvm-mca / Views / RegisterFileStatistics.cpp
blob58736ee0d18c30e6f43e4cc1ab40e753892749e8
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 //===----------------------------------------------------------------------===//
14 #include "Views/RegisterFileStatistics.h"
15 #include "llvm/Support/Format.h"
17 namespace llvm {
18 namespace mca {
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;
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);
40 PRFUsage.resize(NumRegFiles);
41 std::fill(PRFUsage.begin(), PRFUsage.end(), RFUEmpty);
43 MoveElimInfo.resize(NumRegFiles);
44 std::fill(MoveElimInfo.begin(), MoveElimInfo.end(), MEIEmpty);
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);
59 void RegisterFileStatistics::updateMoveElimInfo(const Instruction &Inst) {
60 if (!Inst.isOptimizableMove())
61 return;
63 assert(Inst.getDefs().size() == 1 && "Expected a single definition!");
64 assert(Inst.getUses().size() == 1 && "Expected a single register use!");
65 const WriteState &WS = Inst.getDefs()[0];
66 const ReadState &RS = Inst.getUses()[0];
68 MoveEliminationInfo &Info =
69 MoveElimInfo[Inst.getDefs()[0].getRegisterFileID()];
70 Info.TotalMoveEliminationCandidates++;
71 if (WS.isEliminated())
72 Info.CurrentMovesEliminated++;
73 if (WS.isWriteZero() && RS.isReadZero())
74 Info.TotalMovesThatPropagateZero++;
77 void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) {
78 switch (Event.Type) {
79 default:
80 break;
81 case HWInstructionEvent::Retired: {
82 const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event);
83 for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I)
84 PRFUsage[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I];
85 break;
87 case HWInstructionEvent::Dispatched: {
88 const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event);
89 updateRegisterFileUsage(DE.UsedPhysRegs);
90 updateMoveElimInfo(*DE.IR.getInstruction());
95 void RegisterFileStatistics::onCycleEnd() {
96 for (MoveEliminationInfo &MEI : MoveElimInfo) {
97 unsigned &CurrentMax = MEI.MaxMovesEliminatedPerCycle;
98 CurrentMax = std::max(CurrentMax, MEI.CurrentMovesEliminated);
99 MEI.TotalMovesEliminated += MEI.CurrentMovesEliminated;
100 MEI.CurrentMovesEliminated = 0;
104 void RegisterFileStatistics::printView(raw_ostream &OS) const {
105 std::string Buffer;
106 raw_string_ostream TempStream(Buffer);
108 TempStream << "\n\nRegister File statistics:";
109 const RegisterFileUsage &GlobalUsage = PRFUsage[0];
110 TempStream << "\nTotal number of mappings created: "
111 << GlobalUsage.TotalMappings;
112 TempStream << "\nMax number of mappings used: "
113 << GlobalUsage.MaxUsedMappings << '\n';
115 for (unsigned I = 1, E = PRFUsage.size(); I < E; ++I) {
116 const RegisterFileUsage &RFU = PRFUsage[I];
117 // Obtain the register file descriptor from the scheduling model.
118 assert(STI.getSchedModel().hasExtraProcessorInfo() &&
119 "Unable to find register file info!");
120 const MCExtraProcessorInfo &PI =
121 STI.getSchedModel().getExtraProcessorInfo();
122 assert(I <= PI.NumRegisterFiles && "Unexpected register file index!");
123 const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I];
124 // Skip invalid register files.
125 if (!RFDesc.NumPhysRegs)
126 continue;
128 TempStream << "\n* Register File #" << I;
129 TempStream << " -- " << StringRef(RFDesc.Name) << ':';
130 TempStream << "\n Number of physical registers: ";
131 if (!RFDesc.NumPhysRegs)
132 TempStream << "unbounded";
133 else
134 TempStream << RFDesc.NumPhysRegs;
135 TempStream << "\n Total number of mappings created: "
136 << RFU.TotalMappings;
137 TempStream << "\n Max number of mappings used: "
138 << RFU.MaxUsedMappings << '\n';
139 const MoveEliminationInfo &MEI = MoveElimInfo[I];
141 if (MEI.TotalMoveEliminationCandidates) {
142 TempStream << " Number of optimizable moves: "
143 << MEI.TotalMoveEliminationCandidates;
144 double EliminatedMovProportion = (double)MEI.TotalMovesEliminated /
145 MEI.TotalMoveEliminationCandidates *
146 100.0;
147 double ZeroMovProportion = (double)MEI.TotalMovesThatPropagateZero /
148 MEI.TotalMoveEliminationCandidates * 100.0;
149 TempStream << "\n Number of moves eliminated: "
150 << MEI.TotalMovesEliminated << " "
151 << format("(%.1f%%)",
152 floor((EliminatedMovProportion * 10) + 0.5) / 10);
153 TempStream << "\n Number of zero moves: "
154 << MEI.TotalMovesThatPropagateZero << " "
155 << format("(%.1f%%)",
156 floor((ZeroMovProportion * 10) + 0.5) / 10);
157 TempStream << "\n Max moves eliminated per cycle: "
158 << MEI.MaxMovesEliminatedPerCycle << '\n';
162 TempStream.flush();
163 OS << Buffer;
166 } // namespace mca
167 } // namespace llvm