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