Clang] Fix expansion of response files in -Wp after integrated-cc1 change
[llvm-project.git] / llvm / tools / llvm-exegesis / lib / Target.cpp
blob40021e2931cb02692d80d5ace5470cf9be0009f1
1 //===-- Target.cpp ----------------------------------------------*- 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 #include "Target.h"
10 #include "LatencyBenchmarkRunner.h"
11 #include "ParallelSnippetGenerator.h"
12 #include "SerialSnippetGenerator.h"
13 #include "UopsBenchmarkRunner.h"
15 namespace llvm {
16 namespace exegesis {
18 ExegesisTarget::~ExegesisTarget() {} // anchor.
20 static ExegesisTarget *FirstTarget = nullptr;
22 const ExegesisTarget *ExegesisTarget::lookup(Triple TT) {
23 for (const ExegesisTarget *T = FirstTarget; T != nullptr; T = T->Next) {
24 if (T->matchesArch(TT.getArch()))
25 return T;
27 return nullptr;
30 void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
31 if (FirstTarget == nullptr) {
32 FirstTarget = Target;
33 return;
35 if (Target->Next != nullptr)
36 return; // Already registered.
37 Target->Next = FirstTarget;
38 FirstTarget = Target;
41 std::unique_ptr<SnippetGenerator> ExegesisTarget::createSnippetGenerator(
42 InstructionBenchmark::ModeE Mode, const LLVMState &State,
43 const SnippetGenerator::Options &Opts) const {
44 switch (Mode) {
45 case InstructionBenchmark::Unknown:
46 return nullptr;
47 case InstructionBenchmark::Latency:
48 return createSerialSnippetGenerator(State, Opts);
49 case InstructionBenchmark::Uops:
50 case InstructionBenchmark::InverseThroughput:
51 return createParallelSnippetGenerator(State, Opts);
53 return nullptr;
56 std::unique_ptr<BenchmarkRunner>
57 ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
58 const LLVMState &State) const {
59 PfmCountersInfo PfmCounters = State.getPfmCounters();
60 switch (Mode) {
61 case InstructionBenchmark::Unknown:
62 return nullptr;
63 case InstructionBenchmark::Latency:
64 case InstructionBenchmark::InverseThroughput:
65 if (!PfmCounters.CycleCounter) {
66 const char *ModeName = Mode == InstructionBenchmark::Latency
67 ? "latency"
68 : "inverse_throughput";
69 report_fatal_error(Twine("can't run '").concat(ModeName).concat("' mode, "
70 "sched model does not define a cycle counter."));
72 return createLatencyBenchmarkRunner(State, Mode);
73 case InstructionBenchmark::Uops:
74 if (!PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
75 report_fatal_error("can't run 'uops' mode, sched model does not define "
76 "uops or issue counters.");
77 return createUopsBenchmarkRunner(State);
79 return nullptr;
82 std::unique_ptr<SnippetGenerator> ExegesisTarget::createSerialSnippetGenerator(
83 const LLVMState &State, const SnippetGenerator::Options &Opts) const {
84 return std::make_unique<SerialSnippetGenerator>(State, Opts);
87 std::unique_ptr<SnippetGenerator> ExegesisTarget::createParallelSnippetGenerator(
88 const LLVMState &State, const SnippetGenerator::Options &Opts) const {
89 return std::make_unique<ParallelSnippetGenerator>(State, Opts);
92 std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner(
93 const LLVMState &State, InstructionBenchmark::ModeE Mode) const {
94 return std::make_unique<LatencyBenchmarkRunner>(State, Mode);
97 std::unique_ptr<BenchmarkRunner>
98 ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
99 return std::make_unique<UopsBenchmarkRunner>(State);
102 void ExegesisTarget::randomizeMCOperand(const Instruction &Instr,
103 const Variable &Var,
104 MCOperand &AssignedValue,
105 const BitVector &ForbiddenRegs) const {
106 const Operand &Op = Instr.getPrimaryOperand(Var);
107 switch (Op.getExplicitOperandInfo().OperandType) {
108 case MCOI::OperandType::OPERAND_IMMEDIATE:
109 // FIXME: explore immediate values too.
110 AssignedValue = MCOperand::createImm(1);
111 break;
112 case MCOI::OperandType::OPERAND_REGISTER: {
113 assert(Op.isReg());
114 auto AllowedRegs = Op.getRegisterAliasing().sourceBits();
115 assert(AllowedRegs.size() == ForbiddenRegs.size());
116 for (auto I : ForbiddenRegs.set_bits())
117 AllowedRegs.reset(I);
118 AssignedValue = MCOperand::createReg(randomBit(AllowedRegs));
119 break;
121 default:
122 break;
126 static_assert(std::is_pod<PfmCountersInfo>::value,
127 "We shouldn't have dynamic initialization here");
128 const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr,
129 0u};
131 const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const {
132 assert(std::is_sorted(
133 CpuPfmCounters.begin(), CpuPfmCounters.end(),
134 [](const CpuAndPfmCounters &LHS, const CpuAndPfmCounters &RHS) {
135 return strcmp(LHS.CpuName, RHS.CpuName) < 0;
136 }) &&
137 "CpuPfmCounters table is not sorted");
139 // Find entry
140 auto Found =
141 std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName);
142 if (Found == CpuPfmCounters.end() || StringRef(Found->CpuName) != CpuName) {
143 // Use the default.
144 if (CpuPfmCounters.begin() != CpuPfmCounters.end() &&
145 CpuPfmCounters.begin()->CpuName[0] == '\0') {
146 Found = CpuPfmCounters.begin(); // The target specifies a default.
147 } else {
148 return PfmCountersInfo::Default; // No default for the target.
151 assert(Found->PCI && "Missing counters");
152 return *Found->PCI;
155 namespace {
157 // Default implementation.
158 class ExegesisDefaultTarget : public ExegesisTarget {
159 public:
160 ExegesisDefaultTarget() : ExegesisTarget({}) {}
162 private:
163 std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
164 const APInt &Value) const override {
165 llvm_unreachable("Not yet implemented");
168 bool matchesArch(Triple::ArchType Arch) const override {
169 llvm_unreachable("never called");
170 return false;
174 } // namespace
176 const ExegesisTarget &ExegesisTarget::getDefault() {
177 static ExegesisDefaultTarget Target;
178 return Target;
181 } // namespace exegesis
182 } // namespace llvm