[llvm-exegesis] Make BenchmarkRunner handle multiple configurations.

Summary: BenchmarkRunner subclasses can now create many configurations - although this patch still generates one.

Reviewers: courbet

Subscribers: tschuett, llvm-commits

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

llvm-svn: 334197
diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp
index 7f1079e..be74a92 100644
--- a/llvm/tools/llvm-exegesis/lib/Uops.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp
@@ -134,51 +134,43 @@
     a.reset(I);
 }
 
-static llvm::Error makeError(llvm::Twine Msg) {
-  return llvm::make_error<llvm::StringError>(Msg,
-                                             llvm::inconvertibleErrorCode());
-}
-
 UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
 
 InstructionBenchmark::ModeE UopsBenchmarkRunner::getMode() const {
   return InstructionBenchmark::Uops;
 }
 
-llvm::Expected<BenchmarkConfiguration>
-UopsBenchmarkRunner::createConfiguration(RegisterAliasingTrackerCache &RATC,
-                                         unsigned Opcode,
-                                         llvm::raw_ostream &Info) const {
-  BenchmarkConfiguration Configuration;
-  std::vector<llvm::MCInst> &Snippet = Configuration.Snippet;
+llvm::Expected<std::vector<BenchmarkConfiguration>>
+UopsBenchmarkRunner::createConfigurations(RegisterAliasingTrackerCache &RATC,
+                                          unsigned Opcode) const {
   const llvm::MCInstrDesc &MCInstrDesc = MCInstrInfo.get(Opcode);
   const Instruction Instruction(MCInstrDesc, RATC);
 
   std::string Error;
-  if (isInfeasible(Instruction, Error)) {
-    llvm::report_fatal_error(llvm::Twine("Infeasible : ").concat(Error));
-  }
+  if (isInfeasible(Instruction, Error))
+    return llvm::make_error<llvm::StringError>(
+        llvm::Twine("Infeasible : ").concat(Error),
+        llvm::inconvertibleErrorCode());
 
+  BenchmarkConfiguration Conf;
   const AliasingConfigurations SelfAliasing(Instruction, Instruction);
   if (SelfAliasing.empty()) {
-    Info << "instruction is parallel, repeating a random one.\n";
-    Snippet.push_back(randomizeUnsetVariablesAndBuild(Instruction));
-    return Configuration;
+    Conf.Info = "instruction is parallel, repeating a random one.";
+    Conf.Snippet = {randomizeUnsetVariablesAndBuild(Instruction)};
+    return std::vector<BenchmarkConfiguration>{Conf};
   }
   if (SelfAliasing.hasImplicitAliasing()) {
-    Info << "instruction is serial, repeating a random one.\n";
-    Snippet.push_back(randomizeUnsetVariablesAndBuild(Instruction));
-    return Configuration;
+    Conf.Info = "instruction is serial, repeating a random one.";
+    Conf.Snippet = {randomizeUnsetVariablesAndBuild(Instruction)};
+    return std::vector<BenchmarkConfiguration>{Conf};
   }
   const auto TiedVariables = getTiedVariables(Instruction);
   if (!TiedVariables.empty()) {
-    if (TiedVariables.size() > 1) {
-      Info << "Not yet implemented, don't know how to handle several tied "
-              "variables\n";
-      return makeError("Infeasible : don't know how to handle several tied "
-                       "variables");
-    }
-    Info << "instruction has tied variables using static renaming.\n";
+    if (TiedVariables.size() > 1)
+      return llvm::make_error<llvm::StringError>(
+          "Infeasible : don't know how to handle several tied variables",
+          llvm::inconvertibleErrorCode());
+    Conf.Info = "instruction has tied variables using static renaming.";
     Variable *Var = TiedVariables.front();
     assert(Var);
     assert(!Var->TiedOperands.empty());
@@ -187,9 +179,9 @@
     for (const llvm::MCPhysReg Reg : Operand.Tracker->sourceBits().set_bits()) {
       clearVariableAssignments(Instruction);
       Var->AssignedValue = llvm::MCOperand::createReg(Reg);
-      Snippet.push_back(randomizeUnsetVariablesAndBuild(Instruction));
+      Conf.Snippet.push_back(randomizeUnsetVariablesAndBuild(Instruction));
     }
-    return Configuration;
+    return std::vector<BenchmarkConfiguration>{Conf};
   }
   // No tied variables, we pick random values for defs.
   llvm::BitVector Defs(MCRegisterInfo.getNumRegs());
@@ -217,10 +209,10 @@
       Op.Var->AssignedValue = llvm::MCOperand::createReg(RandomReg);
     }
   }
-  Info
-      << "instruction has no tied variables picking Uses different from defs\n";
-  Snippet.push_back(randomizeUnsetVariablesAndBuild(Instruction));
-  return Configuration;
+  Conf.Info =
+      "instruction has no tied variables picking Uses different from defs";
+  Conf.Snippet = {randomizeUnsetVariablesAndBuild(Instruction)};
+  return std::vector<BenchmarkConfiguration>{Conf};
 }
 
 std::vector<BenchmarkMeasure>