diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h @@ -40,6 +40,8 @@ virtual ~BenchmarkRunner(); + enum ExecutionModeE { InProcess }; + class RunnableConfiguration { friend class BenchmarkRunner; @@ -56,12 +58,14 @@ Benchmark InstrBenchmark; object::OwningBinary ObjectFile; + ExecutionModeE ExecutionMode; }; Expected getRunnableConfiguration(const BenchmarkCode &Configuration, unsigned NumRepetitions, unsigned LoopUnrollFactor, - const SnippetRepetitor &Repetitor) const; + const SnippetRepetitor &Repetitor, + ExecutionModeE ExecutionMode) const; Expected runConfiguration(RunnableConfiguration &&RC, @@ -119,6 +123,11 @@ StringRef FileName) const; const std::unique_ptr Scratch; + + Expected> + getFunctionExecutor(ExecutionModeE ExecutionMode, + object::OwningBinary Obj, + const BenchmarkKey &Key) const; }; } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp --- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -12,6 +12,7 @@ #include "Assembler.h" #include "BenchmarkRunner.h" +#include "CodeTemplate.h" #include "Error.h" #include "MCInstrDescView.h" #include "PerfHelper.h" @@ -22,6 +23,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Program.h" @@ -66,9 +68,9 @@ } namespace { -class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor { +class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor { public: - FunctionExecutorImpl(const LLVMState &State, + InProcessFunctionExecutorImpl(const LLVMState &State, object::OwningBinary Obj, BenchmarkRunner::ScratchSpace *Scratch) : State(State), Function(State.createTargetMachine(), std::move(Obj)), @@ -149,7 +151,7 @@ Expected BenchmarkRunner::getRunnableConfiguration( const BenchmarkCode &BC, unsigned NumRepetitions, unsigned LoopBodySize, - const SnippetRepetitor &Repetitor) const { + const SnippetRepetitor &Repetitor, ExecutionModeE ExecutionMode) const { RunnableConfiguration RC; Benchmark &InstrBenchmark = RC.InstrBenchmark; @@ -190,9 +192,23 @@ RC.ObjectFile = getObjectFromBuffer(*Snippet); } + RC.ExecutionMode = ExecutionMode; + return std::move(RC); } +Expected> +BenchmarkRunner::getFunctionExecutor( + ExecutionModeE ExecutionMode, + object::OwningBinary ObjectFile, + const BenchmarkKey &Key) const { + if (ExecutionMode == ExecutionModeE::InProcess) { + return std::make_unique( + State, std::move(ObjectFile), Scratch.get()); + } + llvm_unreachable("ExecutionMode is outside expected range"); +} + Expected BenchmarkRunner::runConfiguration( RunnableConfiguration &&RC, const std::optional &DumpFile) const { @@ -216,9 +232,13 @@ return std::move(InstrBenchmark); } - const FunctionExecutorImpl Executor(State, std::move(ObjectFile), - Scratch.get()); - auto NewMeasurements = runMeasurements(Executor); + Expected> Executor = + getFunctionExecutor(RC.ExecutionMode, std::move(ObjectFile), + RC.InstrBenchmark.Key); + if (!Executor) + return Executor.takeError(); + auto NewMeasurements = runMeasurements(**Executor); + if (Error E = NewMeasurements.takeError()) { if (!E.isA()) return std::move(E); diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -15,6 +15,7 @@ #include "lib/BenchmarkResult.h" #include "lib/BenchmarkRunner.h" #include "lib/Clustering.h" +#include "lib/CodeTemplate.h" #include "lib/Error.h" #include "lib/LlvmState.h" #include "lib/PerfHelper.h" @@ -248,6 +249,15 @@ "and prints a message to access it"), cl::ValueOptional, cl::cat(BenchmarkOptions)); +static cl::opt 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. @@ -380,7 +390,7 @@ for (const std::unique_ptr &Repetitor : Repetitors) { auto RC = ExitOnErr(Runner.getRunnableConfiguration( - Conf, NumRepetitions, LoopBodySize, *Repetitor)); + Conf, NumRepetitions, LoopBodySize, *Repetitor, ExecutionMode)); std::optional DumpFile; if (DumpObjectToDisk.getNumOccurrences()) DumpFile = DumpObjectToDisk;