From 48f0c80277d15bef574c10f247b25329dfe4941d Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sun, 25 Jun 2023 23:46:22 +0000 Subject: [PATCH] [llvm-exegesis] Add ability to assign perf counters to specific PID This patch gives the ability to assign performance counters within llvm-exegesis to a specific process by passing its PID. This is needed later on for implementing a subprocess executor. Defaults to zero, the current process, for the InProcessFunctionExecutorImpl. Reviewed By: courbet Differential Revision: https://reviews.llvm.org/D151020 --- llvm/tools/llvm-exegesis/lib/PerfHelper.cpp | 11 +++++------ llvm/tools/llvm-exegesis/lib/PerfHelper.h | 14 ++++++++++---- llvm/tools/llvm-exegesis/lib/Target.cpp | 5 +++-- llvm/tools/llvm-exegesis/lib/Target.h | 3 ++- llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 5 +++-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp index 4bf748523cf2..3ff1745e9e06 100644 --- a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp +++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp @@ -107,21 +107,20 @@ StringRef PerfEvent::getPfmEventString() const { return FullQualifiedEventString; } -Counter::Counter(PerfEvent &&E) : Event(std::move(E)){ +Counter::Counter(PerfEvent &&E, pid_t ProcessID) : Event(std::move(E)) { assert(Event.valid()); IsDummyEvent = Event.name() == PerfEvent::DummyEventString; if (!IsDummyEvent) - initRealEvent(E); + initRealEvent(E, ProcessID); } #ifdef HAVE_LIBPFM -void Counter::initRealEvent(const PerfEvent &E) { - const pid_t Pid = 0; // measure current process/thread. +void Counter::initRealEvent(const PerfEvent &E, pid_t ProcessID) { const int Cpu = -1; // measure any processor. const int GroupFd = -1; // no grouping of counters. const uint32_t Flags = 0; perf_event_attr AttrCopy = *Event.attribute(); - FileDescriptor = perf_event_open(&AttrCopy, Pid, Cpu, GroupFd, Flags); + FileDescriptor = perf_event_open(&AttrCopy, ProcessID, Cpu, GroupFd, Flags); if (FileDescriptor == -1) { errs() << "Unable to open event. ERRNO: " << strerror(errno) << ". Make sure your kernel allows user " @@ -180,7 +179,7 @@ Counter::readOrError(StringRef /*unused*/) const { int Counter::numValues() const { return 1; } #else -void Counter::initRealEvent(const PerfEvent &) {} +void Counter::initRealEvent(const PerfEvent &, pid_t ProcessID) {} Counter::~Counter() = default; diff --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.h b/llvm/tools/llvm-exegesis/lib/PerfHelper.h index f3e2b1b6b952..0796c264b622 100644 --- a/llvm/tools/llvm-exegesis/lib/PerfHelper.h +++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.h @@ -23,6 +23,12 @@ #include #include +#ifdef _MSC_VER +typedef int pid_t; +#else +#include +#endif // HAVE_LIBPFM + struct perf_event_attr; namespace llvm { @@ -76,7 +82,7 @@ private: class Counter { public: // event: the PerfEvent to measure. - explicit Counter(PerfEvent &&event); + explicit Counter(PerfEvent &&event, pid_t ProcessID = 0); Counter(const Counter &) = delete; Counter(Counter &&other) = default; @@ -103,15 +109,15 @@ public: virtual int numValues() const; + int getFileDescriptor() const { return FileDescriptor; } + protected: PerfEvent Event; -#ifdef HAVE_LIBPFM int FileDescriptor = -1; -#endif bool IsDummyEvent; private: - void initRealEvent(const PerfEvent &E); + void initRealEvent(const PerfEvent &E, pid_t ProcessID); }; } // namespace pfm diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index d99638f2679d..1e5f688cf61b 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -35,7 +35,8 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) { } Expected> -ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &) const { +ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &, + const pid_t ProcessID) const { pfm::PerfEvent Event(CounterName); if (!Event.valid()) return llvm::make_error( @@ -43,7 +44,7 @@ ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &) const { .concat(CounterName) .concat("'")); - return std::make_unique(std::move(Event)); + return std::make_unique(std::move(Event), ProcessID); } void ExegesisTarget::registerTarget(ExegesisTarget *Target) { diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index b8fd4abcbbe4..51bd5f3aff55 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -75,7 +75,8 @@ public: // Targets can use this to create target-specific perf counters. virtual Expected> - createCounter(StringRef CounterName, const LLVMState &State) const; + createCounter(StringRef CounterName, const LLVMState &State, + const pid_t ProcessID = 0) const; // Targets can use this to add target-specific passes in assembleToStream(); virtual void addTargetSpecificPasses(PassManagerBase &PM) const {} diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 833ba01e5546..12e80a7ca06b 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -665,7 +665,8 @@ public: ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {} Expected> - createCounter(StringRef CounterName, const LLVMState &State) const override { + createCounter(StringRef CounterName, const LLVMState &State, + const pid_t ProcessID) const override { // If LbrSamplingPeriod was provided, then ignore the // CounterName because we only have one for LBR. if (LbrSamplingPeriod > 0) { @@ -682,7 +683,7 @@ public: llvm::errc::invalid_argument); #endif } - return ExegesisTarget::createCounter(CounterName, State); + return ExegesisTarget::createCounter(CounterName, State, ProcessID); } private: -- 2.11.4.GIT