| //===-- PerfHelper.h ------------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// Helpers for measuring perf events. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H |
| #define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H |
| |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/Config/config.h" |
| #include "llvm/Support/Error.h" |
| |
| #include <cstdint> |
| #include <functional> |
| #include <memory> |
| |
| struct perf_event_attr; |
| |
| namespace llvm { |
| namespace exegesis { |
| namespace pfm { |
| |
| // Returns true on error. |
| bool pfmInitialize(); |
| void pfmTerminate(); |
| |
| // Retrieves the encoding for the event described by pfm_event_string. |
| // NOTE: pfm_initialize() must be called before creating PerfEvent objects. |
| class PerfEvent { |
| public: |
| // http://perfmon2.sourceforge.net/manv4/libpfm.html |
| // Events are expressed as strings. e.g. "INSTRUCTION_RETIRED" |
| explicit PerfEvent(StringRef PfmEventString); |
| |
| PerfEvent(const PerfEvent &) = delete; |
| PerfEvent(PerfEvent &&other); |
| ~PerfEvent(); |
| |
| // The pfm_event_string passed at construction time. |
| StringRef name() const; |
| |
| // Whether the event was successfully created. |
| bool valid() const; |
| |
| // The encoded event to be passed to the Kernel. |
| const perf_event_attr *attribute() const; |
| |
| // The fully qualified name for the event. |
| // e.g. "snb_ep::INSTRUCTION_RETIRED:e=0:i=0:c=0:t=0:u=1:k=0:mg=0:mh=1" |
| StringRef getPfmEventString() const; |
| |
| protected: |
| PerfEvent() = default; |
| std::string EventString; |
| std::string FullQualifiedEventString; |
| perf_event_attr *Attr; |
| }; |
| |
| // Uses a valid PerfEvent to configure the Kernel so we can measure the |
| // underlying event. |
| class Counter { |
| public: |
| // event: the PerfEvent to measure. |
| explicit Counter(PerfEvent &&event); |
| |
| Counter(const Counter &) = delete; |
| Counter(Counter &&other) = default; |
| |
| 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; |
| |
| /// Returns the current value of the counter or error if it cannot be read. |
| /// FunctionBytes: The benchmark function being executed. |
| /// This is used to filter out the measurements to ensure they are only |
| /// within the benchmarked code. |
| /// If empty (or not specified), then no filtering will be done. |
| /// Not all counters choose to use this. |
| virtual llvm::Expected<llvm::SmallVector<int64_t, 4>> |
| readOrError(StringRef FunctionBytes = StringRef()) const; |
| |
| virtual int numValues() const; |
| |
| protected: |
| PerfEvent Event; |
| #ifdef HAVE_LIBPFM |
| int FileDescriptor = -1; |
| #endif |
| }; |
| |
| } // namespace pfm |
| } // namespace exegesis |
| } // namespace llvm |
| |
| #endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H |