[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/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 2ac92965..92d19c0 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -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>
     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 @@
   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 @@
   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 @@
 
   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 @@
     return EXIT_FAILURE;
   });
 
-  if (BenchmarkMode == BenchmarkModeE::Analysis) {
+  if (BenchmarkMode == exegesis::InstructionBenchmark::Unknown) {
     exegesis::analysisMain();
   } else {
     exegesis::benchmarkMain();