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