xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-mca/Views/ResourcePressureView.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===--------------------- ResourcePressureView.h ---------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric /// \file
90b57cec5SDimitry Andric ///
100b57cec5SDimitry Andric /// This file define class ResourcePressureView.
110b57cec5SDimitry Andric /// Class ResourcePressureView observes hardware events generated by
120b57cec5SDimitry Andric /// the Pipeline object and collects statistics related to resource usage at
130b57cec5SDimitry Andric /// instruction granularity.
140b57cec5SDimitry Andric /// Resource pressure information is then printed out to a stream in the
150b57cec5SDimitry Andric /// form of a table like the one from the example below:
160b57cec5SDimitry Andric ///
170b57cec5SDimitry Andric /// Resources:
180b57cec5SDimitry Andric /// [0] - JALU0
190b57cec5SDimitry Andric /// [1] - JALU1
200b57cec5SDimitry Andric /// [2] - JDiv
210b57cec5SDimitry Andric /// [3] - JFPM
220b57cec5SDimitry Andric /// [4] - JFPU0
230b57cec5SDimitry Andric /// [5] - JFPU1
240b57cec5SDimitry Andric /// [6] - JLAGU
250b57cec5SDimitry Andric /// [7] - JSAGU
260b57cec5SDimitry Andric /// [8] - JSTC
270b57cec5SDimitry Andric /// [9] - JVIMUL
280b57cec5SDimitry Andric ///
290b57cec5SDimitry Andric /// Resource pressure per iteration:
300b57cec5SDimitry Andric /// [0]    [1]    [2]    [3]    [4]    [5]    [6]    [7]    [8]    [9]
310b57cec5SDimitry Andric /// 0.00   0.00   0.00   0.00   2.00   2.00   0.00   0.00   0.00   0.00
320b57cec5SDimitry Andric ///
330b57cec5SDimitry Andric /// Resource pressure by instruction:
340b57cec5SDimitry Andric /// [0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9]  Instructions:
350b57cec5SDimitry Andric ///  -    -    -    -    -   1.00  -    -    -    -   vpermilpd  $1,    %xmm0,
360b57cec5SDimitry Andric ///  %xmm1
370b57cec5SDimitry Andric ///  -    -    -    -   1.00  -    -    -    -    -   vaddps     %xmm0, %xmm1,
380b57cec5SDimitry Andric ///  %xmm2
390b57cec5SDimitry Andric ///  -    -    -    -    -   1.00  -    -    -    -   vmovshdup  %xmm2, %xmm3
400b57cec5SDimitry Andric ///  -    -    -    -   1.00  -    -    -    -    -   vaddss     %xmm2, %xmm3,
410b57cec5SDimitry Andric ///  %xmm4
420b57cec5SDimitry Andric ///
430b57cec5SDimitry Andric /// In this example, we have AVX code executed on AMD Jaguar (btver2).
440b57cec5SDimitry Andric /// Both shuffles and vector floating point add operations on XMM registers have
450b57cec5SDimitry Andric /// a reciprocal throughput of 1cy.
460b57cec5SDimitry Andric /// Each add is issued to pipeline JFPU0, while each shuffle is issued to
470b57cec5SDimitry Andric /// pipeline JFPU1. The overall pressure per iteration is reported by two
480b57cec5SDimitry Andric /// tables: the first smaller table is the resource pressure per iteration;
490b57cec5SDimitry Andric /// the second table reports resource pressure per instruction. Values are the
500b57cec5SDimitry Andric /// average resource cycles consumed by an instruction.
510b57cec5SDimitry Andric /// Every vector add from the example uses resource JFPU0 for an average of 1cy
520b57cec5SDimitry Andric /// per iteration. Consequently, the resource pressure on JFPU0 is of 2cy per
530b57cec5SDimitry Andric /// iteration.
540b57cec5SDimitry Andric ///
550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric #ifndef LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
580b57cec5SDimitry Andric #define LLVM_TOOLS_LLVM_MCA_RESOURCEPRESSUREVIEW_H
590b57cec5SDimitry Andric 
60e8d8bef9SDimitry Andric #include "Views/InstructionView.h"
610b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
620b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
630b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
640b57cec5SDimitry Andric #include "llvm/MC/MCInstPrinter.h"
650b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
66e8d8bef9SDimitry Andric #include "llvm/Support/JSON.h"
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric namespace llvm {
690b57cec5SDimitry Andric namespace mca {
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric /// This class collects resource pressure statistics and it is able to print
720b57cec5SDimitry Andric /// out all the collected information as a table to an output stream.
73e8d8bef9SDimitry Andric class ResourcePressureView : public InstructionView {
740b57cec5SDimitry Andric   unsigned LastInstructionIdx;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   // Map to quickly obtain the ResourceUsage column index from a processor
770b57cec5SDimitry Andric   // resource ID.
780b57cec5SDimitry Andric   llvm::DenseMap<unsigned, unsigned> Resource2VecIndex;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   // Table of resources used by instructions.
81*5f757f3fSDimitry Andric   std::vector<ReleaseAtCycles> ResourceUsage;
820b57cec5SDimitry Andric   unsigned NumResourceUnits;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   void printResourcePressurePerIter(llvm::raw_ostream &OS) const;
850b57cec5SDimitry Andric   void printResourcePressurePerInst(llvm::raw_ostream &OS) const;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric public:
880b57cec5SDimitry Andric   ResourcePressureView(const llvm::MCSubtargetInfo &sti,
890b57cec5SDimitry Andric                        llvm::MCInstPrinter &Printer,
900b57cec5SDimitry Andric                        llvm::ArrayRef<llvm::MCInst> S);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   void onEvent(const HWInstructionEvent &Event) override;
printView(llvm::raw_ostream & OS)930b57cec5SDimitry Andric   void printView(llvm::raw_ostream &OS) const override {
940b57cec5SDimitry Andric     printResourcePressurePerIter(OS);
950b57cec5SDimitry Andric     printResourcePressurePerInst(OS);
960b57cec5SDimitry Andric   }
getNameAsString()97e8d8bef9SDimitry Andric   StringRef getNameAsString() const override { return "ResourcePressureView"; }
98e8d8bef9SDimitry Andric   json::Value toJSON() const override;
990b57cec5SDimitry Andric };
1000b57cec5SDimitry Andric } // namespace mca
1010b57cec5SDimitry Andric } // namespace llvm
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric #endif
104