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