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), TotalCycles(0), NumMicroOps(0),
29 ProcResourceUsage(Model
.getNumProcResourceKinds(), 0),
30 ProcResourceMasks(Model
.getNumProcResourceKinds()),
31 ResIdx2ProcResID(Model
.getNumProcResourceKinds(), 0) {
32 computeProcResourceMasks(SM
, ProcResourceMasks
);
33 for (unsigned I
= 1, E
= SM
.getNumProcResourceKinds(); I
< E
; ++I
) {
34 unsigned Index
= getResourceStateIndex(ProcResourceMasks
[I
]);
35 ResIdx2ProcResID
[Index
] = I
;
39 void SummaryView::onEvent(const HWInstructionEvent
&Event
) {
40 if (Event
.Type
== HWInstructionEvent::Dispatched
)
41 LastInstructionIdx
= Event
.IR
.getSourceIndex();
43 // We are only interested in the "instruction retired" events generated by
44 // the retire stage for instructions that are part of iteration #0.
45 if (Event
.Type
!= HWInstructionEvent::Retired
||
46 Event
.IR
.getSourceIndex() >= Source
.size())
49 // Update the cumulative number of resource cycles based on the processor
50 // resource usage information available from the instruction descriptor. We
51 // need to compute the cumulative number of resource cycles for every
52 // processor resource which is consumed by an instruction of the block.
53 const Instruction
&Inst
= *Event
.IR
.getInstruction();
54 const InstrDesc
&Desc
= Inst
.getDesc();
55 NumMicroOps
+= Desc
.NumMicroOps
;
56 for (const std::pair
<uint64_t, ResourceUsage
> &RU
: Desc
.Resources
) {
57 if (RU
.second
.size()) {
58 unsigned ProcResID
= ResIdx2ProcResID
[getResourceStateIndex(RU
.first
)];
59 ProcResourceUsage
[ProcResID
] += RU
.second
.size();
64 void SummaryView::printView(raw_ostream
&OS
) const {
66 raw_string_ostream
TempStream(Buffer
);
70 TempStream
<< "Iterations: " << DV
.Iterations
;
71 TempStream
<< "\nInstructions: " << DV
.TotalInstructions
;
72 TempStream
<< "\nTotal Cycles: " << DV
.TotalCycles
;
73 TempStream
<< "\nTotal uOps: " << DV
.TotalUOps
<< '\n';
74 TempStream
<< "\nDispatch Width: " << DV
.DispatchWidth
;
75 TempStream
<< "\nuOps Per Cycle: "
76 << format("%.2f", floor((DV
.UOpsPerCycle
* 100) + 0.5) / 100);
77 TempStream
<< "\nIPC: "
78 << format("%.2f", floor((DV
.IPC
* 100) + 0.5) / 100);
79 TempStream
<< "\nBlock RThroughput: "
80 << format("%.1f", floor((DV
.BlockRThroughput
* 10) + 0.5) / 10)
86 void SummaryView::collectData(DisplayValues
&DV
) const {
87 DV
.Instructions
= Source
.size();
88 DV
.Iterations
= (LastInstructionIdx
/ DV
.Instructions
) + 1;
89 DV
.TotalInstructions
= DV
.Instructions
* DV
.Iterations
;
90 DV
.TotalCycles
= TotalCycles
;
91 DV
.DispatchWidth
= DispatchWidth
;
92 DV
.TotalUOps
= NumMicroOps
* DV
.Iterations
;
93 DV
.UOpsPerCycle
= (double)DV
.TotalUOps
/ TotalCycles
;
94 DV
.IPC
= (double)DV
.TotalInstructions
/ TotalCycles
;
95 DV
.BlockRThroughput
= computeBlockRThroughput(SM
, DispatchWidth
, NumMicroOps
,
99 json::Value
SummaryView::toJSON() const {
102 json::Object
JO({{"Iterations", DV
.Iterations
},
103 {"Instructions", DV
.TotalInstructions
},
104 {"TotalCycles", DV
.TotalCycles
},
105 {"TotaluOps", DV
.TotalUOps
},
106 {"DispatchWidth", DV
.DispatchWidth
},
107 {"uOpsPerCycle", DV
.UOpsPerCycle
},
109 {"BlockRThroughput", DV
.BlockRThroughput
}});