[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/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp
index 92e3e46..44156c8 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Target.cpp
@@ -8,6 +8,9 @@
 //===----------------------------------------------------------------------===//
 #include "Target.h"
 
+#include "Latency.h"
+#include "Uops.h"
+
 namespace exegesis {
 
 ExegesisTarget::~ExegesisTarget() {} // anchor.
@@ -33,4 +36,47 @@
   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