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
27namespace llvm {
28namespace mca {
29
30class RecycledInstErr : public ErrorInfo<RecycledInstErr> {
31  Instruction *RecycledInst;
32
33public:
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.
61class 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
100public:
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