1 //===-- Target.cpp ----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #include "Target.h" 10 11 #include "Latency.h" 12 #include "Uops.h" 13 14 namespace llvm { 15 namespace exegesis { 16 17 ExegesisTarget::~ExegesisTarget() {} // anchor. 18 19 static ExegesisTarget *FirstTarget = nullptr; 20 21 const ExegesisTarget *ExegesisTarget::lookup(llvm::Triple TT) { 22 for (const ExegesisTarget *T = FirstTarget; T != nullptr; T = T->Next) { 23 if (T->matchesArch(TT.getArch())) 24 return T; 25 } 26 return nullptr; 27 } 28 29 void ExegesisTarget::registerTarget(ExegesisTarget *Target) { 30 if (FirstTarget == nullptr) { 31 FirstTarget = Target; 32 return; 33 } 34 if (Target->Next != nullptr) 35 return; // Already registered. 36 Target->Next = FirstTarget; 37 FirstTarget = Target; 38 } 39 40 std::unique_ptr<SnippetGenerator> 41 ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode, 42 const LLVMState &State) const { 43 switch (Mode) { 44 case InstructionBenchmark::Unknown: 45 return nullptr; 46 case InstructionBenchmark::Latency: 47 return createLatencySnippetGenerator(State); 48 case InstructionBenchmark::Uops: 49 return createUopsSnippetGenerator(State); 50 } 51 return nullptr; 52 } 53 54 std::unique_ptr<BenchmarkRunner> 55 ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode, 56 const LLVMState &State) const { 57 switch (Mode) { 58 case InstructionBenchmark::Unknown: 59 return nullptr; 60 case InstructionBenchmark::Latency: 61 return createLatencyBenchmarkRunner(State); 62 case InstructionBenchmark::Uops: 63 return createUopsBenchmarkRunner(State); 64 } 65 return nullptr; 66 } 67 68 std::unique_ptr<SnippetGenerator> 69 ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const { 70 return llvm::make_unique<LatencySnippetGenerator>(State); 71 } 72 73 std::unique_ptr<SnippetGenerator> 74 ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const { 75 return llvm::make_unique<UopsSnippetGenerator>(State); 76 } 77 78 std::unique_ptr<BenchmarkRunner> 79 ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const { 80 return llvm::make_unique<LatencyBenchmarkRunner>(State); 81 } 82 83 std::unique_ptr<BenchmarkRunner> 84 ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const { 85 return llvm::make_unique<UopsBenchmarkRunner>(State); 86 } 87 88 static_assert(std::is_pod<PfmCountersInfo>::value, 89 "We shouldn't have dynamic initialization here"); 90 const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, 91 0u}; 92 93 const PfmCountersInfo & 94 ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const { 95 assert(std::is_sorted( 96 CpuPfmCounters.begin(), CpuPfmCounters.end(), 97 [](const CpuAndPfmCounters &LHS, const CpuAndPfmCounters &RHS) { 98 return strcmp(LHS.CpuName, RHS.CpuName) < 0; 99 }) && 100 "CpuPfmCounters table is not sorted"); 101 102 // Find entry 103 auto Found = 104 std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName); 105 if (Found == CpuPfmCounters.end() || 106 llvm::StringRef(Found->CpuName) != CpuName) { 107 // Use the default. 108 if (CpuPfmCounters.begin() != CpuPfmCounters.end() && 109 CpuPfmCounters.begin()->CpuName[0] == '\0') { 110 Found = CpuPfmCounters.begin(); // The target specifies a default. 111 } else { 112 return PfmCountersInfo::Default; // No default for the target. 113 } 114 } 115 assert(Found->PCI && "Missing counters"); 116 return *Found->PCI; 117 } 118 119 namespace { 120 121 // Default implementation. 122 class ExegesisDefaultTarget : public ExegesisTarget { 123 public: 124 ExegesisDefaultTarget() : ExegesisTarget({}) {} 125 126 private: 127 std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, 128 unsigned Reg, 129 const llvm::APInt &Value) const override { 130 llvm_unreachable("Not yet implemented"); 131 } 132 133 bool matchesArch(llvm::Triple::ArchType Arch) const override { 134 llvm_unreachable("never called"); 135 return false; 136 } 137 }; 138 139 } // namespace 140 141 const ExegesisTarget &ExegesisTarget::getDefault() { 142 static ExegesisDefaultTarget Target; 143 return Target; 144 } 145 146 } // namespace exegesis 147 } // namespace llvm 148