1 //===-- Target.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 /// 9 /// \file 10 /// 11 /// Classes that handle the creation of target-specific objects. This is 12 /// similar to Target/TargetRegistry. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H 17 #define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H 18 19 #include "BenchmarkResult.h" 20 #include "BenchmarkRunner.h" 21 #include "LlvmState.h" 22 #include "SnippetGenerator.h" 23 #include "llvm/ADT/Triple.h" 24 #include "llvm/CodeGen/TargetPassConfig.h" 25 #include "llvm/IR/CallingConv.h" 26 #include "llvm/IR/LegacyPassManager.h" 27 #include "llvm/MC/MCInst.h" 28 #include "llvm/MC/MCRegisterInfo.h" 29 30 namespace llvm { 31 namespace exegesis { 32 33 struct PfmCountersInfo { 34 // An optional name of a performance counter that can be used to measure 35 // cycles. 36 const char *CycleCounter; 37 38 // An optional name of a performance counter that can be used to measure 39 // uops. 40 const char *UopsCounter; 41 42 // An IssueCounter specifies how to measure uops issued to specific proc 43 // resources. 44 struct IssueCounter { 45 const char *Counter; 46 // The name of the ProcResource that this counter measures. 47 const char *ProcResName; 48 }; 49 // An optional list of IssueCounters. 50 const IssueCounter *IssueCounters; 51 unsigned NumIssueCounters; 52 53 static const PfmCountersInfo Default; 54 }; 55 56 struct CpuAndPfmCounters { 57 const char *CpuName; 58 const PfmCountersInfo *PCI; 59 bool operator<(StringRef S) const { return StringRef(CpuName) < S; } 60 }; 61 62 class ExegesisTarget { 63 public: 64 explicit ExegesisTarget(ArrayRef<CpuAndPfmCounters> CpuPfmCounters) 65 : CpuPfmCounters(CpuPfmCounters) {} 66 67 // Targets can use this to add target-specific passes in assembleToStream(); 68 virtual void addTargetSpecificPasses(PassManagerBase &PM) const {} 69 70 // Generates code to move a constant into a the given register. 71 // Precondition: Value must fit into Reg. 72 virtual std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg, 73 const APInt &Value) const = 0; 74 75 // Returns the register pointing to scratch memory, or 0 if this target 76 // does not support memory operands. The benchmark function uses the 77 // default calling convention. 78 virtual unsigned getScratchMemoryRegister(const Triple &) const { return 0; } 79 80 // Fills memory operands with references to the address at [Reg] + Offset. 81 virtual void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg, 82 unsigned Offset) const { 83 llvm_unreachable( 84 "fillMemoryOperands() requires getScratchMemoryRegister() > 0"); 85 } 86 87 // Returns a counter usable as a loop counter. 88 virtual unsigned getLoopCounterRegister(const Triple &) const { return 0; } 89 90 // Adds the code to decrement the loop counter and 91 virtual void decrementLoopCounterAndJump(MachineBasicBlock &MBB, 92 MachineBasicBlock &TargetMBB, 93 const MCInstrInfo &MII) const { 94 llvm_unreachable("decrementLoopCounterAndBranch() requires " 95 "getLoopCounterRegister() > 0"); 96 } 97 98 // Returns a list of unavailable registers. 99 // Targets can use this to prevent some registers to be automatically selected 100 // for use in snippets. 101 virtual ArrayRef<unsigned> getUnavailableRegisters() const { return {}; } 102 103 // Returns the maximum number of bytes a load/store instruction can access at 104 // once. This is typically the size of the largest register available on the 105 // processor. Note that this only used as a hint to generate independant 106 // load/stores to/from memory, so the exact returned value does not really 107 // matter as long as it's large enough. 108 virtual unsigned getMaxMemoryAccessSize() const { return 0; } 109 110 // Assigns a random operand of the right type to variable Var. 111 // The default implementation only handles generic operand types. 112 // The target is responsible for handling any operand 113 // starting from OPERAND_FIRST_TARGET. 114 virtual void randomizeMCOperand(const Instruction &Instr, const Variable &Var, 115 MCOperand &AssignedValue, 116 const BitVector &ForbiddenRegs) const; 117 118 // Returns true if this instruction is supported as a back-to-back 119 // instructions. 120 // FIXME: Eventually we should discover this dynamically. 121 virtual bool allowAsBackToBack(const Instruction &Instr) const { 122 return true; 123 } 124 125 // Creates a snippet generator for the given mode. 126 std::unique_ptr<SnippetGenerator> 127 createSnippetGenerator(InstructionBenchmark::ModeE Mode, 128 const LLVMState &State, 129 const SnippetGenerator::Options &Opts) const; 130 // Creates a benchmark runner for the given mode. 131 std::unique_ptr<BenchmarkRunner> 132 createBenchmarkRunner(InstructionBenchmark::ModeE Mode, 133 const LLVMState &State) const; 134 135 // Returns the ExegesisTarget for the given triple or nullptr if the target 136 // does not exist. 137 static const ExegesisTarget *lookup(Triple TT); 138 // Returns the default (unspecialized) ExegesisTarget. 139 static const ExegesisTarget &getDefault(); 140 // Registers a target. Not thread safe. 141 static void registerTarget(ExegesisTarget *T); 142 143 virtual ~ExegesisTarget(); 144 145 // Returns the Pfm counters for the given CPU (or the default if no pfm 146 // counters are defined for this CPU). 147 const PfmCountersInfo &getPfmCounters(StringRef CpuName) const; 148 149 private: 150 virtual bool matchesArch(Triple::ArchType Arch) const = 0; 151 152 // Targets can implement their own snippet generators/benchmarks runners by 153 // implementing these. 154 std::unique_ptr<SnippetGenerator> virtual createSerialSnippetGenerator( 155 const LLVMState &State, const SnippetGenerator::Options &Opts) const; 156 std::unique_ptr<SnippetGenerator> virtual createParallelSnippetGenerator( 157 const LLVMState &State, const SnippetGenerator::Options &Opts) const; 158 std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner( 159 const LLVMState &State, InstructionBenchmark::ModeE Mode) const; 160 std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner( 161 const LLVMState &State) const; 162 163 const ExegesisTarget *Next = nullptr; 164 const ArrayRef<CpuAndPfmCounters> CpuPfmCounters; 165 }; 166 167 } // namespace exegesis 168 } // namespace llvm 169 170 #endif // LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H 171