1 //===--------------------- SummaryView.cpp -------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file implements the functionalities used by the SummaryView to print
11 /// the report information.
13 //===----------------------------------------------------------------------===//
15 #include "Views/SummaryView.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/MCA/Support.h"
18 #include "llvm/Support/Format.h"
23 #define DEBUG_TYPE "llvm-mca"
25 SummaryView::SummaryView(const MCSchedModel
&Model
, ArrayRef
<MCInst
> S
,
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
;
40 void SummaryView::onEvent(const HWInstructionEvent
&Event
) {
41 if (Event
.Type
== HWInstructionEvent::Dispatched
)
42 LastInstructionIdx
= Event
.IR
.getSourceIndex();
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())
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, const ResourceUsage
> &RU
: Desc
.Resources
) {
58 if (RU
.second
.size()) {
59 unsigned ProcResID
= ResIdx2ProcResID
[getResourceStateIndex(RU
.first
)];
60 ProcResourceUsage
[ProcResID
] += RU
.second
.size();
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
);
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)