Home | History | Annotate | Download | only in llvm-mca
      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