[llvm-exegesis] Add options to SnippetGenerator.

Summary:
This adds a `-max-configs-per-opcode` option to limit the number of
configs per opcode.

Reviewers: gchatelet

Subscribers: tschuett, llvm-commits

Tags: #llvm

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

llvm-svn: 374054
diff --git a/llvm/tools/llvm-exegesis/lib/Latency.h b/llvm/tools/llvm-exegesis/lib/Latency.h
index 503f91d..0ad0c2c 100644
--- a/llvm/tools/llvm-exegesis/lib/Latency.h
+++ b/llvm/tools/llvm-exegesis/lib/Latency.h
@@ -24,7 +24,7 @@
 
 class LatencySnippetGenerator : public SnippetGenerator {
 public:
-  LatencySnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
+  using SnippetGenerator::SnippetGenerator;
   ~LatencySnippetGenerator() override;
 
   llvm::Expected<std::vector<CodeTemplate>>
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
index 8799620..1b16259 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp
@@ -33,7 +33,8 @@
 SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S)
     : llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
 
-SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {}
+SnippetGenerator::SnippetGenerator(const LLVMState &State, const Options &Opts)
+    : State(State), Opts(Opts) {}
 
 SnippetGenerator::~SnippetGenerator() = default;
 
@@ -81,6 +82,9 @@
             computeRegisterInitialValues(CT.Instructions);
         BC.Key.Config = CT.Config;
         Output.push_back(std::move(BC));
+        if (Output.size() >= Opts.MaxConfigsPerOpcode)
+          return Output; // Early exit if we exceeded the number of allowed
+                         // configs.
       }
     }
     return Output;
diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
index c2ea1c1..8e8cd6f 100644
--- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
+++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h
@@ -51,7 +51,11 @@
 // Common code for all benchmark modes.
 class SnippetGenerator {
 public:
-  explicit SnippetGenerator(const LLVMState &State);
+  struct Options {
+    unsigned MaxConfigsPerOpcode = 1;
+  };
+
+  explicit SnippetGenerator(const LLVMState &State, const Options &Opts);
 
   virtual ~SnippetGenerator();
 
@@ -66,6 +70,7 @@
 
 protected:
   const LLVMState &State;
+  const Options Opts;
 
 private:
   // API to be implemented by subclasses.
diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp
index a5ba24c..7e27627c 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Target.cpp
@@ -36,17 +36,17 @@
   FirstTarget = Target;
 }
 
-std::unique_ptr<SnippetGenerator>
-ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode,
-                                       const LLVMState &State) const {
+std::unique_ptr<SnippetGenerator> ExegesisTarget::createSnippetGenerator(
+    InstructionBenchmark::ModeE Mode, const LLVMState &State,
+    const SnippetGenerator::Options &Opts) const {
   switch (Mode) {
   case InstructionBenchmark::Unknown:
     return nullptr;
   case InstructionBenchmark::Latency:
-    return createLatencySnippetGenerator(State);
+    return createLatencySnippetGenerator(State, Opts);
   case InstructionBenchmark::Uops:
   case InstructionBenchmark::InverseThroughput:
-    return createUopsSnippetGenerator(State);
+    return createUopsSnippetGenerator(State, Opts);
   }
   return nullptr;
 }
@@ -66,14 +66,14 @@
   return nullptr;
 }
 
-std::unique_ptr<SnippetGenerator>
-ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const {
-  return std::make_unique<LatencySnippetGenerator>(State);
+std::unique_ptr<SnippetGenerator> ExegesisTarget::createLatencySnippetGenerator(
+    const LLVMState &State, const SnippetGenerator::Options &Opts) const {
+  return std::make_unique<LatencySnippetGenerator>(State, Opts);
 }
 
-std::unique_ptr<SnippetGenerator>
-ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const {
-  return std::make_unique<UopsSnippetGenerator>(State);
+std::unique_ptr<SnippetGenerator> ExegesisTarget::createUopsSnippetGenerator(
+    const LLVMState &State, const SnippetGenerator::Options &Opts) const {
+  return std::make_unique<UopsSnippetGenerator>(State, Opts);
 }
 
 std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner(
diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h
index 70313a7..511104d 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.h
+++ b/llvm/tools/llvm-exegesis/lib/Target.h
@@ -125,7 +125,8 @@
   // Creates a snippet generator for the given mode.
   std::unique_ptr<SnippetGenerator>
   createSnippetGenerator(InstructionBenchmark::ModeE Mode,
-                         const LLVMState &State) const;
+                         const LLVMState &State,
+                         const SnippetGenerator::Options &Opts) const;
   // Creates a benchmark runner for the given mode.
   std::unique_ptr<BenchmarkRunner>
   createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
@@ -151,9 +152,9 @@
   // Targets can implement their own snippet generators/benchmarks runners by
   // implementing these.
   std::unique_ptr<SnippetGenerator> virtual createLatencySnippetGenerator(
-      const LLVMState &State) const;
+      const LLVMState &State, const SnippetGenerator::Options &Opts) const;
   std::unique_ptr<SnippetGenerator> virtual createUopsSnippetGenerator(
-      const LLVMState &State) const;
+      const LLVMState &State, const SnippetGenerator::Options &Opts) const;
   std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
       const LLVMState &State, InstructionBenchmark::ModeE Mode) const;
   std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
diff --git a/llvm/tools/llvm-exegesis/lib/Uops.h b/llvm/tools/llvm-exegesis/lib/Uops.h
index 23caff2..fcfeabe 100644
--- a/llvm/tools/llvm-exegesis/lib/Uops.h
+++ b/llvm/tools/llvm-exegesis/lib/Uops.h
@@ -22,7 +22,7 @@
 
 class UopsSnippetGenerator : public SnippetGenerator {
 public:
-  UopsSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {}
+  using SnippetGenerator::SnippetGenerator;
   ~UopsSnippetGenerator() override;
 
   llvm::Expected<std::vector<CodeTemplate>>
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index ce66610..1532af8 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -462,14 +462,16 @@
                             sizeof(kUnavailableRegisters[0]));
   }
 
-  std::unique_ptr<SnippetGenerator>
-  createLatencySnippetGenerator(const LLVMState &State) const override {
-    return std::make_unique<X86LatencySnippetGenerator>(State);
+  std::unique_ptr<SnippetGenerator> createLatencySnippetGenerator(
+      const LLVMState &State,
+      const SnippetGenerator::Options &Opts) const override {
+    return std::make_unique<X86LatencySnippetGenerator>(State, Opts);
   }
 
-  std::unique_ptr<SnippetGenerator>
-  createUopsSnippetGenerator(const LLVMState &State) const override {
-    return std::make_unique<X86UopsSnippetGenerator>(State);
+  std::unique_ptr<SnippetGenerator> createUopsSnippetGenerator(
+      const LLVMState &State,
+      const SnippetGenerator::Options &Opts) const override {
+    return std::make_unique<X86UopsSnippetGenerator>(State, Opts);
   }
 
   bool matchesArch(llvm::Triple::ArchType Arch) const override {