[llvm] 72df12c - [llvm-exegesis] Refactor FunctionExecutorImpl and create factory

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 20 17:15:38 PDT 2023


Author: Aiden Grossman
Date: 2023-06-21T00:04:48Z
New Revision: 72df12cce226e1ed47e9dbd6e2fc461229947b85

URL: https://github.com/llvm/llvm-project/commit/72df12cce226e1ed47e9dbd6e2fc461229947b85
DIFF: https://github.com/llvm/llvm-project/commit/72df12cce226e1ed47e9dbd6e2fc461229947b85.diff

LOG: [llvm-exegesis] Refactor FunctionExecutorImpl and create factory

In order to better support adding in new implementations of
FunctionExecutor, this patch makes some small changes so that it is
easier to add new ones in. FunctionExecutorImpl is renamed to
InProcessFunctionExecutorImpl to better reflect how it will be placed
relative to the soon-to-be introduced subprocess executor and a new
function is created to create executors so selection can be done more
easily. In addition, a new CLI flag, -execution-mode, which can be used
to select between the different executors.

Reviewed By: courbet

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

Added: 
    

Modified: 
    llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
    llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
    llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
    llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h
    llvm/tools/llvm-exegesis/lib/Target.cpp
    llvm/tools/llvm-exegesis/lib/Target.h
    llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
    llvm/tools/llvm-exegesis/llvm-exegesis.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index f934b8ec4c6cc..09539e84cfaea 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -29,11 +29,11 @@
 namespace llvm {
 namespace exegesis {
 
-BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
-                                 Benchmark::ModeE Mode,
-                                 BenchmarkPhaseSelectorE BenchmarkPhaseSelector)
+BenchmarkRunner::BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
+                                 BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
+                                 ExecutionModeE ExecutionMode)
     : State(State), Mode(Mode), BenchmarkPhaseSelector(BenchmarkPhaseSelector),
-      Scratch(std::make_unique<ScratchSpace>()) {}
+      ExecutionMode(ExecutionMode), Scratch(std::make_unique<ScratchSpace>()) {}
 
 BenchmarkRunner::~BenchmarkRunner() = default;
 
@@ -66,11 +66,11 @@ BenchmarkRunner::FunctionExecutor::runAndSample(const char *Counters) const {
 }
 
 namespace {
-class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
+class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
 public:
-  FunctionExecutorImpl(const LLVMState &State,
-                       object::OwningBinary<object::ObjectFile> Obj,
-                       BenchmarkRunner::ScratchSpace *Scratch)
+  InProcessFunctionExecutorImpl(const LLVMState &State,
+                                object::OwningBinary<object::ObjectFile> Obj,
+                                BenchmarkRunner::ScratchSpace *Scratch)
       : State(State), Function(State.createTargetMachine(), std::move(Obj)),
         Scratch(Scratch) {}
 
@@ -193,6 +193,18 @@ BenchmarkRunner::getRunnableConfiguration(
   return std::move(RC);
 }
 
+Expected<std::unique_ptr<BenchmarkRunner::FunctionExecutor>>
+BenchmarkRunner::createFunctionExecutor(
+    object::OwningBinary<object::ObjectFile> ObjectFile,
+    const BenchmarkKey &Key) const {
+  switch (ExecutionMode) {
+  case ExecutionModeE::InProcess:
+    return std::make_unique<InProcessFunctionExecutorImpl>(
+        State, std::move(ObjectFile), Scratch.get());
+  }
+  llvm_unreachable("ExecutionMode is outside expected range");
+}
+
 Expected<Benchmark> BenchmarkRunner::runConfiguration(
     RunnableConfiguration &&RC,
     const std::optional<StringRef> &DumpFile) const {
@@ -216,9 +228,12 @@ Expected<Benchmark> BenchmarkRunner::runConfiguration(
     return std::move(InstrBenchmark);
   }
 
-  const FunctionExecutorImpl Executor(State, std::move(ObjectFile),
-                                      Scratch.get());
-  auto NewMeasurements = runMeasurements(Executor);
+  Expected<std::unique_ptr<BenchmarkRunner::FunctionExecutor>> Executor =
+      createFunctionExecutor(std::move(ObjectFile), RC.InstrBenchmark.Key);
+  if (!Executor)
+    return Executor.takeError();
+  auto NewMeasurements = runMeasurements(**Executor);
+
   if (Error E = NewMeasurements.takeError()) {
     if (!E.isA<SnippetCrash>())
       return std::move(E);

diff  --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
index eece929ae8c55..e5185b4e97e32 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h
@@ -34,9 +34,11 @@ namespace exegesis {
 // Common code for all benchmark modes.
 class BenchmarkRunner {
 public:
-  explicit BenchmarkRunner(const LLVMState &State,
-                           Benchmark::ModeE Mode,
-                           BenchmarkPhaseSelectorE BenchmarkPhaseSelector);
+  enum ExecutionModeE { InProcess };
+
+  explicit BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
+                           BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
+                           ExecutionModeE ExecutionMode);
 
   virtual ~BenchmarkRunner();
 
@@ -105,6 +107,7 @@ class BenchmarkRunner {
   const LLVMState &State;
   const Benchmark::ModeE Mode;
   const BenchmarkPhaseSelectorE BenchmarkPhaseSelector;
+  const ExecutionModeE ExecutionMode;
 
 private:
   virtual Expected<std::vector<BenchmarkMeasure>>
@@ -119,6 +122,10 @@ class BenchmarkRunner {
                                         StringRef FileName) const;
 
   const std::unique_ptr<ScratchSpace> Scratch;
+
+  Expected<std::unique_ptr<FunctionExecutor>>
+  createFunctionExecutor(object::OwningBinary<object::ObjectFile> Obj,
+                         const BenchmarkKey &Key) const;
 };
 
 } // namespace exegesis

diff  --git a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
index 18c0671c0f2e9..753efed138163 100644
--- a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
@@ -21,10 +21,9 @@ namespace exegesis {
 LatencyBenchmarkRunner::LatencyBenchmarkRunner(
     const LLVMState &State, Benchmark::ModeE Mode,
     BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-    Benchmark::ResultAggregationModeE ResultAgg)
-    : BenchmarkRunner(State, Mode, BenchmarkPhaseSelector) {
-  assert((Mode == Benchmark::Latency ||
-          Mode == Benchmark::InverseThroughput) &&
+    Benchmark::ResultAggregationModeE ResultAgg, ExecutionModeE ExecutionMode)
+    : BenchmarkRunner(State, Mode, BenchmarkPhaseSelector, ExecutionMode) {
+  assert((Mode == Benchmark::Latency || Mode == Benchmark::InverseThroughput) &&
          "invalid mode");
   ResultAggMode = ResultAgg;
 }

diff  --git a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h
index cd06d00fd74cc..34b912f0abded 100644
--- a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h
@@ -21,10 +21,10 @@ namespace exegesis {
 
 class LatencyBenchmarkRunner : public BenchmarkRunner {
 public:
-  LatencyBenchmarkRunner(
-      const LLVMState &State, Benchmark::ModeE Mode,
-      BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-      Benchmark::ResultAggregationModeE ResultAggMode);
+  LatencyBenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
+                         BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
+                         Benchmark::ResultAggregationModeE ResultAggMode,
+                         ExecutionModeE ExecutionMode);
   ~LatencyBenchmarkRunner() override;
 
 private:

diff  --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp
index 268d99e96d62e..d99638f2679d3 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Target.cpp
@@ -76,6 +76,7 @@ Expected<std::unique_ptr<BenchmarkRunner>>
 ExegesisTarget::createBenchmarkRunner(
     Benchmark::ModeE Mode, const LLVMState &State,
     BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
+    BenchmarkRunner::ExecutionModeE ExecutionMode,
     Benchmark::ResultAggregationModeE ResultAggMode) const {
   PfmCountersInfo PfmCounters = State.getPfmCounters();
   switch (Mode) {
@@ -98,7 +99,7 @@ ExegesisTarget::createBenchmarkRunner(
                   "the kernel for real event counts."));
     }
     return createLatencyBenchmarkRunner(State, Mode, BenchmarkPhaseSelector,
-                                        ResultAggMode);
+                                        ResultAggMode, ExecutionMode);
   case Benchmark::Uops:
     if (BenchmarkPhaseSelector == BenchmarkPhaseSelectorE::Measure &&
         !PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
@@ -108,7 +109,7 @@ ExegesisTarget::createBenchmarkRunner(
           "benchmarking or --use-dummy-perf-counters to not query the kernel "
           "for real event counts.");
     return createUopsBenchmarkRunner(State, BenchmarkPhaseSelector,
-                                     ResultAggMode);
+                                     ResultAggMode, ExecutionMode);
   }
   return nullptr;
 }
@@ -126,15 +127,18 @@ std::unique_ptr<SnippetGenerator> ExegesisTarget::createParallelSnippetGenerator
 std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner(
     const LLVMState &State, Benchmark::ModeE Mode,
     BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-    Benchmark::ResultAggregationModeE ResultAggMode) const {
+    Benchmark::ResultAggregationModeE ResultAggMode,
+    BenchmarkRunner::ExecutionModeE ExecutionMode) const {
   return std::make_unique<LatencyBenchmarkRunner>(
-      State, Mode, BenchmarkPhaseSelector, ResultAggMode);
+      State, Mode, BenchmarkPhaseSelector, ResultAggMode, ExecutionMode);
 }
 
 std::unique_ptr<BenchmarkRunner> ExegesisTarget::createUopsBenchmarkRunner(
     const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-    Benchmark::ResultAggregationModeE /*unused*/) const {
-  return std::make_unique<UopsBenchmarkRunner>(State, BenchmarkPhaseSelector);
+    Benchmark::ResultAggregationModeE /*unused*/,
+    BenchmarkRunner::ExecutionModeE ExecutionMode) const {
+  return std::make_unique<UopsBenchmarkRunner>(State, BenchmarkPhaseSelector,
+                                               ExecutionMode);
 }
 
 static_assert(std::is_trivial_v<PfmCountersInfo>,

diff  --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h
index 3cc36457134fd..b8fd4abcbbe4a 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.h
+++ b/llvm/tools/llvm-exegesis/lib/Target.h
@@ -162,8 +162,8 @@ class ExegesisTarget {
   Expected<std::unique_ptr<BenchmarkRunner>> createBenchmarkRunner(
       Benchmark::ModeE Mode, const LLVMState &State,
       BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-      Benchmark::ResultAggregationModeE ResultAggMode =
-          Benchmark::Min) const;
+      BenchmarkRunner::ExecutionModeE ExecutionMode,
+      Benchmark::ResultAggregationModeE ResultAggMode = Benchmark::Min) const;
 
   // Returns the ExegesisTarget for the given triple or nullptr if the target
   // does not exist.
@@ -205,10 +205,12 @@ class ExegesisTarget {
   std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
       const LLVMState &State, Benchmark::ModeE Mode,
       BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-      Benchmark::ResultAggregationModeE ResultAggMode) const;
+      Benchmark::ResultAggregationModeE ResultAggMode,
+      BenchmarkRunner::ExecutionModeE ExecutionMode) const;
   std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
       const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
-      Benchmark::ResultAggregationModeE ResultAggMode) const;
+      Benchmark::ResultAggregationModeE ResultAggMode,
+      BenchmarkRunner::ExecutionModeE ExecutionMode) const;
 
   const ExegesisTarget *Next = nullptr;
   const ArrayRef<CpuAndPfmCounters> CpuPfmCounters;

diff  --git a/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
index e08eaa7706dd2..337f093670122 100644
--- a/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
+++ b/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h
@@ -22,9 +22,10 @@ namespace exegesis {
 class UopsBenchmarkRunner : public BenchmarkRunner {
 public:
   UopsBenchmarkRunner(const LLVMState &State,
-                      BenchmarkPhaseSelectorE BenchmarkPhaseSelector)
-      : BenchmarkRunner(State, Benchmark::Uops,
-                        BenchmarkPhaseSelector) {}
+                      BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
+                      ExecutionModeE ExecutionMode)
+      : BenchmarkRunner(State, Benchmark::Uops, BenchmarkPhaseSelector,
+                        ExecutionMode) {}
   ~UopsBenchmarkRunner() override;
 
   static constexpr const size_t kMinNumDifferentAddresses = 6;

diff  --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
index 0973f7bb721f1..d890fbb1336b4 100644
--- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
+++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp
@@ -248,6 +248,15 @@ static cl::opt<std::string>
                               "and prints a message to access it"),
                      cl::ValueOptional, cl::cat(BenchmarkOptions));
 
+static cl::opt<BenchmarkRunner::ExecutionModeE> ExecutionMode(
+    "execution-mode",
+    cl::desc("Selects the execution mode to use for running snippets"),
+    cl::cat(BenchmarkOptions),
+    cl::values(clEnumValN(BenchmarkRunner::ExecutionModeE::InProcess,
+                          "inprocess",
+                          "Executes the snippets within the same process")),
+    cl::init(BenchmarkRunner::ExecutionModeE::InProcess));
+
 static ExitOnError ExitOnErr("llvm-exegesis error: ");
 
 // Helper function that logs the error(s) and exits.
@@ -459,7 +468,8 @@ void benchmarkMain() {
 
   const std::unique_ptr<BenchmarkRunner> Runner =
       ExitOnErr(State.getExegesisTarget().createBenchmarkRunner(
-          BenchmarkMode, State, BenchmarkPhaseSelector, ResultAggMode));
+          BenchmarkMode, State, BenchmarkPhaseSelector, ExecutionMode,
+          ResultAggMode));
   if (!Runner) {
     ExitWithError("cannot create benchmark runner");
   }


        


More information about the llvm-commits mailing list