@@ -54,9 +54,11 @@ namespace exegesis {
5454
5555BenchmarkRunner::BenchmarkRunner (const LLVMState &State, Benchmark::ModeE Mode,
5656 BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
57- ExecutionModeE ExecutionMode)
57+ ExecutionModeE ExecutionMode,
58+ ArrayRef<ValidationEvent> ValCounters)
5859 : 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>()) {}
6062
6163BenchmarkRunner::~BenchmarkRunner () = default ;
6264
@@ -71,16 +73,18 @@ void BenchmarkRunner::FunctionExecutor::accumulateCounterValues(
7173}
7274
7375Expected<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 {
7579 // We sum counts when there are several counters for a single ProcRes
7680 // (e.g. P23 on SandyBridge).
7781 llvm::SmallVector<int64_t , 4 > CounterValues;
7882 SmallVector<StringRef, 2 > CounterNames;
7983 StringRef (Counters).split (CounterNames, ' +' );
8084 for (auto &CounterName : CounterNames) {
8185 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 );
8488 if (!ValueOrError)
8589 return ValueOrError.takeError ();
8690 accumulateCounterValues (ValueOrError.get (), &CounterValues);
@@ -120,11 +124,13 @@ class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
120124 (*Result)[I] += NewValues[I];
121125 }
122126
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 {
125130 const ExegesisTarget &ET = State.getExegesisTarget ();
126131 char *const ScratchPtr = Scratch->ptr ();
127- auto CounterOrError = ET.createCounter (CounterName, State);
132+ auto CounterOrError =
133+ ET.createCounter (CounterName, State, ValidationCounters);
128134
129135 if (!CounterOrError)
130136 return CounterOrError.takeError ();
@@ -156,6 +162,14 @@ class InProcessFunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
156162 }
157163 }
158164
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+
159173 return Counter->readOrError (Function.getFunctionBytes ());
160174 }
161175
@@ -266,7 +280,9 @@ class SubProcessFunctionExecutorImpl
266280 }
267281
268282 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 {
270286 int PipeFiles[2 ];
271287 int PipeSuccessOrErr = socketpair (AF_UNIX, SOCK_DGRAM, 0 , PipeFiles);
272288 if (PipeSuccessOrErr != 0 ) {
@@ -306,8 +322,8 @@ class SubProcessFunctionExecutorImpl
306322 }
307323
308324 const ExegesisTarget &ET = State.getExegesisTarget ();
309- auto CounterOrError =
310- ET. createCounter ( CounterName, State, ParentOrChildPID);
325+ auto CounterOrError = ET. createCounter (
326+ CounterName, State, ValidationCounters , ParentOrChildPID);
311327
312328 if (!CounterOrError)
313329 return CounterOrError.takeError ();
@@ -362,6 +378,14 @@ class SubProcessFunctionExecutorImpl
362378 return CounterValueOrErr.takeError ();
363379 CounterValues = std::move (*CounterValueOrErr);
364380
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+
365389 return Error::success ();
366390 }
367391 // The child exited, but not successfully
@@ -460,15 +484,15 @@ class SubProcessFunctionExecutorImpl
460484 exit (0 );
461485 }
462486
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 {
465490 SmallVector<int64_t , 4 > Value (1 , 0 );
466- Error PossibleBenchmarkError =
467- createSubProcessAndRunBenchmark ( CounterName, Value);
491+ Error PossibleBenchmarkError = createSubProcessAndRunBenchmark (
492+ CounterName, Value, ValidationCounters, ValidationCounterValues );
468493
469- if (PossibleBenchmarkError) {
494+ if (PossibleBenchmarkError)
470495 return std::move (PossibleBenchmarkError);
471- }
472496
473497 return Value;
474498 }
@@ -642,6 +666,34 @@ BenchmarkRunner::writeObjectFile(StringRef Buffer, StringRef FileName) const {
642666 return std::string (ResultPath);
643667}
644668
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+
645697BenchmarkRunner::FunctionExecutor::~FunctionExecutor () {}
646698
647699} // namespace exegesis
0 commit comments