1 //===--------------------- RegisterFileStatistics.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 the RegisterFileStatistics interface.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "RegisterFileStatistics.h"
16 #include "llvm/Support/Format.h"
17
18 using namespace llvm;
19
20 namespace mca {
21
initializeRegisterFileInfo()22 void RegisterFileStatistics::initializeRegisterFileInfo() {
23 const MCSchedModel &SM = STI.getSchedModel();
24 RegisterFileUsage Empty = {0, 0, 0};
25 if (!SM.hasExtraProcessorInfo()) {
26 // Assume a single register file.
27 RegisterFiles.emplace_back(Empty);
28 return;
29 }
30
31 // Initialize a RegisterFileUsage for every user defined register file, plus
32 // the default register file which is always at index #0.
33 const MCExtraProcessorInfo &PI = SM.getExtraProcessorInfo();
34 // There is always an "InvalidRegisterFile" entry in tablegen. That entry can
35 // be skipped. If there are no user defined register files, then reserve a
36 // single entry for the default register file at index #0.
37 unsigned NumRegFiles = std::max(PI.NumRegisterFiles, 1U);
38 RegisterFiles.resize(NumRegFiles);
39 std::fill(RegisterFiles.begin(), RegisterFiles.end(), Empty);
40 }
41
onEvent(const HWInstructionEvent & Event)42 void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) {
43 switch (Event.Type) {
44 default:
45 break;
46 case HWInstructionEvent::Retired: {
47 const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event);
48 for (unsigned I = 0, E = RegisterFiles.size(); I < E; ++I)
49 RegisterFiles[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I];
50 break;
51 }
52 case HWInstructionEvent::Dispatched: {
53 const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event);
54 for (unsigned I = 0, E = RegisterFiles.size(); I < E; ++I) {
55 RegisterFileUsage &RFU = RegisterFiles[I];
56 unsigned NumUsedPhysRegs = DE.UsedPhysRegs[I];
57 RFU.CurrentlyUsedMappings += NumUsedPhysRegs;
58 RFU.TotalMappings += NumUsedPhysRegs;
59 RFU.MaxUsedMappings =
60 std::max(RFU.MaxUsedMappings, RFU.CurrentlyUsedMappings);
61 }
62 }
63 }
64 }
65
printView(raw_ostream & OS) const66 void RegisterFileStatistics::printView(raw_ostream &OS) const {
67 std::string Buffer;
68 raw_string_ostream TempStream(Buffer);
69
70 TempStream << "\n\nRegister File statistics:";
71 const RegisterFileUsage &GlobalUsage = RegisterFiles[0];
72 TempStream << "\nTotal number of mappings created: "
73 << GlobalUsage.TotalMappings;
74 TempStream << "\nMax number of mappings used: "
75 << GlobalUsage.MaxUsedMappings << '\n';
76
77 for (unsigned I = 1, E = RegisterFiles.size(); I < E; ++I) {
78 const RegisterFileUsage &RFU = RegisterFiles[I];
79 // Obtain the register file descriptor from the scheduling model.
80 assert(STI.getSchedModel().hasExtraProcessorInfo() &&
81 "Unable to find register file info!");
82 const MCExtraProcessorInfo &PI =
83 STI.getSchedModel().getExtraProcessorInfo();
84 assert(I <= PI.NumRegisterFiles && "Unexpected register file index!");
85 const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I];
86 // Skip invalid register files.
87 if (!RFDesc.NumPhysRegs)
88 continue;
89
90 TempStream << "\n* Register File #" << I;
91 TempStream << " -- " << StringRef(RFDesc.Name) << ':';
92 TempStream << "\n Number of physical registers: ";
93 if (!RFDesc.NumPhysRegs)
94 TempStream << "unbounded";
95 else
96 TempStream << RFDesc.NumPhysRegs;
97 TempStream << "\n Total number of mappings created: "
98 << RFU.TotalMappings;
99 TempStream << "\n Max number of mappings used: "
100 << RFU.MaxUsedMappings << '\n';
101 }
102
103 TempStream.flush();
104 OS << Buffer;
105 }
106
107 } // namespace mca
108