Skip to content

Commit 72df12c

Browse files
[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
1 parent fabd16c commit 72df12c

File tree

8 files changed

+74
-36
lines changed

8 files changed

+74
-36
lines changed

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
namespace llvm {
3030
namespace exegesis {
3131

32-
BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
33-
Benchmark::ModeE Mode,
34-
BenchmarkPhaseSelectorE BenchmarkPhaseSelector)
32+
BenchmarkRunner::BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
33+
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
34+
ExecutionModeE ExecutionMode)
3535
: State(State), Mode(Mode), BenchmarkPhaseSelector(BenchmarkPhaseSelector),
36-
Scratch(std::make_unique<ScratchSpace>()) {}
36+
ExecutionMode(ExecutionMode), Scratch(std::make_unique<ScratchSpace>()) {}
3737

3838
BenchmarkRunner::~BenchmarkRunner() = default;
3939

@@ -66,11 +66,11 @@ BenchmarkRunner::FunctionExecutor::runAndSample(const char *Counters) const {
6666
}
6767

6868
namespace {
69-
class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
69+
class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
7070
public:
71-
FunctionExecutorImpl(const LLVMState &State,
72-
object::OwningBinary<object::ObjectFile> Obj,
73-
BenchmarkRunner::ScratchSpace *Scratch)
71+
InProcessFunctionExecutorImpl(const LLVMState &State,
72+
object::OwningBinary<object::ObjectFile> Obj,
73+
BenchmarkRunner::ScratchSpace *Scratch)
7474
: State(State), Function(State.createTargetMachine(), std::move(Obj)),
7575
Scratch(Scratch) {}
7676

@@ -193,6 +193,18 @@ BenchmarkRunner::getRunnableConfiguration(
193193
return std::move(RC);
194194
}
195195

196+
Expected<std::unique_ptr<BenchmarkRunner::FunctionExecutor>>
197+
BenchmarkRunner::createFunctionExecutor(
198+
object::OwningBinary<object::ObjectFile> ObjectFile,
199+
const BenchmarkKey &Key) const {
200+
switch (ExecutionMode) {
201+
case ExecutionModeE::InProcess:
202+
return std::make_unique<InProcessFunctionExecutorImpl>(
203+
State, std::move(ObjectFile), Scratch.get());
204+
}
205+
llvm_unreachable("ExecutionMode is outside expected range");
206+
}
207+
196208
Expected<Benchmark> BenchmarkRunner::runConfiguration(
197209
RunnableConfiguration &&RC,
198210
const std::optional<StringRef> &DumpFile) const {
@@ -216,9 +228,12 @@ Expected<Benchmark> BenchmarkRunner::runConfiguration(
216228
return std::move(InstrBenchmark);
217229
}
218230

219-
const FunctionExecutorImpl Executor(State, std::move(ObjectFile),
220-
Scratch.get());
221-
auto NewMeasurements = runMeasurements(Executor);
231+
Expected<std::unique_ptr<BenchmarkRunner::FunctionExecutor>> Executor =
232+
createFunctionExecutor(std::move(ObjectFile), RC.InstrBenchmark.Key);
233+
if (!Executor)
234+
return Executor.takeError();
235+
auto NewMeasurements = runMeasurements(**Executor);
236+
222237
if (Error E = NewMeasurements.takeError()) {
223238
if (!E.isA<SnippetCrash>())
224239
return std::move(E);

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ namespace exegesis {
3434
// Common code for all benchmark modes.
3535
class BenchmarkRunner {
3636
public:
37-
explicit BenchmarkRunner(const LLVMState &State,
38-
Benchmark::ModeE Mode,
39-
BenchmarkPhaseSelectorE BenchmarkPhaseSelector);
37+
enum ExecutionModeE { InProcess };
38+
39+
explicit BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
40+
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
41+
ExecutionModeE ExecutionMode);
4042

4143
virtual ~BenchmarkRunner();
4244

@@ -105,6 +107,7 @@ class BenchmarkRunner {
105107
const LLVMState &State;
106108
const Benchmark::ModeE Mode;
107109
const BenchmarkPhaseSelectorE BenchmarkPhaseSelector;
110+
const ExecutionModeE ExecutionMode;
108111

109112
private:
110113
virtual Expected<std::vector<BenchmarkMeasure>>
@@ -119,6 +122,10 @@ class BenchmarkRunner {
119122
StringRef FileName) const;
120123

121124
const std::unique_ptr<ScratchSpace> Scratch;
125+
126+
Expected<std::unique_ptr<FunctionExecutor>>
127+
createFunctionExecutor(object::OwningBinary<object::ObjectFile> Obj,
128+
const BenchmarkKey &Key) const;
122129
};
123130

124131
} // namespace exegesis

llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ namespace exegesis {
2121
LatencyBenchmarkRunner::LatencyBenchmarkRunner(
2222
const LLVMState &State, Benchmark::ModeE Mode,
2323
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
24-
Benchmark::ResultAggregationModeE ResultAgg)
25-
: BenchmarkRunner(State, Mode, BenchmarkPhaseSelector) {
26-
assert((Mode == Benchmark::Latency ||
27-
Mode == Benchmark::InverseThroughput) &&
24+
Benchmark::ResultAggregationModeE ResultAgg, ExecutionModeE ExecutionMode)
25+
: BenchmarkRunner(State, Mode, BenchmarkPhaseSelector, ExecutionMode) {
26+
assert((Mode == Benchmark::Latency || Mode == Benchmark::InverseThroughput) &&
2827
"invalid mode");
2928
ResultAggMode = ResultAgg;
3029
}

llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ namespace exegesis {
2121

2222
class LatencyBenchmarkRunner : public BenchmarkRunner {
2323
public:
24-
LatencyBenchmarkRunner(
25-
const LLVMState &State, Benchmark::ModeE Mode,
26-
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
27-
Benchmark::ResultAggregationModeE ResultAggMode);
24+
LatencyBenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
25+
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
26+
Benchmark::ResultAggregationModeE ResultAggMode,
27+
ExecutionModeE ExecutionMode);
2828
~LatencyBenchmarkRunner() override;
2929

3030
private:

llvm/tools/llvm-exegesis/lib/Target.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Expected<std::unique_ptr<BenchmarkRunner>>
7676
ExegesisTarget::createBenchmarkRunner(
7777
Benchmark::ModeE Mode, const LLVMState &State,
7878
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
79+
BenchmarkRunner::ExecutionModeE ExecutionMode,
7980
Benchmark::ResultAggregationModeE ResultAggMode) const {
8081
PfmCountersInfo PfmCounters = State.getPfmCounters();
8182
switch (Mode) {
@@ -98,7 +99,7 @@ ExegesisTarget::createBenchmarkRunner(
9899
"the kernel for real event counts."));
99100
}
100101
return createLatencyBenchmarkRunner(State, Mode, BenchmarkPhaseSelector,
101-
ResultAggMode);
102+
ResultAggMode, ExecutionMode);
102103
case Benchmark::Uops:
103104
if (BenchmarkPhaseSelector == BenchmarkPhaseSelectorE::Measure &&
104105
!PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
@@ -108,7 +109,7 @@ ExegesisTarget::createBenchmarkRunner(
108109
"benchmarking or --use-dummy-perf-counters to not query the kernel "
109110
"for real event counts.");
110111
return createUopsBenchmarkRunner(State, BenchmarkPhaseSelector,
111-
ResultAggMode);
112+
ResultAggMode, ExecutionMode);
112113
}
113114
return nullptr;
114115
}
@@ -126,15 +127,18 @@ std::unique_ptr<SnippetGenerator> ExegesisTarget::createParallelSnippetGenerator
126127
std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner(
127128
const LLVMState &State, Benchmark::ModeE Mode,
128129
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
129-
Benchmark::ResultAggregationModeE ResultAggMode) const {
130+
Benchmark::ResultAggregationModeE ResultAggMode,
131+
BenchmarkRunner::ExecutionModeE ExecutionMode) const {
130132
return std::make_unique<LatencyBenchmarkRunner>(
131-
State, Mode, BenchmarkPhaseSelector, ResultAggMode);
133+
State, Mode, BenchmarkPhaseSelector, ResultAggMode, ExecutionMode);
132134
}
133135

134136
std::unique_ptr<BenchmarkRunner> ExegesisTarget::createUopsBenchmarkRunner(
135137
const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
136-
Benchmark::ResultAggregationModeE /*unused*/) const {
137-
return std::make_unique<UopsBenchmarkRunner>(State, BenchmarkPhaseSelector);
138+
Benchmark::ResultAggregationModeE /*unused*/,
139+
BenchmarkRunner::ExecutionModeE ExecutionMode) const {
140+
return std::make_unique<UopsBenchmarkRunner>(State, BenchmarkPhaseSelector,
141+
ExecutionMode);
138142
}
139143

140144
static_assert(std::is_trivial_v<PfmCountersInfo>,

llvm/tools/llvm-exegesis/lib/Target.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ class ExegesisTarget {
162162
Expected<std::unique_ptr<BenchmarkRunner>> createBenchmarkRunner(
163163
Benchmark::ModeE Mode, const LLVMState &State,
164164
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
165-
Benchmark::ResultAggregationModeE ResultAggMode =
166-
Benchmark::Min) const;
165+
BenchmarkRunner::ExecutionModeE ExecutionMode,
166+
Benchmark::ResultAggregationModeE ResultAggMode = Benchmark::Min) const;
167167

168168
// Returns the ExegesisTarget for the given triple or nullptr if the target
169169
// does not exist.
@@ -205,10 +205,12 @@ class ExegesisTarget {
205205
std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
206206
const LLVMState &State, Benchmark::ModeE Mode,
207207
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
208-
Benchmark::ResultAggregationModeE ResultAggMode) const;
208+
Benchmark::ResultAggregationModeE ResultAggMode,
209+
BenchmarkRunner::ExecutionModeE ExecutionMode) const;
209210
std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
210211
const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
211-
Benchmark::ResultAggregationModeE ResultAggMode) const;
212+
Benchmark::ResultAggregationModeE ResultAggMode,
213+
BenchmarkRunner::ExecutionModeE ExecutionMode) const;
212214

213215
const ExegesisTarget *Next = nullptr;
214216
const ArrayRef<CpuAndPfmCounters> CpuPfmCounters;

llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ namespace exegesis {
2222
class UopsBenchmarkRunner : public BenchmarkRunner {
2323
public:
2424
UopsBenchmarkRunner(const LLVMState &State,
25-
BenchmarkPhaseSelectorE BenchmarkPhaseSelector)
26-
: BenchmarkRunner(State, Benchmark::Uops,
27-
BenchmarkPhaseSelector) {}
25+
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
26+
ExecutionModeE ExecutionMode)
27+
: BenchmarkRunner(State, Benchmark::Uops, BenchmarkPhaseSelector,
28+
ExecutionMode) {}
2829
~UopsBenchmarkRunner() override;
2930

3031
static constexpr const size_t kMinNumDifferentAddresses = 6;

llvm/tools/llvm-exegesis/llvm-exegesis.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ static cl::opt<std::string>
248248
"and prints a message to access it"),
249249
cl::ValueOptional, cl::cat(BenchmarkOptions));
250250

251+
static cl::opt<BenchmarkRunner::ExecutionModeE> ExecutionMode(
252+
"execution-mode",
253+
cl::desc("Selects the execution mode to use for running snippets"),
254+
cl::cat(BenchmarkOptions),
255+
cl::values(clEnumValN(BenchmarkRunner::ExecutionModeE::InProcess,
256+
"inprocess",
257+
"Executes the snippets within the same process")),
258+
cl::init(BenchmarkRunner::ExecutionModeE::InProcess));
259+
251260
static ExitOnError ExitOnErr("llvm-exegesis error: ");
252261

253262
// Helper function that logs the error(s) and exits.
@@ -459,7 +468,8 @@ void benchmarkMain() {
459468

460469
const std::unique_ptr<BenchmarkRunner> Runner =
461470
ExitOnErr(State.getExegesisTarget().createBenchmarkRunner(
462-
BenchmarkMode, State, BenchmarkPhaseSelector, ResultAggMode));
471+
BenchmarkMode, State, BenchmarkPhaseSelector, ExecutionMode,
472+
ResultAggMode));
463473
if (!Runner) {
464474
ExitWithError("cannot create benchmark runner");
465475
}

0 commit comments

Comments
 (0)