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