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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Helpers for measuring perf events. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 15 #define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Config/config.h" 20 #include <functional> 21 #include <memory> 22 23 struct perf_event_attr; 24 25 namespace llvm { 26 namespace exegesis { 27 namespace pfm { 28 29 // Returns true on error. 30 bool pfmInitialize(); 31 void pfmTerminate(); 32 33 // Retrieves the encoding for the event described by pfm_event_string. 34 // NOTE: pfm_initialize() must be called before creating PerfEvent objects. 35 class PerfEvent { 36 public: 37 // http://perfmon2.sourceforge.net/manv4/libpfm.html 38 // Events are expressed as strings. e.g. "INSTRUCTION_RETIRED" 39 explicit PerfEvent(StringRef pfm_event_string); 40 41 PerfEvent(const PerfEvent &) = delete; 42 PerfEvent(PerfEvent &&other); 43 ~PerfEvent(); 44 45 // The pfm_event_string passed at construction time. 46 StringRef name() const; 47 48 // Whether the event was successfully created. 49 bool valid() const; 50 51 // The encoded event to be passed to the Kernel. 52 const perf_event_attr *attribute() const; 53 54 // The fully qualified name for the event. 55 // e.g. "snb_ep::INSTRUCTION_RETIRED:e=0:i=0:c=0:t=0:u=1:k=0:mg=0:mh=1" 56 StringRef getPfmEventString() const; 57 58 private: 59 const std::string EventString; 60 std::string FullQualifiedEventString; 61 perf_event_attr *Attr; 62 }; 63 64 // Uses a valid PerfEvent to configure the Kernel so we can measure the 65 // underlying event. 66 struct Counter { 67 // event: the PerfEvent to measure. 68 explicit Counter(const PerfEvent &event); 69 70 Counter(const Counter &) = delete; 71 Counter(Counter &&other) = default; 72 73 ~Counter(); 74 75 void start(); // Starts the measurement of the event. 76 void stop(); // Stops the measurement of the event. 77 int64_t read() const; // Return the current value of the counter. 78 79 private: 80 #ifdef HAVE_LIBPFM 81 int FileDescriptor = -1; 82 #endif 83 }; 84 85 // Helper to measure a list of PerfEvent for a particular function. 86 // callback is called for each successful measure (PerfEvent needs to be valid). 87 template <typename Function> 88 void Measure( 89 ArrayRef<PerfEvent> Events, 90 const std::function<void(const PerfEvent &Event, int64_t Value)> &Callback, 91 Function Fn) { 92 for (const auto &Event : Events) { 93 if (!Event.valid()) 94 continue; 95 Counter Cnt(Event); 96 Cnt.start(); 97 Fn(); 98 Cnt.stop(); 99 Callback(Event, Cnt.read()); 100 } 101 } 102 103 } // namespace pfm 104 } // namespace exegesis 105 } // namespace llvm 106 107 #endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 108