1 //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
16 ExegesisTarget::~ExegesisTarget() {} // anchor.
18 static ExegesisTarget
*FirstTarget
= nullptr;
20 const ExegesisTarget
*ExegesisTarget::lookup(Triple TT
) {
21 for (const ExegesisTarget
*T
= FirstTarget
; T
!= nullptr; T
= T
->Next
) {
22 if (T
->matchesArch(TT
.getArch()))
28 void ExegesisTarget::registerTarget(ExegesisTarget
*Target
) {
29 if (FirstTarget
== nullptr) {
33 if (Target
->Next
!= nullptr)
34 return; // Already registered.
35 Target
->Next
= FirstTarget
;
39 std::unique_ptr
<SnippetGenerator
> ExegesisTarget::createSnippetGenerator(
40 InstructionBenchmark::ModeE Mode
, const LLVMState
&State
,
41 const SnippetGenerator::Options
&Opts
) const {
43 case InstructionBenchmark::Unknown
:
45 case InstructionBenchmark::Latency
:
46 return createLatencySnippetGenerator(State
, Opts
);
47 case InstructionBenchmark::Uops
:
48 case InstructionBenchmark::InverseThroughput
:
49 return createUopsSnippetGenerator(State
, Opts
);
54 std::unique_ptr
<BenchmarkRunner
>
55 ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode
,
56 const LLVMState
&State
) const {
58 case InstructionBenchmark::Unknown
:
60 case InstructionBenchmark::Latency
:
61 case InstructionBenchmark::InverseThroughput
:
62 return createLatencyBenchmarkRunner(State
, Mode
);
63 case InstructionBenchmark::Uops
:
64 return createUopsBenchmarkRunner(State
);
69 std::unique_ptr
<SnippetGenerator
> ExegesisTarget::createLatencySnippetGenerator(
70 const LLVMState
&State
, const SnippetGenerator::Options
&Opts
) const {
71 return std::make_unique
<LatencySnippetGenerator
>(State
, Opts
);
74 std::unique_ptr
<SnippetGenerator
> ExegesisTarget::createUopsSnippetGenerator(
75 const LLVMState
&State
, const SnippetGenerator::Options
&Opts
) const {
76 return std::make_unique
<UopsSnippetGenerator
>(State
, Opts
);
79 std::unique_ptr
<BenchmarkRunner
> ExegesisTarget::createLatencyBenchmarkRunner(
80 const LLVMState
&State
, InstructionBenchmark::ModeE Mode
) const {
81 return std::make_unique
<LatencyBenchmarkRunner
>(State
, Mode
);
84 std::unique_ptr
<BenchmarkRunner
>
85 ExegesisTarget::createUopsBenchmarkRunner(const LLVMState
&State
) const {
86 return std::make_unique
<UopsBenchmarkRunner
>(State
);
89 void ExegesisTarget::randomizeMCOperand(const Instruction
&Instr
,
91 MCOperand
&AssignedValue
,
92 const BitVector
&ForbiddenRegs
) const {
93 const Operand
&Op
= Instr
.getPrimaryOperand(Var
);
94 switch (Op
.getExplicitOperandInfo().OperandType
) {
95 case MCOI::OperandType::OPERAND_IMMEDIATE
:
96 // FIXME: explore immediate values too.
97 AssignedValue
= MCOperand::createImm(1);
99 case MCOI::OperandType::OPERAND_REGISTER
: {
101 auto AllowedRegs
= Op
.getRegisterAliasing().sourceBits();
102 assert(AllowedRegs
.size() == ForbiddenRegs
.size());
103 for (auto I
: ForbiddenRegs
.set_bits())
104 AllowedRegs
.reset(I
);
105 AssignedValue
= MCOperand::createReg(randomBit(AllowedRegs
));
113 static_assert(std::is_pod
<PfmCountersInfo
>::value
,
114 "We shouldn't have dynamic initialization here");
115 const PfmCountersInfo
PfmCountersInfo::Default
= {nullptr, nullptr, nullptr,
118 const PfmCountersInfo
&ExegesisTarget::getPfmCounters(StringRef CpuName
) const {
119 assert(std::is_sorted(
120 CpuPfmCounters
.begin(), CpuPfmCounters
.end(),
121 [](const CpuAndPfmCounters
&LHS
, const CpuAndPfmCounters
&RHS
) {
122 return strcmp(LHS
.CpuName
, RHS
.CpuName
) < 0;
124 "CpuPfmCounters table is not sorted");
128 std::lower_bound(CpuPfmCounters
.begin(), CpuPfmCounters
.end(), CpuName
);
129 if (Found
== CpuPfmCounters
.end() || StringRef(Found
->CpuName
) != CpuName
) {
131 if (CpuPfmCounters
.begin() != CpuPfmCounters
.end() &&
132 CpuPfmCounters
.begin()->CpuName
[0] == '\0') {
133 Found
= CpuPfmCounters
.begin(); // The target specifies a default.
135 return PfmCountersInfo::Default
; // No default for the target.
138 assert(Found
->PCI
&& "Missing counters");
144 // Default implementation.
145 class ExegesisDefaultTarget
: public ExegesisTarget
{
147 ExegesisDefaultTarget() : ExegesisTarget({}) {}
150 std::vector
<MCInst
> setRegTo(const MCSubtargetInfo
&STI
, unsigned Reg
,
151 const APInt
&Value
) const override
{
152 llvm_unreachable("Not yet implemented");
155 bool matchesArch(Triple::ArchType Arch
) const override
{
156 llvm_unreachable("never called");
163 const ExegesisTarget
&ExegesisTarget::getDefault() {
164 static ExegesisDefaultTarget Target
;
168 } // namespace exegesis