xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MCA/InstrBuilder.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===--------------------- InstrBuilder.h -----------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// A builder class for instructions that are statically analyzed by llvm-mca.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_MCA_INSTRBUILDER_H
15 #define LLVM_MCA_INSTRBUILDER_H
16 
17 #include "llvm/ADT/Hashing.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/MC/MCInstrAnalysis.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MCA/CustomBehaviour.h"
24 #include "llvm/MCA/Instruction.h"
25 #include "llvm/MCA/Support.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/Error.h"
28 
29 namespace llvm {
30 namespace mca {
31 
32 class RecycledInstErr : public ErrorInfo<RecycledInstErr> {
33   Instruction *RecycledInst;
34 
35 public:
36   LLVM_ABI static char ID;
37 
RecycledInstErr(Instruction * Inst)38   explicit RecycledInstErr(Instruction *Inst) : RecycledInst(Inst) {}
39   // Always need to carry an Instruction
40   RecycledInstErr() = delete;
41 
getInst()42   Instruction *getInst() const { return RecycledInst; }
43 
log(raw_ostream & OS)44   void log(raw_ostream &OS) const override {
45     OS << "Instruction is recycled\n";
46   }
47 
convertToErrorCode()48   std::error_code convertToErrorCode() const override {
49     return llvm::inconvertibleErrorCode();
50   }
51 };
52 
53 /// A builder class that knows how to construct Instruction objects.
54 ///
55 /// Every llvm-mca Instruction is described by an object of class InstrDesc.
56 /// An InstrDesc describes which registers are read/written by the instruction,
57 /// as well as the instruction latency and hardware resources consumed.
58 ///
59 /// This class is used by the tool to construct Instructions and instruction
60 /// descriptors (i.e. InstrDesc objects).
61 /// Information from the machine scheduling model is used to identify processor
62 /// resources that are consumed by an instruction.
63 class InstrBuilder {
64   const MCSubtargetInfo &STI;
65   const MCInstrInfo &MCII;
66   const MCRegisterInfo &MRI;
67   const MCInstrAnalysis *MCIA;
68   const InstrumentManager &IM;
69   SmallVector<uint64_t, 8> ProcResourceMasks;
70 
71   // Key is the MCI.Opcode and SchedClassID the describe the value InstrDesc
72   DenseMap<std::pair<unsigned short, unsigned>,
73            std::unique_ptr<const InstrDesc>>
74       Descriptors;
75 
76   // Key is a hash of the MCInstruction and a SchedClassID that describe the
77   // value InstrDesc
78   DenseMap<std::pair<hash_code, unsigned>, std::unique_ptr<const InstrDesc>>
79       VariantDescriptors;
80 
81   bool FirstCallInst;
82   bool FirstReturnInst;
83   unsigned CallLatency;
84 
85   using InstRecycleCallback = std::function<Instruction *(const InstrDesc &)>;
86   InstRecycleCallback InstRecycleCB;
87 
88   Expected<unsigned> getVariantSchedClassID(const MCInst &MCI, unsigned SchedClassID);
89   Expected<const InstrDesc &>
90   createInstrDescImpl(const MCInst &MCI, const SmallVector<Instrument *> &IVec);
91   Expected<const InstrDesc &>
92   getOrCreateInstrDesc(const MCInst &MCI,
93                        const SmallVector<Instrument *> &IVec);
94 
95   InstrBuilder(const InstrBuilder &) = delete;
96   InstrBuilder &operator=(const InstrBuilder &) = delete;
97 
98   void populateWrites(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
99   void populateReads(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
100   Error verifyInstrDesc(const InstrDesc &ID, const MCInst &MCI) const;
101 
102 public:
103   LLVM_ABI InstrBuilder(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
104                         const MCRegisterInfo &RI, const MCInstrAnalysis *IA,
105                         const InstrumentManager &IM, unsigned CallLatency);
106 
clear()107   void clear() {
108     Descriptors.clear();
109     VariantDescriptors.clear();
110     FirstCallInst = true;
111     FirstReturnInst = true;
112   }
113 
114   /// Set a callback which is invoked to retrieve a recycled mca::Instruction
115   /// or null if there isn't any.
setInstRecycleCallback(InstRecycleCallback CB)116   void setInstRecycleCallback(InstRecycleCallback CB) { InstRecycleCB = CB; }
117 
118   LLVM_ABI Expected<std::unique_ptr<Instruction>>
119   createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec);
120 };
121 } // namespace mca
122 } // namespace llvm
123 
124 #endif // LLVM_MCA_INSTRBUILDER_H
125