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