[llvm-exegesis] Add ability to assign perf counters to specific PID
authorAiden Grossman <agrossman154@yahoo.com>
Sun, 25 Jun 2023 23:46:22 +0000 (23:46 +0000)
committerAiden Grossman <agrossman154@yahoo.com>
Mon, 26 Jun 2023 00:45:53 +0000 (00:45 +0000)
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
llvm/tools/llvm-exegesis/lib/PerfHelper.h
llvm/tools/llvm-exegesis/lib/Target.cpp
llvm/tools/llvm-exegesis/lib/Target.h
llvm/tools/llvm-exegesis/lib/X86/Target.cpp

index 4bf7485..3ff1745 100644 (file)
@@ -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;
 
index f3e2b1b..0796c26 100644 (file)
 #include <functional>
 #include <memory>
 
+#ifdef _MSC_VER
+typedef int pid_t;
+#else
+#include <sys/types.h>
+#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
index d99638f..1e5f688 100644 (file)
@@ -35,7 +35,8 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) {
 }
 
 Expected<std::unique_ptr<pfm::Counter>>
-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<Failure>(
@@ -43,7 +44,7 @@ ExegesisTarget::createCounter(StringRef CounterName, const LLVMState &) const {
             .concat(CounterName)
             .concat("'"));
 
-  return std::make_unique<pfm::Counter>(std::move(Event));
+  return std::make_unique<pfm::Counter>(std::move(Event), ProcessID);
 }
 
 void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
index b8fd4ab..51bd5f3 100644 (file)
@@ -75,7 +75,8 @@ public:
 
   // Targets can use this to create target-specific perf counters.
   virtual Expected<std::unique_ptr<pfm::Counter>>
-  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 {}
index 833ba01..12e80a7 100644 (file)
@@ -665,7 +665,8 @@ public:
   ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {}
 
   Expected<std::unique_ptr<pfm::Counter>>
-  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: