[llvm] cc8fafa - [llvm-exegesis] Make a few counter methods virtual to allow targets to provide target-specific support.

Vy Nguyen via llvm-commits llvm-commits at lists.llvm.org
Thu May 28 09:38:39 PDT 2020


Author: Vy Nguyen
Date: 2020-05-28T12:38:25-04:00
New Revision: cc8fafa2be8d5315cc55aec54b2a6d7e60f470c4

URL: https://github.com/llvm/llvm-project/commit/cc8fafa2be8d5315cc55aec54b2a6d7e60f470c4
DIFF: https://github.com/llvm/llvm-project/commit/cc8fafa2be8d5315cc55aec54b2a6d7e60f470c4.diff

LOG: [llvm-exegesis] Make a few counter methods virtual to allow targets to provide target-specific support.
Misc: Also include errno in failure message.

Differential Revision: https://reviews.llvm.org/D80610

Added: 
    

Modified: 
    llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
    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

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 9592fd8faa0c..522d4210245c 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <array>
+#include <memory>
 #include <string>
 
 #include "Assembler.h"
@@ -14,11 +15,13 @@
 #include "Error.h"
 #include "MCInstrDescView.h"
 #include "PerfHelper.h"
+#include "Target.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Program.h"
@@ -38,7 +41,7 @@ class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
   FunctionExecutorImpl(const LLVMState &State,
                        object::OwningBinary<object::ObjectFile> Obj,
                        BenchmarkRunner::ScratchSpace *Scratch)
-      : Function(State.createTargetMachine(), std::move(Obj)),
+      : State(State), Function(State.createTargetMachine(), std::move(Obj)),
         Scratch(Scratch) {}
 
 private:
@@ -51,30 +54,33 @@ class FunctionExecutorImpl : public BenchmarkRunner::FunctionExecutor {
     char *const ScratchPtr = Scratch->ptr();
     for (auto &CounterName : CounterNames) {
       CounterName = CounterName.trim();
-      pfm::PerfEvent PerfEvent(CounterName);
-      if (!PerfEvent.valid())
-        return make_error<Failure>(
-            Twine("invalid perf event '").concat(CounterName).concat("'"));
-      pfm::Counter Counter(std::move(PerfEvent));
+      auto CounterOrError =
+          State.getExegesisTarget().createCounter(CounterName.data(), State);
+
+      if (!CounterOrError)
+        return CounterOrError.takeError();
+
+      pfm::Counter *Counter = CounterOrError.get().get();
       Scratch->clear();
       {
         CrashRecoveryContext CRC;
         CrashRecoveryContext::Enable();
-        const bool Crashed = !CRC.RunSafely([this, &Counter, ScratchPtr]() {
-          Counter.start();
+        const bool Crashed = !CRC.RunSafely([this, Counter, ScratchPtr]() {
+          Counter->start();
           this->Function(ScratchPtr);
-          Counter.stop();
+          Counter->stop();
         });
         CrashRecoveryContext::Disable();
         // FIXME: Better diagnosis.
         if (Crashed)
           return make_error<SnippetCrash>("snippet crashed while running");
       }
-      CounterValue += Counter.read();
+      CounterValue += Counter->read();
     }
     return CounterValue;
   }
 
+  const LLVMState &State;
   const ExecutableFunction Function;
   BenchmarkRunner::ScratchSpace *const Scratch;
 };

diff  --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp
index c36bd5c8b9c3..c372ac4f364e 100644
--- a/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp
+++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.cpp
@@ -8,13 +8,19 @@
 
 #include "PerfHelper.h"
 #include "llvm/Config/config.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/raw_ostream.h"
 #ifdef HAVE_LIBPFM
 #include "perfmon/perf_event.h"
 #include "perfmon/pfmlib.h"
 #include "perfmon/pfmlib_perf_event.h"
 #endif
+
 #include <cassert>
+#include <cstddef>
+#include <errno.h>  // for erno
+#include <string.h> // for strerror()
 
 namespace llvm {
 namespace exegesis {
@@ -97,7 +103,8 @@ Counter::Counter(PerfEvent &&E) : Event(std::move(E)){
   perf_event_attr AttrCopy = *Event.attribute();
   FileDescriptor = perf_event_open(&AttrCopy, Pid, Cpu, GroupFd, Flags);
   if (FileDescriptor == -1) {
-    errs() << "Unable to open event, make sure your kernel allows user "
+    errs() << "Unable to open event. ERRNO: " << strerror(errno)
+           << ". Make sure your kernel allows user "
               "space perf monitoring.\nYou may want to try:\n$ sudo sh "
               "-c 'echo -1 > /proc/sys/kernel/perf_event_paranoid'\n";
   }
@@ -111,12 +118,21 @@ void Counter::start() { ioctl(FileDescriptor, PERF_EVENT_IOC_RESET, 0); }
 void Counter::stop() { ioctl(FileDescriptor, PERF_EVENT_IOC_DISABLE, 0); }
 
 int64_t Counter::read() const {
+  auto ValueOrError = readOrError();
+  if (ValueOrError)
+    return ValueOrError.get();
+
+  errs() << ValueOrError.takeError() << "\n";
+  return -1;
+}
+
+llvm::Expected<int64_t> Counter::readOrError() const {
   int64_t Count = 0;
   ssize_t ReadSize = ::read(FileDescriptor, &Count, sizeof(Count));
-  if (ReadSize != sizeof(Count)) {
-    Count = -1;
-    errs() << "Failed to read event counter\n";
-  }
+  if (ReadSize != sizeof(Count))
+    return llvm::make_error<llvm::StringError>("Failed to read event counter",
+                                               llvm::errc::io_error);
+
   return Count;
 }
 
@@ -132,6 +148,11 @@ void Counter::stop() {}
 
 int64_t Counter::read() const { return 42; }
 
+llvm::Expected<int64_t> Counter::readOrError() const {
+  return llvm::make_error<llvm::StringError>("Not implemented",
+                                             llvm::errc::io_error);
+}
+
 #endif
 
 } // namespace pfm

diff  --git a/llvm/tools/llvm-exegesis/lib/PerfHelper.h b/llvm/tools/llvm-exegesis/lib/PerfHelper.h
index 99c555587c53..7562af9c4524 100644
--- a/llvm/tools/llvm-exegesis/lib/PerfHelper.h
+++ b/llvm/tools/llvm-exegesis/lib/PerfHelper.h
@@ -17,6 +17,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Config/config.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
 #include <functional>
 #include <memory>
 
@@ -36,7 +38,7 @@ class PerfEvent {
 public:
   // http://perfmon2.sourceforge.net/manv4/libpfm.html
   // Events are expressed as strings. e.g. "INSTRUCTION_RETIRED"
-  explicit PerfEvent(StringRef pfm_event_string);
+  explicit PerfEvent(StringRef PfmEventString);
 
   PerfEvent(const PerfEvent &) = delete;
   PerfEvent(PerfEvent &&other);
@@ -63,18 +65,27 @@ class PerfEvent {
 
 // Uses a valid PerfEvent to configure the Kernel so we can measure the
 // underlying event.
-struct Counter {
+class Counter {
+public:
   // event: the PerfEvent to measure.
   explicit Counter(PerfEvent &&event);
 
   Counter(const Counter &) = delete;
   Counter(Counter &&other) = default;
 
-  ~Counter();
+  virtual ~Counter();
+
+  /// Starts the measurement of the event.
+  virtual void start();
+
+  /// Stops the measurement of the event.
+  void stop();
+
+  /// Returns the current value of the counter or -1 if it cannot be read.
+  int64_t read() const;
 
-  void start();         // Starts the measurement of the event.
-  void stop();          // Stops the measurement of the event.
-  int64_t read() const; // Return the current value of the counter.
+  /// Returns the current value of the counter or error if it cannot be read.
+  virtual llvm::Expected<int64_t> readOrError() const;
 
 private:
   PerfEvent Event;

diff  --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp
index 4e0de9375669..61821bf4bb4d 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Target.cpp
@@ -11,6 +11,8 @@
 #include "ParallelSnippetGenerator.h"
 #include "SerialSnippetGenerator.h"
 #include "UopsBenchmarkRunner.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
 
 namespace llvm {
 namespace exegesis {
@@ -27,6 +29,19 @@ const ExegesisTarget *ExegesisTarget::lookup(Triple TT) {
   return nullptr;
 }
 
+Expected<std::unique_ptr<pfm::Counter>>
+ExegesisTarget::createCounter(const char *CounterName,
+                              const LLVMState &) const {
+  pfm::PerfEvent Event(CounterName);
+  if (!Event.valid())
+    return llvm::make_error<Failure>(
+        llvm::Twine("Unable to create counter with name '")
+            .concat(CounterName)
+            .concat("'"));
+
+  return std::make_unique<pfm::Counter>(std::move(Event));
+}
+
 void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
   if (FirstTarget == nullptr) {
     FirstTarget = Target;

diff  --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h
index 298cfac23e81..937b88ddb4cc 100644
--- a/llvm/tools/llvm-exegesis/lib/Target.h
+++ b/llvm/tools/llvm-exegesis/lib/Target.h
@@ -20,6 +20,7 @@
 #include "BenchmarkRunner.h"
 #include "Error.h"
 #include "LlvmState.h"
+#include "PerfHelper.h"
 #include "SnippetGenerator.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -27,6 +28,7 @@
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Error.h"
 
 namespace llvm {
 namespace exegesis {
@@ -65,6 +67,10 @@ class ExegesisTarget {
   explicit ExegesisTarget(ArrayRef<CpuAndPfmCounters> CpuPfmCounters)
       : CpuPfmCounters(CpuPfmCounters) {}
 
+  // Targets can use this to create target-specific perf counters.
+  virtual Expected<std::unique_ptr<pfm::Counter>>
+  createCounter(const char *CounterName, const LLVMState &State) const;
+
   // Targets can use this to add target-specific passes in assembleToStream();
   virtual void addTargetSpecificPasses(PassManagerBase &PM) const {}
 


        


More information about the llvm-commits mailing list