[llvm] r334197 - [llvm-exegesis] Make BenchmarkRunner handle multiple configurations.

Guillaume Chatelet via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 7 07:00:29 PDT 2018


Author: gchatelet
Date: Thu Jun  7 07:00:29 2018
New Revision: 334197

URL: http://llvm.org/viewvc/llvm-project?rev=334197&view=rev
Log:
[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

Modified:
    llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
    llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
    llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Latency.h
    llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Uops.h
    llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp

Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp Thu Jun  7 07:00:29 2018
@@ -24,54 +24,57 @@
 namespace exegesis {
 
 BenchmarkRunner::InstructionFilter::~InstructionFilter() = default;
+
 BenchmarkRunner::BenchmarkRunner(const LLVMState &State)
     : State(State), MCInstrInfo(State.getInstrInfo()),
       MCRegisterInfo(State.getRegInfo()),
       RATC(MCRegisterInfo,
            getFunctionReservedRegs(*State.createTargetMachine())) {}
+
 BenchmarkRunner::~BenchmarkRunner() = default;
 
-InstructionBenchmark BenchmarkRunner::run(unsigned Opcode,
-                                          const InstructionFilter &Filter,
-                                          unsigned NumRepetitions) {
-  InstructionBenchmark InstrBenchmark;
+llvm::Expected<std::vector<InstructionBenchmark>>
+BenchmarkRunner::run(unsigned Opcode, const InstructionFilter &Filter,
+                     unsigned NumRepetitions) {
+  // Ignore instructions that we cannot run.
+  if (State.getInstrInfo().get(Opcode).isPseudo())
+    return llvm::make_error<llvm::StringError>("Unsupported opcode: isPseudo",
+                                               llvm::inconvertibleErrorCode());
+
+  if (llvm::Error E = Filter.shouldRun(State, Opcode))
+    return std::move(E);
 
+  llvm::Expected<std::vector<BenchmarkConfiguration>> ConfigurationOrError =
+      createConfigurations(RATC, Opcode);
+
+  if (llvm::Error E = ConfigurationOrError.takeError())
+    return std::move(E);
+
+  std::vector<InstructionBenchmark> InstrBenchmarks;
+  for (const BenchmarkConfiguration &Conf : ConfigurationOrError.get())
+    InstrBenchmarks.push_back(runOne(Conf, Opcode, NumRepetitions));
+  return InstrBenchmarks;
+}
+
+InstructionBenchmark
+BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
+                        unsigned Opcode, unsigned NumRepetitions) const {
+  InstructionBenchmark InstrBenchmark;
   InstrBenchmark.Key.OpcodeName = State.getInstrInfo().getName(Opcode);
   InstrBenchmark.Mode = getMode();
   InstrBenchmark.CpuName = State.getCpuName();
   InstrBenchmark.LLVMTriple = State.getTriple();
   InstrBenchmark.NumRepetitions = NumRepetitions;
+  InstrBenchmark.Info = Configuration.Info;
 
-  // Ignore instructions that we cannot run.
-  if (State.getInstrInfo().get(Opcode).isPseudo()) {
-    InstrBenchmark.Error = "Unsupported opcode: isPseudo";
-    return InstrBenchmark;
-  }
-  if (llvm::Error E = Filter.shouldRun(State, Opcode)) {
-    InstrBenchmark.Error = llvm::toString(std::move(E));
-    return InstrBenchmark;
-  }
-  llvm::raw_string_ostream InfoStream(InstrBenchmark.Info);
-  llvm::Expected<BenchmarkConfiguration> ConfigurationOrError =
-      createConfiguration(RATC, Opcode, InfoStream);
-  if (llvm::Error E = ConfigurationOrError.takeError()) {
-    InstrBenchmark.Error = llvm::toString(std::move(E));
-    return InstrBenchmark;
-  }
-  BenchmarkConfiguration &Configuration = ConfigurationOrError.get();
   const std::vector<llvm::MCInst> &Snippet = Configuration.Snippet;
   if (Snippet.empty()) {
     InstrBenchmark.Error = "Empty snippet";
     return InstrBenchmark;
   }
-  for (const auto &MCInst : Snippet) {
+
+  for (const auto &MCInst : Snippet)
     InstrBenchmark.Key.Instructions.push_back(MCInst);
-  }
-  InfoStream << "Snippet:\n";
-  for (const auto &MCInst : Snippet) {
-    DumpMCInst(MCRegisterInfo, MCInstrInfo, MCInst, InfoStream);
-    InfoStream << "\n";
-  }
 
   std::vector<llvm::MCInst> Code;
   for (int I = 0; I < InstrBenchmark.NumRepetitions; ++I)

Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h Thu Jun  7 07:00:29 2018
@@ -35,6 +35,9 @@ struct BenchmarkConfiguration {
 
   // The sequence of instructions that are to be repeated.
   std::vector<llvm::MCInst> Snippet;
+
+  // Informations about how this configuration was built.
+  std::string Info;
 };
 
 // Common code for all benchmark modes.
@@ -56,8 +59,9 @@ public:
 
   virtual ~BenchmarkRunner();
 
-  InstructionBenchmark run(unsigned Opcode, const InstructionFilter &Filter,
-                           unsigned NumRepetitions);
+  llvm::Expected<std::vector<InstructionBenchmark>>
+  run(unsigned Opcode, const InstructionFilter &Filter,
+      unsigned NumRepetitions);
 
 protected:
   const LLVMState &State;
@@ -65,11 +69,14 @@ protected:
   const llvm::MCRegisterInfo &MCRegisterInfo;
 
 private:
+  InstructionBenchmark runOne(const BenchmarkConfiguration &Configuration,
+                              unsigned Opcode, unsigned NumRepetitions) const;
+
   virtual InstructionBenchmark::ModeE getMode() const = 0;
 
-  virtual llvm::Expected<BenchmarkConfiguration>
-  createConfiguration(RegisterAliasingTrackerCache &RATC, unsigned Opcode,
-                      llvm::raw_ostream &Debug) const = 0;
+  virtual llvm::Expected<std::vector<BenchmarkConfiguration>>
+  createConfigurations(RegisterAliasingTrackerCache &RATC,
+                       unsigned Opcode) const = 0;
 
   virtual std::vector<BenchmarkMeasure>
   runMeasurements(const ExecutableFunction &EF,

Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp Thu Jun  7 07:00:29 2018
@@ -45,40 +45,35 @@ static bool IsInfeasible(const Instructi
   return false;
 }
 
-static llvm::Error makeError(llvm::Twine Msg) {
-  return llvm::make_error<llvm::StringError>(Msg,
-                                             llvm::inconvertibleErrorCode());
-}
-
 LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
 
 InstructionBenchmark::ModeE LatencyBenchmarkRunner::getMode() const {
   return InstructionBenchmark::Latency;
 }
 
-llvm::Expected<BenchmarkConfiguration>
-LatencyBenchmarkRunner::createConfiguration(RegisterAliasingTrackerCache &RATC,
-                                            unsigned Opcode,
-                                            llvm::raw_ostream &Info) const {
-  BenchmarkConfiguration Configuration;
-  std::vector<llvm::MCInst> &Snippet = Configuration.Snippet;
+llvm::Expected<std::vector<BenchmarkConfiguration>>
+LatencyBenchmarkRunner::createConfigurations(RegisterAliasingTrackerCache &RATC,
+                                             unsigned Opcode) const {
   const llvm::MCInstrDesc &MCInstrDesc = MCInstrInfo.get(Opcode);
   const Instruction ThisInstruction(MCInstrDesc, RATC);
 
   std::string Error;
   if (IsInfeasible(ThisInstruction, Error))
-    return makeError(llvm::Twine("Infeasible : ").concat(Error));
+    return llvm::make_error<llvm::StringError>(
+        llvm::Twine("Infeasible : ").concat(Error),
+        llvm::inconvertibleErrorCode());
 
+  BenchmarkConfiguration Conf;
   const AliasingConfigurations SelfAliasing(ThisInstruction, ThisInstruction);
   if (!SelfAliasing.empty()) {
     if (!SelfAliasing.hasImplicitAliasing()) {
-      Info << "explicit self cycles, selecting one aliasing configuration.\n";
+      Conf.Info = "explicit self cycles, selecting one aliasing Conf.";
       setRandomAliasing(SelfAliasing);
     } else {
-      Info << "implicit Self cycles, picking random values.\n";
+      Conf.Info = "implicit Self cycles, picking random values.";
     }
-    Snippet.push_back(randomizeUnsetVariablesAndBuild(ThisInstruction));
-    return Configuration;
+    Conf.Snippet = {randomizeUnsetVariablesAndBuild(ThisInstruction)};
+    return std::vector<BenchmarkConfiguration>{Conf};
   }
 
   // Let's try to create a dependency through another opcode.
@@ -99,15 +94,18 @@ LatencyBenchmarkRunner::createConfigurat
       continue;
     setRandomAliasing(Forward);
     setRandomAliasing(Back);
-    Info << "creating cycle through " << MCInstrInfo.getName(OtherOpcode)
-         << ".\n";
-    Snippet.push_back(randomizeUnsetVariablesAndBuild(ThisInstruction));
-    Snippet.push_back(randomizeUnsetVariablesAndBuild(OtherInstruction));
-    return Configuration;
+    Conf.Info = llvm::Twine("creating cycle through ")
+                    .concat(MCInstrInfo.getName(OtherOpcode))
+                    .concat(".")
+                    .str();
+    Conf.Snippet.push_back(randomizeUnsetVariablesAndBuild(ThisInstruction));
+    Conf.Snippet.push_back(randomizeUnsetVariablesAndBuild(OtherInstruction));
+    return std::vector<BenchmarkConfiguration>{Conf};
   }
 
-  return makeError(
-      "Infeasible : Didn't find any scheme to make the instruction serial\n");
+  return llvm::make_error<llvm::StringError>(
+      "Infeasible : Didn't find any scheme to make the instruction serial",
+      llvm::inconvertibleErrorCode());
 }
 
 std::vector<BenchmarkMeasure>

Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.h?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.h Thu Jun  7 07:00:29 2018
@@ -27,9 +27,9 @@ public:
 private:
   InstructionBenchmark::ModeE getMode() const override;
 
-  llvm::Expected<BenchmarkConfiguration>
-  createConfiguration(RegisterAliasingTrackerCache &RATC, unsigned OpcodeIndex,
-                      llvm::raw_ostream &Info) const override;
+  llvm::Expected<std::vector<BenchmarkConfiguration>>
+  createConfigurations(RegisterAliasingTrackerCache &RATC,
+                       unsigned OpcodeIndex) const override;
 
   std::vector<BenchmarkMeasure>
   runMeasurements(const ExecutableFunction &EF,

Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp Thu Jun  7 07:00:29 2018
@@ -134,51 +134,43 @@ static void remove(llvm::BitVector &a, c
     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 @@ UopsBenchmarkRunner::createConfiguration
     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 @@ UopsBenchmarkRunner::createConfiguration
       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>

Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.h?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.h Thu Jun  7 07:00:29 2018
@@ -27,9 +27,9 @@ public:
 private:
   InstructionBenchmark::ModeE getMode() const override;
 
-  llvm::Expected<BenchmarkConfiguration>
-  createConfiguration(RegisterAliasingTrackerCache &RATC, unsigned Opcode,
-                      llvm::raw_ostream &Info) const override;
+  llvm::Expected<std::vector<BenchmarkConfiguration>>
+  createConfigurations(RegisterAliasingTrackerCache &RATC,
+                       unsigned Opcode) const override;
 
   std::vector<BenchmarkMeasure>
   runMeasurements(const ExecutableFunction &EF,

Modified: llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp?rev=334197&r1=334196&r2=334197&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp Thu Jun  7 07:00:29 2018
@@ -144,9 +144,12 @@ void benchmarkMain() {
   if (BenchmarkFile.empty())
     BenchmarkFile = "-";
 
-  ExitOnErr(
-      Runner->run(GetOpcodeOrDie(State.getInstrInfo()), Filter, NumRepetitions)
-          .writeYaml(getBenchmarkResultContext(State), BenchmarkFile));
+  const BenchmarkResultContext Context = getBenchmarkResultContext(State);
+  std::vector<InstructionBenchmark> Results = ExitOnErr(Runner->run(
+      GetOpcodeOrDie(State.getInstrInfo()), Filter, NumRepetitions));
+  for (InstructionBenchmark &Result : Results)
+    Result.writeYaml(Context, BenchmarkFile);
+
   exegesis::pfm::pfmTerminate();
 }
 




More information about the llvm-commits mailing list