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(llvm::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
>
40 ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode
,
41 const LLVMState
&State
) const {
43 case InstructionBenchmark::Unknown
:
45 case InstructionBenchmark::Latency
:
46 return createLatencySnippetGenerator(State
);
47 case InstructionBenchmark::Uops
:
48 case InstructionBenchmark::InverseThroughput
:
49 return createUopsSnippetGenerator(State
);
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
>
70 ExegesisTarget::createLatencySnippetGenerator(const LLVMState
&State
) const {
71 return llvm::make_unique
<LatencySnippetGenerator
>(State
);
74 std::unique_ptr
<SnippetGenerator
>
75 ExegesisTarget::createUopsSnippetGenerator(const LLVMState
&State
) const {
76 return llvm::make_unique
<UopsSnippetGenerator
>(State
);
79 std::unique_ptr
<BenchmarkRunner
> ExegesisTarget::createLatencyBenchmarkRunner(
80 const LLVMState
&State
, InstructionBenchmark::ModeE Mode
) const {
81 return llvm::make_unique
<LatencyBenchmarkRunner
>(State
, Mode
);
84 std::unique_ptr
<BenchmarkRunner
>
85 ExegesisTarget::createUopsBenchmarkRunner(const LLVMState
&State
) const {
86 return llvm::make_unique
<UopsBenchmarkRunner
>(State
);
89 void ExegesisTarget::randomizeMCOperand(
90 const Instruction
&Instr
, const Variable
&Var
,
91 llvm::MCOperand
&AssignedValue
,
92 const llvm::BitVector
&ForbiddenRegs
) const {
93 const Operand
&Op
= Instr
.getPrimaryOperand(Var
);
94 switch (Op
.getExplicitOperandInfo().OperandType
) {
95 case llvm::MCOI::OperandType::OPERAND_IMMEDIATE
:
96 // FIXME: explore immediate values too.
97 AssignedValue
= llvm::MCOperand::createImm(1);
99 case llvm::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
= llvm::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
&
119 ExegesisTarget::getPfmCounters(llvm::StringRef CpuName
) const {
120 assert(std::is_sorted(
121 CpuPfmCounters
.begin(), CpuPfmCounters
.end(),
122 [](const CpuAndPfmCounters
&LHS
, const CpuAndPfmCounters
&RHS
) {
123 return strcmp(LHS
.CpuName
, RHS
.CpuName
) < 0;
125 "CpuPfmCounters table is not sorted");
129 std::lower_bound(CpuPfmCounters
.begin(), CpuPfmCounters
.end(), CpuName
);
130 if (Found
== CpuPfmCounters
.end() ||
131 llvm::StringRef(Found
->CpuName
) != CpuName
) {
133 if (CpuPfmCounters
.begin() != CpuPfmCounters
.end() &&
134 CpuPfmCounters
.begin()->CpuName
[0] == '\0') {
135 Found
= CpuPfmCounters
.begin(); // The target specifies a default.
137 return PfmCountersInfo::Default
; // No default for the target.
140 assert(Found
->PCI
&& "Missing counters");
146 // Default implementation.
147 class ExegesisDefaultTarget
: public ExegesisTarget
{
149 ExegesisDefaultTarget() : ExegesisTarget({}) {}
152 std::vector
<llvm::MCInst
> setRegTo(const llvm::MCSubtargetInfo
&STI
,
154 const llvm::APInt
&Value
) const override
{
155 llvm_unreachable("Not yet implemented");
158 bool matchesArch(llvm::Triple::ArchType Arch
) const override
{
159 llvm_unreachable("never called");
166 const ExegesisTarget
&ExegesisTarget::getDefault() {
167 static ExegesisDefaultTarget Target
;
171 } // namespace exegesis