xref: /llvm-project/llvm/tools/llvm-mca/Views/SummaryView.cpp (revision 14f77576c9c4f502267a92992abe3bdcbeb96b2c)
1*14f77576SMarcos Horro //===--------------------- SummaryView.cpp ----------------------*- C++ -*-===//
210aa09f0SMatt Davis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610aa09f0SMatt Davis //
710aa09f0SMatt Davis //===----------------------------------------------------------------------===//
810aa09f0SMatt Davis /// \file
910aa09f0SMatt Davis ///
1010aa09f0SMatt Davis /// This file implements the functionalities used by the SummaryView to print
1110aa09f0SMatt Davis /// the report information.
1210aa09f0SMatt Davis ///
1310aa09f0SMatt Davis //===----------------------------------------------------------------------===//
1410aa09f0SMatt Davis 
1510aa09f0SMatt Davis #include "Views/SummaryView.h"
1610aa09f0SMatt Davis #include "llvm/ADT/SmallVector.h"
17cc5e6a72SClement Courbet #include "llvm/MCA/Support.h"
1810aa09f0SMatt Davis #include "llvm/Support/Format.h"
1910aa09f0SMatt Davis 
205a8fd657SFangrui Song namespace llvm {
2110aa09f0SMatt Davis namespace mca {
2210aa09f0SMatt Davis 
2310aa09f0SMatt Davis #define DEBUG_TYPE "llvm-mca"
2410aa09f0SMatt Davis 
SummaryView(const MCSchedModel & Model,ArrayRef<MCInst> S,unsigned Width)2584d00513SAndrea Di Biagio SummaryView::SummaryView(const MCSchedModel &Model, ArrayRef<MCInst> S,
2657cef586SAndrea Di Biagio                          unsigned Width)
27ddce32e2SAndrea Di Biagio     : SM(Model), Source(S), DispatchWidth(Width ? Width : Model.IssueWidth),
28*14f77576SMarcos Horro       LastInstructionIdx(0), TotalCycles(0), NumMicroOps(0),
2997ed076dSAndrea Di Biagio       ProcResourceUsage(Model.getNumProcResourceKinds(), 0),
30d882ad5eSAndrea Di Biagio       ProcResourceMasks(Model.getNumProcResourceKinds()),
3157cef586SAndrea Di Biagio       ResIdx2ProcResID(Model.getNumProcResourceKinds(), 0) {
3210aa09f0SMatt Davis   computeProcResourceMasks(SM, ProcResourceMasks);
33d882ad5eSAndrea Di Biagio   for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
34d882ad5eSAndrea Di Biagio     unsigned Index = getResourceStateIndex(ProcResourceMasks[I]);
35d882ad5eSAndrea Di Biagio     ResIdx2ProcResID[Index] = I;
36d882ad5eSAndrea Di Biagio   }
3710aa09f0SMatt Davis }
3810aa09f0SMatt Davis 
onEvent(const HWInstructionEvent & Event)3910aa09f0SMatt Davis void SummaryView::onEvent(const HWInstructionEvent &Event) {
4084d00513SAndrea Di Biagio   if (Event.Type == HWInstructionEvent::Dispatched)
4184d00513SAndrea Di Biagio     LastInstructionIdx = Event.IR.getSourceIndex();
4284d00513SAndrea Di Biagio 
438b647dcfSAndrea Di Biagio   // We are only interested in the "instruction retired" events generated by
448b647dcfSAndrea Di Biagio   // the retire stage for instructions that are part of iteration #0.
458b647dcfSAndrea Di Biagio   if (Event.Type != HWInstructionEvent::Retired ||
468b647dcfSAndrea Di Biagio       Event.IR.getSourceIndex() >= Source.size())
4710aa09f0SMatt Davis     return;
4810aa09f0SMatt Davis 
4910aa09f0SMatt Davis   // Update the cumulative number of resource cycles based on the processor
5010aa09f0SMatt Davis   // resource usage information available from the instruction descriptor. We
5110aa09f0SMatt Davis   // need to compute the cumulative number of resource cycles for every
5210aa09f0SMatt Davis   // processor resource which is consumed by an instruction of the block.
5310aa09f0SMatt Davis   const Instruction &Inst = *Event.IR.getInstruction();
5410aa09f0SMatt Davis   const InstrDesc &Desc = Inst.getDesc();
5510aa09f0SMatt Davis   NumMicroOps += Desc.NumMicroOps;
56536c9a60SMark de Wever   for (const std::pair<uint64_t, ResourceUsage> &RU : Desc.Resources) {
5710aa09f0SMatt Davis     if (RU.second.size()) {
58d882ad5eSAndrea Di Biagio       unsigned ProcResID = ResIdx2ProcResID[getResourceStateIndex(RU.first)];
59d882ad5eSAndrea Di Biagio       ProcResourceUsage[ProcResID] += RU.second.size();
6010aa09f0SMatt Davis     }
6110aa09f0SMatt Davis   }
6210aa09f0SMatt Davis }
6310aa09f0SMatt Davis 
printView(raw_ostream & OS) const6410aa09f0SMatt Davis void SummaryView::printView(raw_ostream &OS) const {
6510aa09f0SMatt Davis   std::string Buffer;
6610aa09f0SMatt Davis   raw_string_ostream TempStream(Buffer);
67cf6adecdSWolfgang Pieb   DisplayValues DV;
68cf6adecdSWolfgang Pieb 
69cf6adecdSWolfgang Pieb   collectData(DV);
70cf6adecdSWolfgang Pieb   TempStream << "Iterations:        " << DV.Iterations;
71cf6adecdSWolfgang Pieb   TempStream << "\nInstructions:      " << DV.TotalInstructions;
72cf6adecdSWolfgang Pieb   TempStream << "\nTotal Cycles:      " << DV.TotalCycles;
73cf6adecdSWolfgang Pieb   TempStream << "\nTotal uOps:        " << DV.TotalUOps << '\n';
74cf6adecdSWolfgang Pieb   TempStream << "\nDispatch Width:    " << DV.DispatchWidth;
75a2eee474SAndrea Di Biagio   TempStream << "\nuOps Per Cycle:    "
76cf6adecdSWolfgang Pieb              << format("%.2f", floor((DV.UOpsPerCycle * 100) + 0.5) / 100);
77a2eee474SAndrea Di Biagio   TempStream << "\nIPC:               "
78cf6adecdSWolfgang Pieb              << format("%.2f", floor((DV.IPC * 100) + 0.5) / 100);
7910aa09f0SMatt Davis   TempStream << "\nBlock RThroughput: "
80cf6adecdSWolfgang Pieb              << format("%.1f", floor((DV.BlockRThroughput * 10) + 0.5) / 10)
8110aa09f0SMatt Davis              << '\n';
8210aa09f0SMatt Davis   TempStream.flush();
8310aa09f0SMatt Davis   OS << Buffer;
8410aa09f0SMatt Davis }
8557cef586SAndrea Di Biagio 
collectData(DisplayValues & DV) const86cf6adecdSWolfgang Pieb void SummaryView::collectData(DisplayValues &DV) const {
87cf6adecdSWolfgang Pieb   DV.Instructions = Source.size();
88cf6adecdSWolfgang Pieb   DV.Iterations = (LastInstructionIdx / DV.Instructions) + 1;
89cf6adecdSWolfgang Pieb   DV.TotalInstructions = DV.Instructions * DV.Iterations;
90cf6adecdSWolfgang Pieb   DV.TotalCycles = TotalCycles;
91cf6adecdSWolfgang Pieb   DV.DispatchWidth = DispatchWidth;
92cf6adecdSWolfgang Pieb   DV.TotalUOps = NumMicroOps * DV.Iterations;
93cf6adecdSWolfgang Pieb   DV.UOpsPerCycle = (double)DV.TotalUOps / TotalCycles;
94cf6adecdSWolfgang Pieb   DV.IPC = (double)DV.TotalInstructions / TotalCycles;
95cf6adecdSWolfgang Pieb   DV.BlockRThroughput = computeBlockRThroughput(SM, DispatchWidth, NumMicroOps,
96cf6adecdSWolfgang Pieb                                                 ProcResourceUsage);
97cf6adecdSWolfgang Pieb }
98d38be2baSWolfgang Pieb 
toJSON() const99d38be2baSWolfgang Pieb json::Value SummaryView::toJSON() const {
100d38be2baSWolfgang Pieb   DisplayValues DV;
101d38be2baSWolfgang Pieb   collectData(DV);
102d38be2baSWolfgang Pieb   json::Object JO({{"Iterations", DV.Iterations},
103d38be2baSWolfgang Pieb                    {"Instructions", DV.TotalInstructions},
104d38be2baSWolfgang Pieb                    {"TotalCycles", DV.TotalCycles},
105d38be2baSWolfgang Pieb                    {"TotaluOps", DV.TotalUOps},
106d38be2baSWolfgang Pieb                    {"DispatchWidth", DV.DispatchWidth},
107d38be2baSWolfgang Pieb                    {"uOpsPerCycle", DV.UOpsPerCycle},
108d38be2baSWolfgang Pieb                    {"IPC", DV.IPC},
109d38be2baSWolfgang Pieb                    {"BlockRThroughput", DV.BlockRThroughput}});
110d38be2baSWolfgang Pieb   return JO;
111d38be2baSWolfgang Pieb }
11210aa09f0SMatt Davis } // namespace mca.
1135a8fd657SFangrui Song } // namespace llvm
114