1 //===-- PerfHelper.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// Helpers for measuring perf events. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 16 #define LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Config/config.h" 21 #include <functional> 22 #include <memory> 23 24 struct perf_event_attr; 25 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(llvm::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 llvm::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 llvm::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> Measure(llvm::ArrayRef<PerfEvent> Events,const std::function<void (const PerfEvent & Event,int64_t Value)> & Callback,Function Fn)88void Measure( 89 llvm::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 106 #endif // LLVM_TOOLS_LLVM_EXEGESIS_PERFHELPER_H 107