@@ -54,9 +54,11 @@ namespace exegesis {
54
54
55
55
BenchmarkRunner::BenchmarkRunner (const LLVMState &State, Benchmark::ModeE Mode,
56
56
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
57
- ExecutionModeE ExecutionMode)
57
+ ExecutionModeE ExecutionMode,
58
+ ArrayRef<ValidationEvent> ValCounters)
58
59
: State(State), Mode(Mode), BenchmarkPhaseSelector(BenchmarkPhaseSelector),
59
- ExecutionMode (ExecutionMode), Scratch(std::make_unique<ScratchSpace>()) {}
60
+ ExecutionMode (ExecutionMode), ValidationCounters(ValCounters),
61
+ Scratch(std::make_unique<ScratchSpace>()) {}
60
62
61
63
BenchmarkRunner::~BenchmarkRunner () = default ;
62
64
@@ -71,16 +73,18 @@ void BenchmarkRunner::FunctionExecutor::accumulateCounterValues(
71
73
}
72
74
73
75
Expected<llvm::SmallVector<int64_t , 4 >>
74
- BenchmarkRunner::FunctionExecutor::runAndSample (const char *Counters) const {
76
+ BenchmarkRunner::FunctionExecutor::runAndSample (
77
+ const char *Counters, ArrayRef<const char *> ValidationCounters,
78
+ SmallVectorImpl<int64_t > &ValidationCounterValues) const {
75
79
// We sum counts when there are several counters for a single ProcRes
76
80
// (e.g. P23 on SandyBridge).
77
81
llvm::SmallVector<int64_t , 4 > CounterValues;
78
82
SmallVector<StringRef, 2 > CounterNames;
79
83
StringRef (Counters).split (CounterNames, ' +' );
80
84
for (auto &CounterName : CounterNames) {
81
85
CounterName = CounterName.trim ();
82
- Expected<SmallVector<int64_t , 4 >> ValueOrError =
83
- runWithCounter ( CounterName);
86
+ Expected<SmallVector<int64_t , 4 >> ValueOrError = runWithCounter (
87
+ CounterName, ValidationCounters, ValidationCounterValues );
84
88
if (!ValueOrError)
85
89
return ValueOrError.takeError ();
86
90
accumulateCounterValues (ValueOrError.get (), &CounterValues);
@@ -120,11 +124,13 @@ class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
120
124
(*Result)[I] += NewValues[I];
121
125
}
122
126
123
- Expected<llvm::SmallVector<int64_t , 4 >>
124
- runWithCounter (StringRef CounterName) const override {
127
+ Expected<llvm::SmallVector<int64_t , 4 >> runWithCounter (
128
+ StringRef CounterName, ArrayRef<const char *> ValidationCounters,
129
+ SmallVectorImpl<int64_t > &ValidationCounterValues) const override {
125
130
const ExegesisTarget &ET = State.getExegesisTarget ();
126
131
char *const ScratchPtr = Scratch->ptr ();
127
- auto CounterOrError = ET.createCounter (CounterName, State);
132
+ auto CounterOrError =
133
+ ET.createCounter (CounterName, State, ValidationCounters);
128
134
129
135
if (!CounterOrError)
130
136
return CounterOrError.takeError ();
@@ -156,6 +162,14 @@ class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
156
162
}
157
163
}
158
164
165
+ auto ValidationValuesOrErr = Counter->readValidationCountersOrError ();
166
+ if (!ValidationValuesOrErr)
167
+ return ValidationValuesOrErr.takeError ();
168
+
169
+ ArrayRef RealValidationValues = *ValidationValuesOrErr;
170
+ for (size_t I = 0 ; I < RealValidationValues.size (); ++I)
171
+ ValidationCounterValues[I] = RealValidationValues[I];
172
+
159
173
return Counter->readOrError (Function.getFunctionBytes ());
160
174
}
161
175
@@ -266,7 +280,9 @@ class SubProcessFunctionExecutorImpl
266
280
}
267
281
268
282
Error createSubProcessAndRunBenchmark (
269
- StringRef CounterName, SmallVectorImpl<int64_t > &CounterValues) const {
283
+ StringRef CounterName, SmallVectorImpl<int64_t > &CounterValues,
284
+ ArrayRef<const char *> ValidationCounters,
285
+ SmallVectorImpl<int64_t > &ValidationCounterValues) const {
270
286
int PipeFiles[2 ];
271
287
int PipeSuccessOrErr = socketpair (AF_UNIX, SOCK_DGRAM, 0 , PipeFiles);
272
288
if (PipeSuccessOrErr != 0 ) {
@@ -306,8 +322,8 @@ class SubProcessFunctionExecutorImpl
306
322
}
307
323
308
324
const ExegesisTarget &ET = State.getExegesisTarget ();
309
- auto CounterOrError =
310
- ET. createCounter ( CounterName, State, ParentOrChildPID);
325
+ auto CounterOrError = ET. createCounter (
326
+ CounterName, State, ValidationCounters , ParentOrChildPID);
311
327
312
328
if (!CounterOrError)
313
329
return CounterOrError.takeError ();
@@ -362,6 +378,14 @@ class SubProcessFunctionExecutorImpl
362
378
return CounterValueOrErr.takeError ();
363
379
CounterValues = std::move (*CounterValueOrErr);
364
380
381
+ auto ValidationValuesOrErr = Counter->readValidationCountersOrError ();
382
+ if (!ValidationValuesOrErr)
383
+ return ValidationValuesOrErr.takeError ();
384
+
385
+ ArrayRef RealValidationValues = *ValidationValuesOrErr;
386
+ for (size_t I = 0 ; I < RealValidationValues.size (); ++I)
387
+ ValidationCounterValues[I] = RealValidationValues[I];
388
+
365
389
return Error::success ();
366
390
}
367
391
// The child exited, but not successfully
@@ -460,15 +484,15 @@ class SubProcessFunctionExecutorImpl
460
484
exit (0 );
461
485
}
462
486
463
- Expected<llvm::SmallVector<int64_t , 4 >>
464
- runWithCounter (StringRef CounterName) const override {
487
+ Expected<llvm::SmallVector<int64_t , 4 >> runWithCounter (
488
+ StringRef CounterName, ArrayRef<const char *> ValidationCounters,
489
+ SmallVectorImpl<int64_t > &ValidationCounterValues) const override {
465
490
SmallVector<int64_t , 4 > Value (1 , 0 );
466
- Error PossibleBenchmarkError =
467
- createSubProcessAndRunBenchmark ( CounterName, Value);
491
+ Error PossibleBenchmarkError = createSubProcessAndRunBenchmark (
492
+ CounterName, Value, ValidationCounters, ValidationCounterValues );
468
493
469
- if (PossibleBenchmarkError) {
494
+ if (PossibleBenchmarkError)
470
495
return std::move (PossibleBenchmarkError);
471
- }
472
496
473
497
return Value;
474
498
}
@@ -642,6 +666,34 @@ BenchmarkRunner::writeObjectFile(StringRef Buffer, StringRef FileName) const {
642
666
return std::string (ResultPath);
643
667
}
644
668
669
+ static bool EventLessThan (const std::pair<ValidationEvent, const char *> LHS,
670
+ const ValidationEvent RHS) {
671
+ return static_cast <int >(LHS.first ) < static_cast <int >(RHS);
672
+ }
673
+
674
+ Error BenchmarkRunner::getValidationCountersToRun (
675
+ SmallVector<const char *> &ValCountersToRun) const {
676
+ const PfmCountersInfo &PCI = State.getPfmCounters ();
677
+ ValCountersToRun.reserve (ValidationCounters.size ());
678
+
679
+ ValCountersToRun.reserve (ValidationCounters.size ());
680
+ ArrayRef TargetValidationEvents (PCI.ValidationEvents ,
681
+ PCI.NumValidationEvents );
682
+ for (const ValidationEvent RequestedValEvent : ValidationCounters) {
683
+ auto ValCounterIt =
684
+ lower_bound (TargetValidationEvents, RequestedValEvent, EventLessThan);
685
+ if (ValCounterIt == TargetValidationEvents.end () ||
686
+ ValCounterIt->first != RequestedValEvent)
687
+ return make_error<Failure>(" Cannot create validation counter" );
688
+
689
+ assert (ValCounterIt->first == RequestedValEvent &&
690
+ " The array of validation events from the target should be sorted" );
691
+ ValCountersToRun.push_back (ValCounterIt->second );
692
+ }
693
+
694
+ return Error::success ();
695
+ }
696
+
645
697
BenchmarkRunner::FunctionExecutor::~FunctionExecutor () {}
646
698
647
699
} // namespace exegesis
0 commit comments