1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[llvm-exegesis] Get the BenchmarkRunner from the ExegesisTarget.

Summary:
This allows targets to override code generation for some instructions.
As an example of override, this also moves ad-hoc instruction filtering
for X86 into the X86 ExegesisTarget.

Reviewers: gchatelet

Subscribers: mgorny, tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D48587

llvm-svn: 335582
This commit is contained in:
Clement Courbet 2018-06-26 08:49:30 +00:00
parent 35344b129a
commit 6b7cfabf55
19 changed files with 183 additions and 170 deletions

View File

@ -138,7 +138,7 @@ llvm::BitVector getFunctionReservedRegs(const llvm::TargetMachine &TM) {
return MF.getSubtarget().getRegisterInfo()->getReservedRegs(MF);
}
void assembleToStream(const ExegesisTarget *ET,
void assembleToStream(const ExegesisTarget &ET,
std::unique_ptr<llvm::LLVMTargetMachine> TM,
llvm::ArrayRef<unsigned> RegsToDef,
llvm::ArrayRef<llvm::MCInst> Instructions,
@ -157,11 +157,10 @@ void assembleToStream(const ExegesisTarget *ET,
auto &Properties = MF.getProperties();
Properties.set(llvm::MachineFunctionProperties::Property::NoVRegs);
Properties.reset(llvm::MachineFunctionProperties::Property::IsSSA);
std::vector<llvm::MCInst> SnippetWithSetup;
bool IsSnippetSetupComplete = RegsToDef.empty();
if (ET) {
SnippetWithSetup =
generateSnippetSetupCode(RegsToDef, *ET, IsSnippetSetupComplete);
bool IsSnippetSetupComplete = false;
std::vector<llvm::MCInst> SnippetWithSetup =
generateSnippetSetupCode(RegsToDef, ET, IsSnippetSetupComplete);
if (!SnippetWithSetup.empty()) {
SnippetWithSetup.insert(SnippetWithSetup.end(), Instructions.begin(),
Instructions.end());
Instructions = SnippetWithSetup;
@ -190,10 +189,8 @@ void assembleToStream(const ExegesisTarget *ET,
PM.add(MMI.release());
TPC->printAndVerify("MachineFunctionGenerator::assemble");
// Add target-specific passes.
if (ET) {
ET->addTargetSpecificPasses(PM);
TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
}
ET.addTargetSpecificPasses(PM);
TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
// Adding the following passes:
// - machineverifier: checks that the MachineFunction is well formed.
// - prologepilog: saves and restore callee saved registers.

View File

@ -43,7 +43,7 @@ llvm::BitVector getFunctionReservedRegs(const llvm::TargetMachine &TM);
// Instructions. Runs a set of llvm Passes to provide correct prologue and
// epilogue. Once the MachineFunction is ready, it is assembled for TM to
// AsmStream, the temporary function is eventually discarded.
void assembleToStream(const ExegesisTarget *ET,
void assembleToStream(const ExegesisTarget &ET,
std::unique_ptr<llvm::LLVMTargetMachine> TM,
llvm::ArrayRef<unsigned> RegsToDef,
llvm::ArrayRef<llvm::MCInst> Instructions,

View File

@ -26,23 +26,26 @@ namespace exegesis {
BenchmarkFailure::BenchmarkFailure(const llvm::Twine &S)
: llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
BenchmarkRunner::InstructionFilter::~InstructionFilter() = default;
BenchmarkRunner::BenchmarkRunner(const LLVMState &State)
: State(State),
RATC(State.getRegInfo(), getFunctionReservedRegs(State.getTargetMachine())) {}
BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
InstructionBenchmark::ModeE Mode)
: State(State), RATC(State.getRegInfo(),
getFunctionReservedRegs(State.getTargetMachine())),
Mode(Mode) {}
BenchmarkRunner::~BenchmarkRunner() = default;
llvm::Expected<std::vector<InstructionBenchmark>>
BenchmarkRunner::run(unsigned Opcode, const InstructionFilter &Filter,
unsigned NumRepetitions) {
BenchmarkRunner::run(unsigned Opcode, unsigned NumRepetitions) {
const llvm::MCInstrDesc &InstrDesc = State.getInstrInfo().get(Opcode);
// Ignore instructions that we cannot run.
if (State.getInstrInfo().get(Opcode).isPseudo())
if (InstrDesc.isPseudo())
return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
if (llvm::Error E = Filter.shouldRun(State, Opcode))
return std::move(E);
if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
return llvm::make_error<BenchmarkFailure>(
"Unsupported opcode: isBranch/isIndirectBranch");
if (InstrDesc.isCall() || InstrDesc.isReturn())
return llvm::make_error<BenchmarkFailure>(
"Unsupported opcode: isCall/isReturn");
llvm::Expected<std::vector<BenchmarkConfiguration>> ConfigurationOrError =
generateConfigurations(Opcode);
@ -60,7 +63,7 @@ InstructionBenchmark
BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
unsigned Opcode, unsigned NumRepetitions) const {
InstructionBenchmark InstrBenchmark;
InstrBenchmark.Mode = getMode();
InstrBenchmark.Mode = Mode;
InstrBenchmark.CpuName = State.getTargetMachine().getTargetCPU();
InstrBenchmark.LLVMTriple =
State.getTargetMachine().getTargetTriple().normalize();

View File

@ -54,25 +54,12 @@ struct BenchmarkConfiguration {
// Common code for all benchmark modes.
class BenchmarkRunner {
public:
explicit BenchmarkRunner(const LLVMState &State);
// Subtargets can disable running benchmarks for some instructions by
// returning an error here.
class InstructionFilter {
public:
virtual ~InstructionFilter();
virtual llvm::Error shouldRun(const LLVMState &State,
unsigned Opcode) const {
return llvm::ErrorSuccess();
}
};
explicit BenchmarkRunner(const LLVMState &State, InstructionBenchmark::ModeE Mode);
virtual ~BenchmarkRunner();
llvm::Expected<std::vector<InstructionBenchmark>>
run(unsigned Opcode, const InstructionFilter &Filter,
unsigned NumRepetitions);
run(unsigned Opcode, unsigned NumRepetitions);
// Given a snippet, computes which registers the setup code needs to define.
std::vector<unsigned>
@ -83,6 +70,15 @@ protected:
const RegisterAliasingTrackerCache RATC;
private:
// API to be implemented by subclasses.
virtual llvm::Expected<SnippetPrototype>
generatePrototype(unsigned Opcode) const = 0;
virtual std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF,
const unsigned NumRepetitions) const = 0;
// Internal helpers.
InstructionBenchmark runOne(const BenchmarkConfiguration &Configuration,
unsigned Opcode, unsigned NumRepetitions) const;
@ -91,18 +87,12 @@ private:
llvm::Expected<std::vector<BenchmarkConfiguration>>
generateConfigurations(unsigned Opcode) const;
virtual InstructionBenchmark::ModeE getMode() const = 0;
virtual llvm::Expected<SnippetPrototype>
generatePrototype(unsigned Opcode) const = 0;
virtual std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF,
const unsigned NumRepetitions) const = 0;
llvm::Expected<std::string>
writeObjectFile(const BenchmarkConfiguration::Setup &Setup,
llvm::ArrayRef<llvm::MCInst> Code) const;
const InstructionBenchmark::ModeE Mode;
};
} // namespace exegesis

View File

@ -16,7 +16,6 @@ add_library(LLVMExegesis
RegisterAliasing.cpp
Target.cpp
Uops.cpp
X86.cpp
)
llvm_update_compile_flags(LLVMExegesis)

View File

@ -31,14 +31,8 @@ static bool hasMemoryOperand(const llvm::MCOperandInfo &OpInfo) {
LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
InstructionBenchmark::ModeE LatencyBenchmarkRunner::getMode() const {
return InstructionBenchmark::Latency;
}
llvm::Error LatencyBenchmarkRunner::isInfeasible(
const llvm::MCInstrDesc &MCInstrDesc) const {
if (MCInstrDesc.isPseudo())
return llvm::make_error<BenchmarkFailure>("Infeasible : is pseudo");
if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
return llvm::make_error<BenchmarkFailure>(
"Infeasible : has unknown operands");

View File

@ -22,7 +22,8 @@ namespace exegesis {
class LatencyBenchmarkRunner : public BenchmarkRunner {
public:
using BenchmarkRunner::BenchmarkRunner;
LatencyBenchmarkRunner(const LLVMState &State)
: BenchmarkRunner(State, InstructionBenchmark::Latency) {}
~LatencyBenchmarkRunner() override;
llvm::Expected<SnippetPrototype>
@ -39,8 +40,6 @@ private:
const Instruction &Instr,
const AliasingConfigurations &SelfAliasing) const;
InstructionBenchmark::ModeE getMode() const override;
std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF,
const unsigned NumRepetitions) const override;

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "LlvmState.h"
#include "Target.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@ -30,6 +31,10 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) {
TheTarget->createTargetMachine(Triple, CpuName, /*Features*/ "", Options,
llvm::Reloc::Model::Static)));
TheExegesisTarget = ExegesisTarget::lookup(TargetMachine->getTargetTriple());
if (!TheExegesisTarget) {
llvm::errs() << "no exegesis target for " << Triple << ", using default\n";
TheExegesisTarget = &ExegesisTarget::getDefault();
}
}
LLVMState::LLVMState()

View File

@ -15,7 +15,6 @@
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
#define LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
#include "Target.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
@ -41,7 +40,7 @@ public:
const llvm::TargetMachine &getTargetMachine() const { return *TargetMachine; }
std::unique_ptr<llvm::LLVMTargetMachine> createTargetMachine() const;
const ExegesisTarget *getExegesisTarget() const { return TheExegesisTarget; }
const ExegesisTarget &getExegesisTarget() const { return *TheExegesisTarget; }
bool canAssemble(const llvm::MCInst &mc_inst) const;
@ -57,7 +56,7 @@ public:
}
private:
const ExegesisTarget *TheExegesisTarget = nullptr;
const ExegesisTarget *TheExegesisTarget;
std::unique_ptr<const llvm::TargetMachine> TargetMachine;
};

View File

@ -8,6 +8,9 @@
//===----------------------------------------------------------------------===//
#include "Target.h"
#include "Latency.h"
#include "Uops.h"
namespace exegesis {
ExegesisTarget::~ExegesisTarget() {} // anchor.
@ -33,4 +36,47 @@ void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
Target->Next = FirstTarget;
FirstTarget = Target;
}
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
const LLVMState &State) const {
switch (Mode) {
case InstructionBenchmark::Unknown:
return nullptr;
case InstructionBenchmark::Latency:
return createLatencyBenchmarkRunner(State);
case InstructionBenchmark::Uops:
return createUopsBenchmarkRunner(State);
}
return nullptr;
}
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const {
return llvm::make_unique<LatencyBenchmarkRunner>(State);
}
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
return llvm::make_unique<UopsBenchmarkRunner>(State);
}
namespace {
// Default implementation.
class ExegesisDefaultTarget : public ExegesisTarget {
private:
bool matchesArch(llvm::Triple::ArchType Arch) const override {
llvm_unreachable("never called");
return false;
}
};
} // namespace
const ExegesisTarget &ExegesisTarget::getDefault() {
static ExegesisDefaultTarget Target;
return Target;
}
} // namespace exegesis

View File

@ -17,6 +17,9 @@
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
#define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
#include "BenchmarkResult.h"
#include "BenchmarkRunner.h"
#include "LlvmState.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
@ -35,9 +38,16 @@ public:
return {};
}
// Creates a benchmark runner for the given mode.
std::unique_ptr<BenchmarkRunner>
createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
const LLVMState &State) const;
// Returns the ExegesisTarget for the given triple or nullptr if the target
// does not exist.
static const ExegesisTarget *lookup(llvm::Triple TT);
// Returns the default (unspecialized) ExegesisTarget.
static const ExegesisTarget &getDefault();
// Registers a target. Not thread safe.
static void registerTarget(ExegesisTarget *T);
@ -45,6 +55,14 @@ public:
private:
virtual bool matchesArch(llvm::Triple::ArchType Arch) const = 0;
// Targets can implement their own Latency/Uops benchmarks runners by
// implementing these.
std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
const LLVMState &State) const;
std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
const LLVMState &State) const;
const ExegesisTarget *Next = nullptr;
};

View File

@ -91,8 +91,6 @@ static bool hasMemoryOperand(const llvm::MCOperandInfo &OpInfo) {
llvm::Error
UopsBenchmarkRunner::isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const {
if (MCInstrDesc.isPseudo())
return llvm::make_error<BenchmarkFailure>("Infeasible : is pseudo");
if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
return llvm::make_error<BenchmarkFailure>(
"Infeasible : has unknown operands");
@ -133,10 +131,6 @@ static void remove(llvm::BitVector &a, const llvm::BitVector &b) {
UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
InstructionBenchmark::ModeE UopsBenchmarkRunner::getMode() const {
return InstructionBenchmark::Uops;
}
llvm::Expected<SnippetPrototype>
UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
const auto &InstrDesc = State.getInstrInfo().get(Opcode);

View File

@ -21,7 +21,8 @@ namespace exegesis {
class UopsBenchmarkRunner : public BenchmarkRunner {
public:
using BenchmarkRunner::BenchmarkRunner;
UopsBenchmarkRunner(const LLVMState &State)
: BenchmarkRunner(State, InstructionBenchmark::Uops) {}
~UopsBenchmarkRunner() override;
llvm::Expected<SnippetPrototype>
@ -30,8 +31,6 @@ public:
private:
llvm::Error isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const;
InstructionBenchmark::ModeE getMode() const override;
std::vector<BenchmarkMeasure>
runMeasurements(const ExecutableFunction &EF,
const unsigned NumRepetitions) const override;

View File

@ -1,38 +0,0 @@
//===-- X86.cpp --------------------------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "X86.h"
namespace exegesis {
static llvm::Error makeError(llvm::Twine Msg) {
return llvm::make_error<llvm::StringError>(Msg,
llvm::inconvertibleErrorCode());
}
X86Filter::~X86Filter() = default;
// Test whether we can generate a snippet for this instruction.
llvm::Error X86Filter::shouldRun(const LLVMState &State,
const unsigned Opcode) const {
const auto &InstrInfo = State.getInstrInfo();
const llvm::MCInstrDesc &InstrDesc = InstrInfo.get(Opcode);
if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
return makeError("Unsupported opcode: isBranch/isIndirectBranch");
if (InstrDesc.isCall() || InstrDesc.isReturn())
return makeError("Unsupported opcode: isCall/isReturn");
const auto OpcodeName = InstrInfo.getName(Opcode);
if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
OpcodeName.startswith("ADJCALLSTACK")) {
return makeError("Unsupported opcode: Push/Pop/AdjCallStack");
}
return llvm::ErrorSuccess();
}
} // namespace exegesis

View File

@ -1,32 +0,0 @@
//===-- X86.h ---------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// X86 target-specific setup.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_X86_H
#define LLVM_TOOLS_LLVM_EXEGESIS_X86_H
#include "BenchmarkRunner.h"
#include "LlvmState.h"
namespace exegesis {
class X86Filter : public BenchmarkRunner::InstructionFilter {
public:
~X86Filter() override;
llvm::Error shouldRun(const LLVMState &State, unsigned Opcode) const override;
};
} // namespace exegesis
#endif // LLVM_TOOLS_LLVM_EXEGESIS_X86_H

View File

@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "../Target.h"
#include "../Latency.h"
#include "../Uops.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
#include "X86.h"
#include "X86RegisterInfo.h"
@ -15,8 +17,46 @@
namespace exegesis {
// Test whether we can generate a snippet for this instruction.
static llvm::Error shouldRun(const LLVMState &State, const unsigned Opcode) {
const auto &InstrInfo = State.getInstrInfo();
const auto OpcodeName = InstrInfo.getName(Opcode);
if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
OpcodeName.startswith("ADJCALLSTACK")) {
return llvm::make_error<BenchmarkFailure>(
"Unsupported opcode: Push/Pop/AdjCallStack");
}
return llvm::ErrorSuccess();
}
namespace {
class X86LatencyBenchmarkRunner : public LatencyBenchmarkRunner {
private:
using LatencyBenchmarkRunner::LatencyBenchmarkRunner;
llvm::Expected<SnippetPrototype>
generatePrototype(unsigned Opcode) const override {
if (llvm::Error E = shouldRun(State, Opcode)) {
return std::move(E);
}
return LatencyBenchmarkRunner::generatePrototype(Opcode);
}
};
class X86UopsBenchmarkRunner : public UopsBenchmarkRunner {
private:
using UopsBenchmarkRunner::UopsBenchmarkRunner;
llvm::Expected<SnippetPrototype>
generatePrototype(unsigned Opcode) const override {
if (llvm::Error E = shouldRun(State, Opcode)) {
return std::move(E);
}
return UopsBenchmarkRunner::generatePrototype(Opcode);
}
};
class ExegesisX86Target : public ExegesisTarget {
void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
// Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F.
@ -55,6 +95,16 @@ class ExegesisX86Target : public ExegesisTarget {
return {};
}
std::unique_ptr<BenchmarkRunner>
createLatencyBenchmarkRunner(const LLVMState &State) const override {
return llvm::make_unique<X86LatencyBenchmarkRunner>(State);
}
std::unique_ptr<BenchmarkRunner>
createUopsBenchmarkRunner(const LLVMState &State) const override {
return llvm::make_unique<X86UopsBenchmarkRunner>(State);
}
bool matchesArch(llvm::Triple::ArchType Arch) const override {
return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86;
}

View File

@ -16,11 +16,9 @@
#include "lib/BenchmarkResult.h"
#include "lib/BenchmarkRunner.h"
#include "lib/Clustering.h"
#include "lib/Latency.h"
#include "lib/LlvmState.h"
#include "lib/PerfHelper.h"
#include "lib/Uops.h"
#include "lib/X86.h"
#include "lib/Target.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCInstBuilder.h"
@ -47,13 +45,16 @@ static llvm::cl::opt<std::string>
static llvm::cl::opt<std::string>
BenchmarkFile("benchmarks-file", llvm::cl::desc(""), llvm::cl::init(""));
enum class BenchmarkModeE { Latency, Uops, Analysis };
static llvm::cl::opt<BenchmarkModeE> BenchmarkMode(
static llvm::cl::opt<exegesis::InstructionBenchmark::ModeE> BenchmarkMode(
"mode", llvm::cl::desc("the mode to run"),
llvm::cl::values(
clEnumValN(BenchmarkModeE::Latency, "latency", "Instruction Latency"),
clEnumValN(BenchmarkModeE::Uops, "uops", "Uop Decomposition"),
clEnumValN(BenchmarkModeE::Analysis, "analysis", "Analysis")));
llvm::cl::values(clEnumValN(exegesis::InstructionBenchmark::Latency,
"latency", "Instruction Latency"),
clEnumValN(exegesis::InstructionBenchmark::Uops, "uops",
"Uop Decomposition"),
// When not asking for a specific benchmark mode, we'll
// analyse the results.
clEnumValN(exegesis::InstructionBenchmark::Unknown,
"analysis", "Analysis")));
static llvm::cl::opt<unsigned>
NumRepetitions("num-repetitions",
@ -128,9 +129,6 @@ void benchmarkMain() {
LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET();
#endif
// FIXME: Target-specific filter.
X86Filter Filter;
const LLVMState State;
const auto Opcode = GetOpcodeOrDie(State.getInstrInfo());
@ -146,16 +144,10 @@ void benchmarkMain() {
if (!State.getSubtargetInfo().getSchedModel().hasExtraProcessorInfo())
llvm::report_fatal_error("sched model is missing extra processor info!");
std::unique_ptr<BenchmarkRunner> Runner;
switch (BenchmarkMode) {
case BenchmarkModeE::Latency:
Runner = llvm::make_unique<LatencyBenchmarkRunner>(State);
break;
case BenchmarkModeE::Uops:
Runner = llvm::make_unique<UopsBenchmarkRunner>(State);
break;
case BenchmarkModeE::Analysis:
llvm_unreachable("not a benchmark");
const std::unique_ptr<BenchmarkRunner> Runner =
State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
if (!Runner) {
llvm::report_fatal_error("cannot create benchmark runner");
}
if (NumRepetitions == 0)
@ -167,7 +159,7 @@ void benchmarkMain() {
const BenchmarkResultContext Context = getBenchmarkResultContext(State);
std::vector<InstructionBenchmark> Results =
ExitOnErr(Runner->run(Opcode, Filter, NumRepetitions));
ExitOnErr(Runner->run(Opcode, NumRepetitions));
for (InstructionBenchmark &Result : Results)
ExitOnErr(Result.writeYaml(Context, BenchmarkFile));
@ -245,7 +237,7 @@ int main(int Argc, char **Argv) {
return EXIT_FAILURE;
});
if (BenchmarkMode == BenchmarkModeE::Analysis) {
if (BenchmarkMode == exegesis::InstructionBenchmark::Unknown) {
exegesis::analysisMain();
} else {
exegesis::benchmarkMain();

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Assembler.h"
#include "Target.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@ -36,11 +37,11 @@ protected:
}
template <class... Bs> inline void Check(llvm::MCInst MCInst, Bs... Bytes) {
CheckWithSetup(nullptr, {}, MCInst, Bytes...);
CheckWithSetup(ExegesisTarget::getDefault(), {}, MCInst, Bytes...);
}
template <class... Bs>
inline void CheckWithSetup(const ExegesisTarget *ET,
inline void CheckWithSetup(const ExegesisTarget &ET,
llvm::ArrayRef<unsigned> RegsToDef,
llvm::MCInst MCInst, Bs... Bytes) {
ExecutableFunction Function =
@ -67,7 +68,7 @@ private:
}
ExecutableFunction
assembleToFunction(const ExegesisTarget *ET,
assembleToFunction(const ExegesisTarget &ET,
llvm::ArrayRef<unsigned> RegsToDef,
llvm::ArrayRef<llvm::MCInst> Instructions) {
llvm::SmallString<256> Buffer;

View File

@ -217,17 +217,14 @@ TEST_F(UopsSnippetGeneratorTest, NoTiedVariables) {
class FakeBenchmarkRunner : public BenchmarkRunner {
public:
using BenchmarkRunner::BenchmarkRunner;
FakeBenchmarkRunner(const LLVMState &State)
: BenchmarkRunner(State, InstructionBenchmark::Unknown) {}
Instruction createInstruction(unsigned Opcode) {
return Instruction(State.getInstrInfo().get(Opcode), RATC);
}
private:
InstructionBenchmark::ModeE getMode() const override {
return InstructionBenchmark::Unknown;
}
llvm::Expected<SnippetPrototype>
generatePrototype(unsigned Opcode) const override {
return llvm::make_error<llvm::StringError>("not implemented",