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, const SmallVector<Instrument *> &IVec); 88 Expected<const InstrDesc &> 89 getOrCreateInstrDesc(const MCInst &MCI, 90 const SmallVector<Instrument *> &IVec); 91 92 InstrBuilder(const InstrBuilder &) = delete; 93 InstrBuilder &operator=(const InstrBuilder &) = delete; 94 95 void populateWrites(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID); 96 void populateReads(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID); 97 Error verifyInstrDesc(const InstrDesc &ID, const MCInst &MCI) const; 98 99 public: 100 InstrBuilder(const MCSubtargetInfo &STI, const MCInstrInfo &MCII, 101 const MCRegisterInfo &RI, const MCInstrAnalysis *IA, 102 const InstrumentManager &IM); 103 104 void clear() { 105 Descriptors.clear(); 106 VariantDescriptors.clear(); 107 FirstCallInst = true; 108 FirstReturnInst = true; 109 } 110 111 /// Set a callback which is invoked to retrieve a recycled mca::Instruction 112 /// or null if there isn't any. 113 void setInstRecycleCallback(InstRecycleCallback CB) { InstRecycleCB = CB; } 114 115 Expected<std::unique_ptr<Instruction>> 116 createInstruction(const MCInst &MCI, const SmallVector<Instrument *> &IVec); 117 }; 118 } // namespace mca 119 } // namespace llvm 120 121 #endif // LLVM_MCA_INSTRBUILDER_H 122