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 namespace llvm { 19 namespace mca { 20 21 RegisterFileStatistics::RegisterFileStatistics(const MCSubtargetInfo &sti) 22 : STI(sti) { 23 const MCSchedModel &SM = STI.getSchedModel(); 24 RegisterFileUsage RFUEmpty = {0, 0, 0}; 25 MoveEliminationInfo MEIEmpty = {0, 0, 0, 0, 0}; 26 if (!SM.hasExtraProcessorInfo()) { 27 // Assume a single register file. 28 PRFUsage.emplace_back(RFUEmpty); 29 MoveElimInfo.emplace_back(MEIEmpty); 30 return; 31 } 32 33 // Initialize a RegisterFileUsage for every user defined register file, plus 34 // the default register file which is always at index #0. 35 const MCExtraProcessorInfo &PI = SM.getExtraProcessorInfo(); 36 // There is always an "InvalidRegisterFile" entry in tablegen. That entry can 37 // be skipped. If there are no user defined register files, then reserve a 38 // single entry for the default register file at index #0. 39 unsigned NumRegFiles = std::max(PI.NumRegisterFiles, 1U); 40 41 PRFUsage.resize(NumRegFiles); 42 std::fill(PRFUsage.begin(), PRFUsage.end(), RFUEmpty); 43 44 MoveElimInfo.resize(NumRegFiles); 45 std::fill(MoveElimInfo.begin(), MoveElimInfo.end(), MEIEmpty); 46 } 47 48 void RegisterFileStatistics::updateRegisterFileUsage( 49 ArrayRef<unsigned> UsedPhysRegs) { 50 for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I) { 51 RegisterFileUsage &RFU = PRFUsage[I]; 52 unsigned NumUsedPhysRegs = UsedPhysRegs[I]; 53 RFU.CurrentlyUsedMappings += NumUsedPhysRegs; 54 RFU.TotalMappings += NumUsedPhysRegs; 55 RFU.MaxUsedMappings = 56 std::max(RFU.MaxUsedMappings, RFU.CurrentlyUsedMappings); 57 } 58 } 59 60 void RegisterFileStatistics::updateMoveElimInfo(const Instruction &Inst) { 61 if (!Inst.isOptimizableMove()) 62 return; 63 64 assert(Inst.getDefs().size() == 1 && "Expected a single definition!"); 65 assert(Inst.getUses().size() == 1 && "Expected a single register use!"); 66 const WriteState &WS = Inst.getDefs()[0]; 67 const ReadState &RS = Inst.getUses()[0]; 68 69 MoveEliminationInfo &Info = 70 MoveElimInfo[Inst.getDefs()[0].getRegisterFileID()]; 71 Info.TotalMoveEliminationCandidates++; 72 if (WS.isEliminated()) 73 Info.CurrentMovesEliminated++; 74 if (WS.isWriteZero() && RS.isReadZero()) 75 Info.TotalMovesThatPropagateZero++; 76 } 77 78 void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) { 79 switch (Event.Type) { 80 default: 81 break; 82 case HWInstructionEvent::Retired: { 83 const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event); 84 for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I) 85 PRFUsage[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I]; 86 break; 87 } 88 case HWInstructionEvent::Dispatched: { 89 const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event); 90 updateRegisterFileUsage(DE.UsedPhysRegs); 91 updateMoveElimInfo(*DE.IR.getInstruction()); 92 } 93 } 94 } 95 96 void RegisterFileStatistics::onCycleEnd() { 97 for (MoveEliminationInfo &MEI : MoveElimInfo) { 98 unsigned &CurrentMax = MEI.MaxMovesEliminatedPerCycle; 99 CurrentMax = std::max(CurrentMax, MEI.CurrentMovesEliminated); 100 MEI.TotalMovesEliminated += MEI.CurrentMovesEliminated; 101 MEI.CurrentMovesEliminated = 0; 102 } 103 } 104 105 void RegisterFileStatistics::printView(raw_ostream &OS) const { 106 std::string Buffer; 107 raw_string_ostream TempStream(Buffer); 108 109 TempStream << "\n\nRegister File statistics:"; 110 const RegisterFileUsage &GlobalUsage = PRFUsage[0]; 111 TempStream << "\nTotal number of mappings created: " 112 << GlobalUsage.TotalMappings; 113 TempStream << "\nMax number of mappings used: " 114 << GlobalUsage.MaxUsedMappings << '\n'; 115 116 for (unsigned I = 1, E = PRFUsage.size(); I < E; ++I) { 117 const RegisterFileUsage &RFU = PRFUsage[I]; 118 // Obtain the register file descriptor from the scheduling model. 119 assert(STI.getSchedModel().hasExtraProcessorInfo() && 120 "Unable to find register file info!"); 121 const MCExtraProcessorInfo &PI = 122 STI.getSchedModel().getExtraProcessorInfo(); 123 assert(I <= PI.NumRegisterFiles && "Unexpected register file index!"); 124 const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I]; 125 // Skip invalid register files. 126 if (!RFDesc.NumPhysRegs) 127 continue; 128 129 TempStream << "\n* Register File #" << I; 130 TempStream << " -- " << StringRef(RFDesc.Name) << ':'; 131 TempStream << "\n Number of physical registers: "; 132 if (!RFDesc.NumPhysRegs) 133 TempStream << "unbounded"; 134 else 135 TempStream << RFDesc.NumPhysRegs; 136 TempStream << "\n Total number of mappings created: " 137 << RFU.TotalMappings; 138 TempStream << "\n Max number of mappings used: " 139 << RFU.MaxUsedMappings << '\n'; 140 const MoveEliminationInfo &MEI = MoveElimInfo[I]; 141 142 if (MEI.TotalMoveEliminationCandidates) { 143 TempStream << " Number of optimizable moves: " 144 << MEI.TotalMoveEliminationCandidates; 145 double EliminatedMovProportion = (double)MEI.TotalMovesEliminated / 146 MEI.TotalMoveEliminationCandidates * 147 100.0; 148 double ZeroMovProportion = (double)MEI.TotalMovesThatPropagateZero / 149 MEI.TotalMoveEliminationCandidates * 100.0; 150 TempStream << "\n Number of moves eliminated: " 151 << MEI.TotalMovesEliminated << " " 152 << format("(%.1f%%)", 153 floor((EliminatedMovProportion * 10) + 0.5) / 10); 154 TempStream << "\n Number of zero moves: " 155 << MEI.TotalMovesThatPropagateZero << " " 156 << format("(%.1f%%)", 157 floor((ZeroMovProportion * 10) + 0.5) / 10); 158 TempStream << "\n Max moves eliminated per cycle: " 159 << MEI.MaxMovesEliminatedPerCycle << '\n'; 160 } 161 } 162 163 TempStream.flush(); 164 OS << Buffer; 165 } 166 167 } // namespace mca 168 } // namespace llvm 169