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