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 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 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 66 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