xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-mca/Views/ResourcePressureView.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===--------------------- ResourcePressureView.h ---------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric /// \file
9*0b57cec5SDimitry Andric ///
10*0b57cec5SDimitry Andric /// This file define class ResourcePressureView.
11*0b57cec5SDimitry Andric /// Class ResourcePressureView observes hardware events generated by
12*0b57cec5SDimitry Andric /// the Pipeline object and collects statistics related to resource usage at
13*0b57cec5SDimitry Andric /// instruction granularity.
14*0b57cec5SDimitry Andric /// Resource pressure information is then printed out to a stream in the
15*0b57cec5SDimitry Andric /// form of a table like the one from the example below:
16*0b57cec5SDimitry Andric ///
17*0b57cec5SDimitry Andric /// Resources:
18*0b57cec5SDimitry Andric /// [0] - JALU0
19*0b57cec5SDimitry Andric /// [1] - JALU1
20*0b57cec5SDimitry Andric /// [2] - JDiv
21*0b57cec5SDimitry Andric /// [3] - JFPM
22*0b57cec5SDimitry Andric /// [4] - JFPU0
23*0b57cec5SDimitry Andric /// [5] - JFPU1
24*0b57cec5SDimitry Andric /// [6] - JLAGU
25*0b57cec5SDimitry Andric /// [7] - JSAGU
26*0b57cec5SDimitry Andric /// [8] - JSTC
27*0b57cec5SDimitry Andric /// [9] - JVIMUL
28*0b57cec5SDimitry Andric ///
29*0b57cec5SDimitry Andric /// Resource pressure per iteration:
30*0b57cec5SDimitry Andric /// [0]    [1]    [2]    [3]    [4]    [5]    [6]    [7]    [8]    [9]
31*0b57cec5SDimitry Andric /// 0.00   0.00   0.00   0.00   2.00   2.00   0.00   0.00   0.00   0.00
32*0b57cec5SDimitry Andric ///
33*0b57cec5SDimitry Andric /// Resource pressure by instruction:
34*0b57cec5SDimitry Andric /// [0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9]  Instructions:
35*0b57cec5SDimitry Andric ///  -    -    -    -    -   1.00  -    -    -    -   vpermilpd  $1,    %xmm0,
36*0b57cec5SDimitry Andric ///  %xmm1
37*0b57cec5SDimitry Andric ///  -    -    -    -   1.00  -    -    -    -    -   vaddps     %xmm0, %xmm1,
38*0b57cec5SDimitry Andric ///  %xmm2
39*0b57cec5SDimitry Andric ///  -    -    -    -    -   1.00  -    -    -    -   vmovshdup  %xmm2, %xmm3
40*0b57cec5SDimitry Andric ///  -    -    -    -   1.00  -    -    -    -    -   vaddss     %xmm2, %xmm3,
41*0b57cec5SDimitry Andric ///  %xmm4
42*0b57cec5SDimitry Andric ///
43*0b57cec5SDimitry Andric /// In this example, we have AVX code executed on AMD Jaguar (btver2).
44*0b57cec5SDimitry Andric /// Both shuffles and vector floating point add operations on XMM registers have
45*0b57cec5SDimitry Andric /// a reciprocal throughput of 1cy.
46*0b57cec5SDimitry Andric /// Each add is issued to pipeline JFPU0, while each shuffle is issued to
47*0b57cec5SDimitry Andric /// pipeline JFPU1. The overall pressure per iteration is reported by two
48*0b57cec5SDimitry Andric /// tables: the first smaller table is the resource pressure per iteration;
49*0b57cec5SDimitry Andric /// the second table reports resource pressure per instruction. Values are the
50*0b57cec5SDimitry Andric /// average resource cycles consumed by an instruction.
51*0b57cec5SDimitry Andric /// Every vector add from the example uses resource JFPU0 for an average of 1cy
52*0b57cec5SDimitry Andric /// per iteration. Consequently, the resource pressure on JFPU0 is of 2cy per
53*0b57cec5SDimitry Andric /// iteration.
54*0b57cec5SDimitry Andric ///
55*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric #ifndef LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
58*0b57cec5SDimitry Andric #define LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric #include "Views/View.h"
61*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
62*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
63*0b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
64*0b57cec5SDimitry Andric #include "llvm/MC/MCInstPrinter.h"
65*0b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
66*0b57cec5SDimitry Andric 
67*0b57cec5SDimitry Andric namespace llvm {
68*0b57cec5SDimitry Andric namespace mca {
69*0b57cec5SDimitry Andric 
70*0b57cec5SDimitry Andric /// This class collects resource pressure statistics and it is able to print
71*0b57cec5SDimitry Andric /// out all the collected information as a table to an output stream.
72*0b57cec5SDimitry Andric class ResourcePressureView : public View {
73*0b57cec5SDimitry Andric   const llvm::MCSubtargetInfo &STI;
74*0b57cec5SDimitry Andric   llvm::MCInstPrinter &MCIP;
75*0b57cec5SDimitry Andric   llvm::ArrayRef<llvm::MCInst> Source;
76*0b57cec5SDimitry Andric   unsigned LastInstructionIdx;
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric   // Map to quickly obtain the ResourceUsage column index from a processor
79*0b57cec5SDimitry Andric   // resource ID.
80*0b57cec5SDimitry Andric   llvm::DenseMap<unsigned, unsigned> Resource2VecIndex;
81*0b57cec5SDimitry Andric 
82*0b57cec5SDimitry Andric   // Table of resources used by instructions.
83*0b57cec5SDimitry Andric   std::vector<ResourceCycles> ResourceUsage;
84*0b57cec5SDimitry Andric   unsigned NumResourceUnits;
85*0b57cec5SDimitry Andric 
86*0b57cec5SDimitry Andric   void printResourcePressurePerIter(llvm::raw_ostream &OS) const;
87*0b57cec5SDimitry Andric   void printResourcePressurePerInst(llvm::raw_ostream &OS) const;
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric public:
90*0b57cec5SDimitry Andric   ResourcePressureView(const llvm::MCSubtargetInfo &sti,
91*0b57cec5SDimitry Andric                        llvm::MCInstPrinter &Printer,
92*0b57cec5SDimitry Andric                        llvm::ArrayRef<llvm::MCInst> S);
93*0b57cec5SDimitry Andric 
94*0b57cec5SDimitry Andric   void onEvent(const HWInstructionEvent &Event) override;
95*0b57cec5SDimitry Andric   void printView(llvm::raw_ostream &OS) const override {
96*0b57cec5SDimitry Andric     printResourcePressurePerIter(OS);
97*0b57cec5SDimitry Andric     printResourcePressurePerInst(OS);
98*0b57cec5SDimitry Andric   }
99*0b57cec5SDimitry Andric };
100*0b57cec5SDimitry Andric } // namespace mca
101*0b57cec5SDimitry Andric } // namespace llvm
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric #endif
104