[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
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 591edd2..5951752 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -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 @@
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;
}