blob: 085518c9a67771f70bf080703aab7310bb3e6d02 [file] [log] [blame]
Clement Courbet44b4c542018-06-19 11:28:59 +00001//===-- 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
Clement Courbet4860b982018-06-26 08:49:30 +000011#include "Latency.h"
Clement Courbetc0950ae2018-11-08 11:45:14 +000012#include "ROBSize.h"
Clement Courbet4860b982018-06-26 08:49:30 +000013#include "Uops.h"
14
Fangrui Song32401af2018-10-22 17:10:47 +000015namespace llvm {
Clement Courbet44b4c542018-06-19 11:28:59 +000016namespace exegesis {
17
Clement Courbetcff2caa2018-06-25 11:22:23 +000018ExegesisTarget::~ExegesisTarget() {} // anchor.
Clement Courbet44b4c542018-06-19 11:28:59 +000019
Clement Courbetcff2caa2018-06-25 11:22:23 +000020static ExegesisTarget *FirstTarget = nullptr;
Clement Courbet44b4c542018-06-19 11:28:59 +000021
Clement Courbet6fd00e32018-06-20 11:54:35 +000022const ExegesisTarget *ExegesisTarget::lookup(llvm::Triple TT) {
Clement Courbetcff2caa2018-06-25 11:22:23 +000023 for (const ExegesisTarget *T = FirstTarget; T != nullptr; T = T->Next) {
Clement Courbet6fd00e32018-06-20 11:54:35 +000024 if (T->matchesArch(TT.getArch()))
25 return T;
Clement Courbet44b4c542018-06-19 11:28:59 +000026 }
27 return nullptr;
28}
29
Clement Courbetcff2caa2018-06-25 11:22:23 +000030void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
Clement Courbet44b4c542018-06-19 11:28:59 +000031 if (FirstTarget == nullptr) {
32 FirstTarget = Target;
33 return;
34 }
Clement Courbet44b4c542018-06-19 11:28:59 +000035 if (Target->Next != nullptr)
Guillaume Chateletfb943542018-08-01 14:41:45 +000036 return; // Already registered.
Clement Courbet44b4c542018-06-19 11:28:59 +000037 Target->Next = FirstTarget;
38 FirstTarget = Target;
39}
Clement Courbet4860b982018-06-26 08:49:30 +000040
Clement Courbetd939f6d2018-09-13 07:40:53 +000041std::unique_ptr<SnippetGenerator>
Clement Courbetc0950ae2018-11-08 11:45:14 +000042ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const {
43 return llvm::make_unique<LatencySnippetGenerator>(State);
44}
45
46std::unique_ptr<SnippetGenerator>
47ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const {
48 return llvm::make_unique<UopsSnippetGenerator>(State);
49}
50
51std::unique_ptr<SnippetGenerator>
52static createROBSizeSnippetGenerator(const LLVMState &State) {
53 return llvm::make_unique<ROBSizeSnippetGenerator>(State);
54}
55
56std::unique_ptr<BenchmarkRunner>
57ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const {
58 return llvm::make_unique<LatencyBenchmarkRunner>(State);
59}
60
61std::unique_ptr<BenchmarkRunner>
62ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
63 return llvm::make_unique<UopsBenchmarkRunner>(State);
64}
65
66std::unique_ptr<SnippetGenerator>
Clement Courbetd939f6d2018-09-13 07:40:53 +000067ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode,
68 const LLVMState &State) const {
69 switch (Mode) {
70 case InstructionBenchmark::Unknown:
71 return nullptr;
72 case InstructionBenchmark::Latency:
73 return createLatencySnippetGenerator(State);
74 case InstructionBenchmark::Uops:
75 return createUopsSnippetGenerator(State);
Clement Courbetc0950ae2018-11-08 11:45:14 +000076 case InstructionBenchmark::ROBSize:
77 return createROBSizeSnippetGenerator(State);
Clement Courbetd939f6d2018-09-13 07:40:53 +000078 }
79 return nullptr;
80}
81
Clement Courbet4860b982018-06-26 08:49:30 +000082std::unique_ptr<BenchmarkRunner>
83ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
84 const LLVMState &State) const {
85 switch (Mode) {
86 case InstructionBenchmark::Unknown:
87 return nullptr;
88 case InstructionBenchmark::Latency:
Clement Courbetc0950ae2018-11-08 11:45:14 +000089 case InstructionBenchmark::ROBSize:
Clement Courbet4860b982018-06-26 08:49:30 +000090 return createLatencyBenchmarkRunner(State);
91 case InstructionBenchmark::Uops:
92 return createUopsBenchmarkRunner(State);
93 }
94 return nullptr;
95}
96
Clement Courbet41c8af32018-10-25 07:44:01 +000097static_assert(std::is_pod<PfmCountersInfo>::value,
98 "We shouldn't have dynamic initialization here");
Clement Courbetb4b6ec02018-10-25 08:11:35 +000099const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, 0u};
Clement Courbet41c8af32018-10-25 07:44:01 +0000100
101const PfmCountersInfo &
102ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const {
103 assert(std::is_sorted(
104 CpuPfmCounters.begin(), CpuPfmCounters.end(),
105 [](const CpuAndPfmCounters &LHS, const CpuAndPfmCounters &RHS) {
106 return strcmp(LHS.CpuName, RHS.CpuName) < 0;
107 }) &&
108 "CpuPfmCounters table is not sorted");
109
110 // Find entry
111 auto Found =
112 std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName);
113 if (Found == CpuPfmCounters.end() ||
114 llvm::StringRef(Found->CpuName) != CpuName) {
115 return PfmCountersInfo::Default;
116 }
117 assert(Found->PCI && "Missing counters");
118 return *Found->PCI;
119}
120
Clement Courbet4860b982018-06-26 08:49:30 +0000121namespace {
122
123// Default implementation.
124class ExegesisDefaultTarget : public ExegesisTarget {
Clement Courbet41c8af32018-10-25 07:44:01 +0000125public:
126 ExegesisDefaultTarget() : ExegesisTarget({}) {}
127
Clement Courbet4860b982018-06-26 08:49:30 +0000128private:
Guillaume Chatelet5ad29092018-09-18 11:26:27 +0000129 std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
Guillaume Chateletc96a97b2018-09-20 12:22:18 +0000130 unsigned Reg,
131 const llvm::APInt &Value) const override {
Guillaume Chatelet5ad29092018-09-18 11:26:27 +0000132 llvm_unreachable("Not yet implemented");
133 }
134
Clement Courbetc0950ae2018-11-08 11:45:14 +0000135 std::vector<llvm::MCInst> copyReg(const llvm::MCSubtargetInfo &STI,
136 unsigned ToReg, unsigned FromReg) const override {
137 llvm_unreachable("Not yet implemented");
138 }
139
Clement Courbet4860b982018-06-26 08:49:30 +0000140 bool matchesArch(llvm::Triple::ArchType Arch) const override {
141 llvm_unreachable("never called");
142 return false;
143 }
144};
145
146} // namespace
147
148const ExegesisTarget &ExegesisTarget::getDefault() {
149 static ExegesisDefaultTarget Target;
150 return Target;
151}
152
Clement Courbetcff2caa2018-06-25 11:22:23 +0000153} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +0000154} // namespace llvm