152 lines · c
1//===-- PerfHelper.h ------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// Helpers for measuring perf events.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H15#define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H16 17#include "llvm/ADT/SmallVector.h"18#include "llvm/ADT/StringRef.h"19#include "llvm/Config/config.h"20#include "llvm/Support/Error.h"21 22#include <cstdint>23#include <functional>24 25#ifdef _MSC_VER26typedef int pid_t;27#else28#include <sys/types.h>29#endif // _MSC_VER30 31struct perf_event_attr;32 33namespace llvm {34namespace exegesis {35namespace pfm {36 37// Returns true on error.38bool pfmInitialize();39void pfmTerminate();40 41// Retrieves the encoding for the event described by pfm_event_string.42// NOTE: pfm_initialize() must be called before creating PerfEvent objects.43class PerfEvent {44public:45 // Dummy event that does not require access to counters (for tests).46 static const char *const DummyEventString;47 48 // http://perfmon2.sourceforge.net/manv4/libpfm.html49 // Events are expressed as strings. e.g. "INSTRUCTION_RETIRED"50 explicit PerfEvent(StringRef PfmEventString);51 52 PerfEvent(const PerfEvent &) = delete;53 PerfEvent(PerfEvent &&other);54 ~PerfEvent();55 56 // The pfm_event_string passed at construction time.57 StringRef name() const;58 59 // Whether the event was successfully created.60 bool valid() const;61 62 // The encoded event to be passed to the Kernel.63 const perf_event_attr *attribute() const;64 65 // The fully qualified name for the event.66 // e.g. "snb_ep::INSTRUCTION_RETIRED:e=0:i=0:c=0:t=0:u=1:k=0:mg=0:mh=1"67 StringRef getPfmEventString() const;68 69protected:70 PerfEvent() = default;71 std::string EventString;72 std::string FullQualifiedEventString;73 perf_event_attr *Attr;74 75private:76 void initRealEvent(StringRef PfmEventString);77};78 79// Represents a single event that has been configured in the Linux perf80// subsystem.81class ConfiguredEvent {82public:83 ConfiguredEvent(PerfEvent &&EventToConfigure);84 85 void initRealEvent(const pid_t ProcessID, const int GroupFD = -1);86 Expected<SmallVector<int64_t>> readOrError(StringRef FunctionBytes) const;87 int getFileDescriptor() const { return FileDescriptor; }88 bool isDummyEvent() const {89 return Event.name() == PerfEvent::DummyEventString;90 }91 92 ConfiguredEvent(const ConfiguredEvent &) = delete;93 ConfiguredEvent(ConfiguredEvent &&other) = default;94 95 ~ConfiguredEvent();96 97private:98 PerfEvent Event;99 int FileDescriptor = -1;100};101 102// Consists of a counter measuring a specific event and associated validation103// counters measuring execution conditions. All counters in a group are part104// of a single event group and are thus scheduled on and off the CPU as a single105// unit.106class CounterGroup {107public:108 // event: the PerfEvent to measure.109 explicit CounterGroup(PerfEvent &&event, std::vector<PerfEvent> &&ValEvents,110 pid_t ProcessID = 0);111 112 CounterGroup(const CounterGroup &) = delete;113 CounterGroup(CounterGroup &&other) = default;114 115 virtual ~CounterGroup() = default;116 117 /// Starts the measurement of the event.118 virtual void start();119 120 /// Stops the measurement of the event.121 void stop();122 123 /// Returns the current value of the counter or error if it cannot be read.124 /// FunctionBytes: The benchmark function being executed.125 /// This is used to filter out the measurements to ensure they are only126 /// within the benchmarked code.127 /// If empty (or not specified), then no filtering will be done.128 /// Not all counters choose to use this.129 virtual Expected<SmallVector<int64_t, 4>>130 readOrError(StringRef FunctionBytes = StringRef()) const;131 132 virtual Expected<SmallVector<int64_t>> readValidationCountersOrError() const;133 134 virtual int numValues() const;135 136 int getFileDescriptor() const { return EventCounter.getFileDescriptor(); }137 138protected:139 ConfiguredEvent EventCounter;140 bool IsDummyEvent;141 std::vector<ConfiguredEvent> ValidationEventCounters;142 143private:144 void initRealEvent(pid_t ProcessID);145};146 147} // namespace pfm148} // namespace exegesis149} // namespace llvm150 151#endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H152