1 //===--------------------- SummaryView.cpp -------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file implements the functionalities used by the SummaryView to print 11 /// the report information. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "Views/SummaryView.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/MCA/Support.h" 18 #include "llvm/Support/Format.h" 19 20 namespace llvm { 21 namespace mca { 22 23 #define DEBUG_TYPE "llvm-mca" 24 25 SummaryView::SummaryView(const MCSchedModel &Model, ArrayRef<MCInst> S, 26 unsigned Width) 27 : SM(Model), Source(S), DispatchWidth(Width?Width: Model.IssueWidth), 28 LastInstructionIdx(0), 29 TotalCycles(0), NumMicroOps(0), 30 ProcResourceUsage(Model.getNumProcResourceKinds(), 0), 31 ProcResourceMasks(Model.getNumProcResourceKinds()), 32 ResIdx2ProcResID(Model.getNumProcResourceKinds(), 0) { 33 computeProcResourceMasks(SM, ProcResourceMasks); 34 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { 35 unsigned Index = getResourceStateIndex(ProcResourceMasks[I]); 36 ResIdx2ProcResID[Index] = I; 37 } 38 } 39 40 void SummaryView::onEvent(const HWInstructionEvent &Event) { 41 if (Event.Type == HWInstructionEvent::Dispatched) 42 LastInstructionIdx = Event.IR.getSourceIndex(); 43 44 // We are only interested in the "instruction retired" events generated by 45 // the retire stage for instructions that are part of iteration #0. 46 if (Event.Type != HWInstructionEvent::Retired || 47 Event.IR.getSourceIndex() >= Source.size()) 48 return; 49 50 // Update the cumulative number of resource cycles based on the processor 51 // resource usage information available from the instruction descriptor. We 52 // need to compute the cumulative number of resource cycles for every 53 // processor resource which is consumed by an instruction of the block. 54 const Instruction &Inst = *Event.IR.getInstruction(); 55 const InstrDesc &Desc = Inst.getDesc(); 56 NumMicroOps += Desc.NumMicroOps; 57 for (const std::pair<uint64_t, ResourceUsage> &RU : Desc.Resources) { 58 if (RU.second.size()) { 59 unsigned ProcResID = ResIdx2ProcResID[getResourceStateIndex(RU.first)]; 60 ProcResourceUsage[ProcResID] += RU.second.size(); 61 } 62 } 63 } 64 65 void SummaryView::printView(raw_ostream &OS) const { 66 unsigned Instructions = Source.size(); 67 unsigned Iterations = (LastInstructionIdx / Instructions) + 1; 68 unsigned TotalInstructions = Instructions * Iterations; 69 unsigned TotalUOps = NumMicroOps * Iterations; 70 double IPC = (double)TotalInstructions / TotalCycles; 71 double UOpsPerCycle = (double)TotalUOps / TotalCycles; 72 double BlockRThroughput = computeBlockRThroughput( 73 SM, DispatchWidth, NumMicroOps, ProcResourceUsage); 74 75 std::string Buffer; 76 raw_string_ostream TempStream(Buffer); 77 TempStream << "Iterations: " << Iterations; 78 TempStream << "\nInstructions: " << TotalInstructions; 79 TempStream << "\nTotal Cycles: " << TotalCycles; 80 TempStream << "\nTotal uOps: " << TotalUOps << '\n'; 81 TempStream << "\nDispatch Width: " << DispatchWidth; 82 TempStream << "\nuOps Per Cycle: " 83 << format("%.2f", floor((UOpsPerCycle * 100) + 0.5) / 100); 84 TempStream << "\nIPC: " 85 << format("%.2f", floor((IPC * 100) + 0.5) / 100); 86 TempStream << "\nBlock RThroughput: " 87 << format("%.1f", floor((BlockRThroughput * 10) + 0.5) / 10) 88 << '\n'; 89 TempStream.flush(); 90 OS << Buffer; 91 } 92 93 } // namespace mca. 94 } // namespace llvm 95